diff options
| author | California Sullivan <california.l.sullivan@intel.com> | 2017-05-30 15:04:18 -0700 |
|---|---|---|
| committer | Saul Wold <sgw@linux.intel.com> | 2017-07-06 15:58:01 -0700 |
| commit | 0f395e9fe94bf150ba050bd9d7ccf60ee20f8c04 (patch) | |
| tree | 932c5953ac3f3bb60eabc12df65eccef63897712 | |
| parent | cb55344928f13306feaf57dd1435913415d9122e (diff) | |
| download | meta-intel-0f395e9fe94bf150ba050bd9d7ccf60ee20f8c04.tar.gz | |
meta-tlk: Add linux-intel bbappend
This bbappend adds the time limited kernel patch and configuration
options. Unlike linux-yocto, the patch is not integrated into the source
tree, so we have to add it here.
Signed-off-by: California Sullivan <california.l.sullivan@intel.com>
Signed-off-by: Saul Wold <sgw@linux.intel.com>
| -rw-r--r-- | meta-tlk/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch | 251 | ||||
| -rw-r--r-- | meta-tlk/recipes-kernel/linux/linux-intel_%.bbappend | 3 |
2 files changed, 254 insertions, 0 deletions
diff --git a/meta-tlk/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch b/meta-tlk/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch new file mode 100644 index 00000000..aa143059 --- /dev/null +++ b/meta-tlk/recipes-kernel/linux/files/uptime-allow-the-optional-limiting-of-kernel-runtime.patch | |||
| @@ -0,0 +1,251 @@ | |||
| 1 | From a21e483b57c8c31beaa5063268ec35da375daf04 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Bruce Ashfield <bruce.ashfield@windriver.com> | ||
| 3 | Date: Tue, 12 Jul 2011 10:26:50 -0400 | ||
| 4 | Subject: [PATCH] uptime: allow the optional limiting of kernel runtime | ||
| 5 | |||
| 6 | Introduce the ability to limit the limit the uptime of a kernel. | ||
| 7 | When enabled, these options set a maximum uptime on the kernel, and | ||
| 8 | (optionally) trigger a clean reboot at expiration. | ||
| 9 | |||
| 10 | This functionality may appear to be very close to the softdog watchdog | ||
| 11 | implementation. It is. But can't be the softdog for several reasons: | ||
| 12 | |||
| 13 | - The soft watchdog should be available while this functionality is active | ||
| 14 | - The duration range is different between this and the softdog. The | ||
| 15 | timeout available here is potentially quite a bit longer. | ||
| 16 | - At expiration, there are different expiration requirements and actions. | ||
| 17 | - This functionality is specific to a particular use case and should | ||
| 18 | not impact mainline functionality | ||
| 19 | |||
| 20 | To cleanly restart the kernel after one minute of uptime, the following | ||
| 21 | config items would be required: | ||
| 22 | |||
| 23 | CONFIG_UPTIME_LIMITED_KERNEL=y | ||
| 24 | CONFIG_UPTIME_LIMIT_DURATION=1 | ||
| 25 | CONFIG_UPTIME_LIMIT_KERNEL_REBOOT=y | ||
| 26 | |||
| 27 | Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com> | ||
| 28 | |||
| 29 | diff --git a/init/Kconfig b/init/Kconfig | ||
| 30 | index cac3f096050d..77d6d5fa1b1d 100644 | ||
| 31 | --- a/init/Kconfig | ||
| 32 | +++ b/init/Kconfig | ||
| 33 | @@ -1376,6 +1376,31 @@ menuconfig EXPERT | ||
| 34 | environments which can tolerate a "non-standard" kernel. | ||
| 35 | Only use this if you really know what you are doing. | ||
| 36 | |||
| 37 | +config UPTIME_LIMITED_KERNEL | ||
| 38 | + bool "Create a kernel with uptime limitations" | ||
| 39 | + default n | ||
| 40 | + help | ||
| 41 | + Limit the amount of time a kernel can run. The associated UPTIME_LIMIT* | ||
| 42 | + kernel config options should be used to tune the behaviour. | ||
| 43 | + | ||
| 44 | +config UPTIME_LIMIT_DURATION | ||
| 45 | + int "Kernel uptime limit in minutes" | ||
| 46 | + depends on UPTIME_LIMITED_KERNEL | ||
| 47 | + range 0 14400 | ||
| 48 | + default 0 | ||
| 49 | + help | ||
| 50 | + Define the uptime limitation on a kernel in minutes. Once | ||
| 51 | + the defined time expires the kernel will emit a warning, cease | ||
| 52 | + to be usable and eventually restart. The valid range is 0 (disable) | ||
| 53 | + to 14400 (10 days) | ||
| 54 | + | ||
| 55 | +config UPTIME_LIMIT_KERNEL_REBOOT | ||
| 56 | + bool "Reboot a time limited kernel at expiration" | ||
| 57 | + depends on UPTIME_LIMITED_KERNEL | ||
| 58 | + default y | ||
| 59 | + help | ||
| 60 | + Reboot an uptime limited kernel at expiration. | ||
| 61 | + | ||
| 62 | config UID16 | ||
| 63 | bool "Enable 16-bit UID system calls" if EXPERT | ||
| 64 | depends on HAVE_UID16 && MULTIUSER | ||
| 65 | diff --git a/kernel/Makefile b/kernel/Makefile | ||
| 66 | index e2ec54e2b952..6b7bdddd624b 100644 | ||
| 67 | --- a/kernel/Makefile | ||
| 68 | +++ b/kernel/Makefile | ||
| 69 | @@ -45,6 +45,7 @@ obj-$(CONFIG_FREEZER) += freezer.o | ||
| 70 | obj-$(CONFIG_PROFILING) += profile.o | ||
| 71 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | ||
| 72 | obj-y += time/ | ||
| 73 | +obj-$(CONFIG_UPTIME_LIMITED_KERNEL) += uptime_limit.o | ||
| 74 | obj-$(CONFIG_FUTEX) += futex.o | ||
| 75 | ifeq ($(CONFIG_COMPAT),y) | ||
| 76 | obj-$(CONFIG_FUTEX) += futex_compat.o | ||
| 77 | diff --git a/kernel/uptime_limit.c b/kernel/uptime_limit.c | ||
| 78 | new file mode 100644 | ||
| 79 | index 000000000000..b6a1a5e4f9d9 | ||
| 80 | --- /dev/null | ||
| 81 | +++ b/kernel/uptime_limit.c | ||
| 82 | @@ -0,0 +1,166 @@ | ||
| 83 | +/* | ||
| 84 | + * uptime_limit.c | ||
| 85 | + * | ||
| 86 | + * This file contains the functions which can limit kernel uptime | ||
| 87 | + * | ||
| 88 | + * Copyright (C) 2011 Bruce Ashfield (bruce.ashfield@windriver.com) | ||
| 89 | + * | ||
| 90 | + * This program is free software; you can redistribute it and/or modify | ||
| 91 | + * it under the terms of the GNU General Public License as published by | ||
| 92 | + * the Free Software Foundation; either version 2 of the License, or | ||
| 93 | + * (at your option) any later version. | ||
| 94 | + * | ||
| 95 | + * This program is distributed in the hope that it will be useful, | ||
| 96 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 97 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 98 | + * GNU General Public License for more details. | ||
| 99 | + * | ||
| 100 | + * You should have received a copy of the GNU General Public License | ||
| 101 | + * along with this program; if not, write to the Free Software | ||
| 102 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 103 | + * | ||
| 104 | + * | ||
| 105 | + * This functionality is somewhat close to the softdog watchdog | ||
| 106 | + * implementation, but it cannot be used directly for several reasons: | ||
| 107 | + * | ||
| 108 | + * - The soft watchdog should be available while this functionality is active | ||
| 109 | + * - The duration range is different between this and the softdog. The | ||
| 110 | + * timeout available here is potentially quite a bit longer. | ||
| 111 | + * - At expiration, there are different expiration requirements and actions. | ||
| 112 | + * - This functionality is specific to a particular use case and should | ||
| 113 | + * not impact mainline functionality | ||
| 114 | + * | ||
| 115 | + */ | ||
| 116 | +#include <linux/kernel.h> | ||
| 117 | +#include <linux/reboot.h> | ||
| 118 | +#include <linux/timer.h> | ||
| 119 | +#include <linux/delay.h> | ||
| 120 | +#include <linux/kthread.h> | ||
| 121 | + | ||
| 122 | +#define UPTIME_LIMIT_IN_SECONDS (CONFIG_UPTIME_LIMIT_DURATION * 60) | ||
| 123 | +#define MIN(X, Y) ((X) <= (Y) ? (X) : (Y)) | ||
| 124 | +#define TEN_MINUTES_IN_SECONDS 600 | ||
| 125 | + | ||
| 126 | +enum uptime_expiration_type { | ||
| 127 | + uptime_no_action, | ||
| 128 | + uptime_reboot | ||
| 129 | +}; | ||
| 130 | + | ||
| 131 | +static enum uptime_expiration_type uptime_expiration_action = uptime_no_action; | ||
| 132 | +static struct timer_list timelimit_timer; | ||
| 133 | +static struct task_struct *uptime_worker_task; | ||
| 134 | + | ||
| 135 | +static void timelimit_expire(unsigned long timeout_seconds) | ||
| 136 | +{ | ||
| 137 | + char msg[128]; | ||
| 138 | + int msglen = 127; | ||
| 139 | + | ||
| 140 | + if (timeout_seconds) { | ||
| 141 | + if (timeout_seconds >= 60) | ||
| 142 | + snprintf(msg, msglen, | ||
| 143 | + "Uptime: kernel validity duration has %d %s remaining\n", | ||
| 144 | + (int) timeout_seconds / 60, "minute(s)"); | ||
| 145 | + else | ||
| 146 | + snprintf(msg, msglen, | ||
| 147 | + "Uptime: kernel validity duration has %d %s remaining\n", | ||
| 148 | + (int) timeout_seconds, "seconds"); | ||
| 149 | + | ||
| 150 | + printk(KERN_CRIT "%s", msg); | ||
| 151 | + | ||
| 152 | + timelimit_timer.expires = jiffies + timeout_seconds * HZ; | ||
| 153 | + timelimit_timer.data = 0; | ||
| 154 | + add_timer_on(&timelimit_timer, cpumask_first(cpu_online_mask)); | ||
| 155 | + } else { | ||
| 156 | + printk(KERN_CRIT "Uptime: Kernel validity timeout has expired\n"); | ||
| 157 | +#ifdef CONFIG_UPTIME_LIMIT_KERNEL_REBOOT | ||
| 158 | + uptime_expiration_action = uptime_reboot; | ||
| 159 | + wake_up_process(uptime_worker_task); | ||
| 160 | + } | ||
| 161 | +#endif | ||
| 162 | +} | ||
| 163 | + | ||
| 164 | +/* | ||
| 165 | + * This thread starts and then immediately goes to sleep. When it is woken | ||
| 166 | + * up, it carries out the instructions left in uptime_expiration_action. If | ||
| 167 | + * no action was specified it simply goes back to sleep. | ||
| 168 | + */ | ||
| 169 | +static int uptime_worker(void *unused) | ||
| 170 | +{ | ||
| 171 | + set_current_state(TASK_INTERRUPTIBLE); | ||
| 172 | + | ||
| 173 | + while (!kthread_should_stop()) { | ||
| 174 | + schedule(); | ||
| 175 | + | ||
| 176 | + if (kthread_should_stop()) | ||
| 177 | + break; | ||
| 178 | + | ||
| 179 | + if (uptime_expiration_action == uptime_reboot) { | ||
| 180 | + printk(KERN_CRIT "Uptime: restarting machine\n"); | ||
| 181 | + kernel_restart(NULL); | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + set_current_state(TASK_INTERRUPTIBLE); | ||
| 185 | + } | ||
| 186 | + __set_current_state(TASK_RUNNING); | ||
| 187 | + | ||
| 188 | + return 0; | ||
| 189 | +} | ||
| 190 | + | ||
| 191 | +static int timeout_enable(int cpu) | ||
| 192 | +{ | ||
| 193 | + int err = 0; | ||
| 194 | + int warning_limit; | ||
| 195 | + | ||
| 196 | + /* | ||
| 197 | + * Create an uptime worker thread. This thread is required since the | ||
| 198 | + * safe version of kernel restart cannot be called from a | ||
| 199 | + * non-interruptible context. Which means we cannot call it directly | ||
| 200 | + * from a timer callback. So we arrange for the timer expiration to | ||
| 201 | + * wakeup a thread, which performs the action. | ||
| 202 | + */ | ||
| 203 | + uptime_worker_task = kthread_create(uptime_worker, | ||
| 204 | + (void *)(unsigned long)cpu, | ||
| 205 | + "uptime_worker/%d", cpu); | ||
| 206 | + if (IS_ERR(uptime_worker_task)) { | ||
| 207 | + printk(KERN_ERR "Uptime: task for cpu %i failed\n", cpu); | ||
| 208 | + err = PTR_ERR(uptime_worker_task); | ||
| 209 | + goto out; | ||
| 210 | + } | ||
| 211 | + /* bind to cpu0 to avoid migration and hot plug nastiness */ | ||
| 212 | + kthread_bind(uptime_worker_task, cpu); | ||
| 213 | + wake_up_process(uptime_worker_task); | ||
| 214 | + | ||
| 215 | + /* Create the timer that will wake the uptime thread at expiration */ | ||
| 216 | + init_timer(&timelimit_timer); | ||
| 217 | + timelimit_timer.function = timelimit_expire; | ||
| 218 | + /* | ||
| 219 | + * Fire two timers. One warning timeout and the final timer | ||
| 220 | + * which will carry out the expiration action. The warning timer will | ||
| 221 | + * expire at the minimum of half the original time or ten minutes. | ||
| 222 | + */ | ||
| 223 | + warning_limit = MIN(UPTIME_LIMIT_IN_SECONDS/2, TEN_MINUTES_IN_SECONDS); | ||
| 224 | + timelimit_timer.expires = jiffies + warning_limit * HZ; | ||
| 225 | + timelimit_timer.data = UPTIME_LIMIT_IN_SECONDS - warning_limit; | ||
| 226 | + | ||
| 227 | + add_timer_on(&timelimit_timer, cpumask_first(cpu_online_mask)); | ||
| 228 | +out: | ||
| 229 | + return err; | ||
| 230 | +} | ||
| 231 | + | ||
| 232 | +static int __init timelimit_init(void) | ||
| 233 | +{ | ||
| 234 | + int err = 0; | ||
| 235 | + | ||
| 236 | + printk(KERN_INFO "Uptime: system uptime restrictions enabled\n"); | ||
| 237 | + | ||
| 238 | + /* | ||
| 239 | + * Enable the timeout thread for cpu 0 only, assuming that the | ||
| 240 | + * uptime limit is non-zero, to protect against any cpu | ||
| 241 | + * migration issues. | ||
| 242 | + */ | ||
| 243 | + if (UPTIME_LIMIT_IN_SECONDS) | ||
| 244 | + err = timeout_enable(0); | ||
| 245 | + | ||
| 246 | + return err; | ||
| 247 | +} | ||
| 248 | +device_initcall(timelimit_init); | ||
| 249 | -- | ||
| 250 | 2.10.1 | ||
| 251 | |||
diff --git a/meta-tlk/recipes-kernel/linux/linux-intel_%.bbappend b/meta-tlk/recipes-kernel/linux/linux-intel_%.bbappend new file mode 100644 index 00000000..47c62efe --- /dev/null +++ b/meta-tlk/recipes-kernel/linux/linux-intel_%.bbappend | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | FILESEXTRAPATHS_prepend := "${THISDIR}/files:" | ||
| 2 | SRC_URI_append = " file://time-limited-kernel.cfg \ | ||
| 3 | file://uptime-allow-the-optional-limiting-of-kernel-runtime.patch" | ||
