Skip to content

Commit 867eacd

Browse files
committed
Merge branch 'akpm' (patches from Andrew)
Merge even more updates from Andrew Morton: - a few leftovers - fault-injector rework - add a module loader test driver * emailed patches from Andrew Morton <akpm@linux-foundation.org>: kmod: throttle kmod thread limit kmod: add test driver to stress test the module loader MAINTAINERS: give kmod some maintainer love xtensa: use generic fb.h fault-inject: add /proc/<pid>/fail-nth fault-inject: simplify access check for fail-nth fault-inject: make fail-nth read/write interface symmetric fault-inject: parse as natural 1-based value for fail-nth write interface fault-inject: automatically detect the number base for fail-nth write interface kernel/watchdog.c: use better pr_fmt prefix MAINTAINERS: move the befs tree to kernel.org lib/atomic64_test.c: add a test that atomic64_inc_not_zero() returns an int mm: fix overflow check in expand_upwards()
2 parents 077d2ba + 6d7964a commit 867eacd

File tree

17 files changed

+1969
-62
lines changed

17 files changed

+1969
-62
lines changed

Documentation/fault-injection/fault-injection.txt

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,13 @@ use the boot option:
136136

137137
o proc entries
138138

139-
- /proc/self/task/<current-tid>/fail-nth:
139+
- /proc/<pid>/fail-nth:
140+
- /proc/self/task/<tid>/fail-nth:
140141

141-
Write to this file of integer N makes N-th call in the current task fail
142-
(N is 0-based). Read from this file returns a single char 'Y' or 'N'
143-
that says if the fault setup with a previous write to this file was
144-
injected or not, and disables the fault if it wasn't yet injected.
142+
Write to this file of integer N makes N-th call in the task fail.
143+
Read from this file returns a integer value. A value of '0' indicates
144+
that the fault setup with a previous write to this file was injected.
145+
A positive integer N indicates that the fault wasn't yet injected.
145146
Note that this file enables all types of faults (slab, futex, etc).
146147
This setting takes precedence over all other generic debugfs settings
147148
like probability, interval, times, etc. But per-capability settings
@@ -320,26 +321,26 @@ int main()
320321
system("echo N > /sys/kernel/debug/failslab/ignore-gfp-wait");
321322
sprintf(buf, "/proc/self/task/%ld/fail-nth", syscall(SYS_gettid));
322323
fail_nth = open(buf, O_RDWR);
323-
for (i = 0;; i++) {
324+
for (i = 1;; i++) {
324325
sprintf(buf, "%d", i);
325326
write(fail_nth, buf, strlen(buf));
326327
res = socketpair(AF_LOCAL, SOCK_STREAM, 0, fds);
327328
err = errno;
328-
read(fail_nth, buf, 1);
329+
pread(fail_nth, buf, sizeof(buf), 0);
329330
if (res == 0) {
330331
close(fds[0]);
331332
close(fds[1]);
332333
}
333-
printf("%d-th fault %c: res=%d/%d\n", i, buf[0], res, err);
334-
if (buf[0] != 'Y')
334+
printf("%d-th fault %c: res=%d/%d\n", i, atoi(buf) ? 'N' : 'Y',
335+
res, err);
336+
if (atoi(buf))
335337
break;
336338
}
337339
return 0;
338340
}
339341

340342
An example output:
341343

342-
0-th fault Y: res=-1/23
343344
1-th fault Y: res=-1/23
344345
2-th fault Y: res=-1/23
345346
3-th fault Y: res=-1/12

MAINTAINERS

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,10 +2516,10 @@ S: Supported
25162516
F: drivers/media/platform/sti/delta
25172517

25182518
BEFS FILE SYSTEM
2519-
M: Luis de Bethencourt <luisbg@osg.samsung.com>
2519+
M: Luis de Bethencourt <luisbg@kernel.org>
25202520
M: Salah Triki <salah.triki@gmail.com>
25212521
S: Maintained
2522-
T: git git://github.com/luisbg/linux-befs.git
2522+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/luisbg/linux-befs.git
25232523
F: Documentation/filesystems/befs.txt
25242524
F: fs/befs/
25252525

@@ -7554,6 +7554,15 @@ F: include/linux/kmemleak.h
75547554
F: mm/kmemleak.c
75557555
F: mm/kmemleak-test.c
75567556

7557+
KMOD MODULE USERMODE HELPER
7558+
M: "Luis R. Rodriguez" <mcgrof@kernel.org>
7559+
L: linux-kernel@vger.kernel.org
7560+
S: Maintained
7561+
F: kernel/kmod.c
7562+
F: include/linux/kmod.h
7563+
F: lib/test_kmod.c
7564+
F: tools/testing/selftests/kmod/
7565+
75577566
KPROBES
75587567
M: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
75597568
M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>

arch/xtensa/include/asm/Kbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ generic-y += dma-contiguous.h
55
generic-y += emergency-restart.h
66
generic-y += exec.h
77
generic-y += extable.h
8+
generic-y += fb.h
89
generic-y += hardirq.h
910
generic-y += irq_regs.h
1011
generic-y += irq_work.h

arch/xtensa/include/asm/fb.h

Lines changed: 0 additions & 12 deletions
This file was deleted.

fs/proc/base.c

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,42 +1360,38 @@ static ssize_t proc_fail_nth_write(struct file *file, const char __user *buf,
13601360
size_t count, loff_t *ppos)
13611361
{
13621362
struct task_struct *task;
1363-
int err, n;
1363+
int err;
1364+
unsigned int n;
1365+
1366+
err = kstrtouint_from_user(buf, count, 0, &n);
1367+
if (err)
1368+
return err;
13641369

13651370
task = get_proc_task(file_inode(file));
13661371
if (!task)
13671372
return -ESRCH;
1373+
WRITE_ONCE(task->fail_nth, n);
13681374
put_task_struct(task);
1369-
if (task != current)
1370-
return -EPERM;
1371-
err = kstrtoint_from_user(buf, count, 10, &n);
1372-
if (err)
1373-
return err;
1374-
if (n < 0 || n == INT_MAX)
1375-
return -EINVAL;
1376-
current->fail_nth = n + 1;
1375+
13771376
return count;
13781377
}
13791378

13801379
static ssize_t proc_fail_nth_read(struct file *file, char __user *buf,
13811380
size_t count, loff_t *ppos)
13821381
{
13831382
struct task_struct *task;
1384-
int err;
1383+
char numbuf[PROC_NUMBUF];
1384+
ssize_t len;
13851385

13861386
task = get_proc_task(file_inode(file));
13871387
if (!task)
13881388
return -ESRCH;
1389+
len = snprintf(numbuf, sizeof(numbuf), "%u\n",
1390+
READ_ONCE(task->fail_nth));
1391+
len = simple_read_from_buffer(buf, count, ppos, numbuf, len);
13891392
put_task_struct(task);
1390-
if (task != current)
1391-
return -EPERM;
1392-
if (count < 1)
1393-
return -EINVAL;
1394-
err = put_user((char)(current->fail_nth ? 'N' : 'Y'), buf);
1395-
if (err)
1396-
return err;
1397-
current->fail_nth = 0;
1398-
return 1;
1393+
1394+
return len;
13991395
}
14001396

14011397
static const struct file_operations proc_fail_nth_operations = {
@@ -2966,6 +2962,7 @@ static const struct pid_entry tgid_base_stuff[] = {
29662962
#endif
29672963
#ifdef CONFIG_FAULT_INJECTION
29682964
REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
2965+
REG("fail-nth", 0644, proc_fail_nth_operations),
29692966
#endif
29702967
#ifdef CONFIG_ELF_CORE
29712968
REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations),
@@ -3358,11 +3355,7 @@ static const struct pid_entry tid_base_stuff[] = {
33583355
#endif
33593356
#ifdef CONFIG_FAULT_INJECTION
33603357
REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
3361-
/*
3362-
* Operations on the file check that the task is current,
3363-
* so we create it with 0666 to support testing under unprivileged user.
3364-
*/
3365-
REG("fail-nth", 0666, proc_fail_nth_operations),
3358+
REG("fail-nth", 0644, proc_fail_nth_operations),
33663359
#endif
33673360
#ifdef CONFIG_TASK_IO_ACCOUNTING
33683361
ONE("io", S_IRUSR, proc_tid_io_accounting),

include/linux/sched.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,7 @@ struct task_struct {
974974

975975
#ifdef CONFIG_FAULT_INJECTION
976976
int make_it_fail;
977-
int fail_nth;
977+
unsigned int fail_nth;
978978
#endif
979979
/*
980980
* When (nr_dirtied >= nr_dirtied_pause), it's time to call

kernel/kmod.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ static DECLARE_RWSEM(umhelper_sem);
6868
*/
6969
#define MAX_KMOD_CONCURRENT 50
7070
static atomic_t kmod_concurrent_max = ATOMIC_INIT(MAX_KMOD_CONCURRENT);
71+
static DECLARE_WAIT_QUEUE_HEAD(kmod_wq);
7172

7273
/*
7374
modprobe_path is set via /proc/sys.
@@ -140,7 +141,6 @@ int __request_module(bool wait, const char *fmt, ...)
140141
va_list args;
141142
char module_name[MODULE_NAME_LEN];
142143
int ret;
143-
static int kmod_loop_msg;
144144

145145
/*
146146
* We don't allow synchronous module loading from async. Module
@@ -164,21 +164,19 @@ int __request_module(bool wait, const char *fmt, ...)
164164
return ret;
165165

166166
if (atomic_dec_if_positive(&kmod_concurrent_max) < 0) {
167-
/* We may be blaming an innocent here, but unlikely */
168-
if (kmod_loop_msg < 5) {
169-
printk(KERN_ERR
170-
"request_module: runaway loop modprobe %s\n",
171-
module_name);
172-
kmod_loop_msg++;
173-
}
174-
return -ENOMEM;
167+
pr_warn_ratelimited("request_module: kmod_concurrent_max (%u) close to 0 (max_modprobes: %u), for module %s, throttling...",
168+
atomic_read(&kmod_concurrent_max),
169+
MAX_KMOD_CONCURRENT, module_name);
170+
wait_event_interruptible(kmod_wq,
171+
atomic_dec_if_positive(&kmod_concurrent_max) >= 0);
175172
}
176173

177174
trace_module_request(module_name, wait, _RET_IP_);
178175

179176
ret = call_modprobe(module_name, wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
180177

181178
atomic_inc(&kmod_concurrent_max);
179+
wake_up(&kmod_wq);
182180

183181
return ret;
184182
}

kernel/watchdog.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* to those contributors as well.
1010
*/
1111

12-
#define pr_fmt(fmt) "NMI watchdog: " fmt
12+
#define pr_fmt(fmt) "watchdog: " fmt
1313

1414
#include <linux/mm.h>
1515
#include <linux/cpu.h>

lib/Kconfig.debug

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,33 @@ config BUG_ON_DATA_CORRUPTION
18471847

18481848
If unsure, say N.
18491849

1850+
config TEST_KMOD
1851+
tristate "kmod stress tester"
1852+
default n
1853+
depends on m
1854+
depends on BLOCK && (64BIT || LBDAF) # for XFS, BTRFS
1855+
depends on NETDEVICES && NET_CORE && INET # for TUN
1856+
select TEST_LKM
1857+
select XFS_FS
1858+
select TUN
1859+
select BTRFS_FS
1860+
help
1861+
Test the kernel's module loading mechanism: kmod. kmod implements
1862+
support to load modules using the Linux kernel's usermode helper.
1863+
This test provides a series of tests against kmod.
1864+
1865+
Although technically you can either build test_kmod as a module or
1866+
into the kernel we disallow building it into the kernel since
1867+
it stress tests request_module() and this will very likely cause
1868+
some issues by taking over precious threads available from other
1869+
module load requests, ultimately this could be fatal.
1870+
1871+
To run tests run:
1872+
1873+
tools/testing/selftests/kmod/kmod.sh --help
1874+
1875+
If unsure, say N.
1876+
18501877
source "samples/Kconfig"
18511878

18521879
source "lib/Kconfig.kgdb"

lib/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ obj-$(CONFIG_TEST_PRINTF) += test_printf.o
6161
obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o
6262
obj-$(CONFIG_TEST_UUID) += test_uuid.o
6363
obj-$(CONFIG_TEST_PARMAN) += test_parman.o
64+
obj-$(CONFIG_TEST_KMOD) += test_kmod.o
6465

6566
ifeq ($(CONFIG_DEBUG_KOBJECT),y)
6667
CFLAGS_kobject.o += -DDEBUG

lib/atomic64_test.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,10 @@ static __init void test_atomic64(void)
153153
long long v0 = 0xaaa31337c001d00dLL;
154154
long long v1 = 0xdeadbeefdeafcafeLL;
155155
long long v2 = 0xfaceabadf00df001LL;
156+
long long v3 = 0x8000000000000000LL;
156157
long long onestwos = 0x1111111122222222LL;
157158
long long one = 1LL;
159+
int r_int;
158160

159161
atomic64_t v = ATOMIC64_INIT(v0);
160162
long long r = v0;
@@ -240,6 +242,11 @@ static __init void test_atomic64(void)
240242
BUG_ON(!atomic64_inc_not_zero(&v));
241243
r += one;
242244
BUG_ON(v.counter != r);
245+
246+
/* Confirm the return value fits in an int, even if the value doesn't */
247+
INIT(v3);
248+
r_int = atomic64_inc_not_zero(&v);
249+
BUG_ON(!r_int);
243250
}
244251

245252
static __init int test_atomics_init(void)

lib/fault-inject.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,12 @@ static inline bool fail_stacktrace(struct fault_attr *attr)
107107

108108
bool should_fail(struct fault_attr *attr, ssize_t size)
109109
{
110-
if (in_task() && current->fail_nth) {
111-
if (--current->fail_nth == 0)
110+
if (in_task()) {
111+
unsigned int fail_nth = READ_ONCE(current->fail_nth);
112+
113+
if (fail_nth && !WRITE_ONCE(current->fail_nth, fail_nth - 1))
112114
goto fail;
115+
113116
return false;
114117
}
115118

0 commit comments

Comments
 (0)