Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

chrdev: emit a warning when we go below dynamic major range

Currently a dynamically allocated character device major is taken
from 254 and downward. This mechanism is used for RTC, IIO and a
few other subsystems.

The kernel currently has no check prevening these dynamic
allocations from eating into the assigned numbers at 233 and
downward.

In a recent test it was reported that so many dynamic device
majors were used on a test server, that the major number for
infiniband (231) was stolen. This occurred when allocating a new
major number for GPIO chips. The error messages from the kernel
were not helpful. (See: https://lkml.org/lkml/2016/2/14/124)

This patch adds a defined lower limit of the dynamic major
allocation region will henceforth emit a warning if we start to
eat into the assigned numbers. It does not do any semantic
changes and will not change the kernels behaviour: numbers will
still continue to be stolen, but we will know from dmesg what
is going on.

This also updates the Documentation/devices.txt to clearly
reflect that we are using this range of major numbers for dynamic
allocation.

Reported-by: Ying Huang <ying.huang@linux.intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Alan Cox <alan@linux.intel.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Linus Walleij and committed by
Greg Kroah-Hartman
49db08c3 00411b7b

+9 -3
+3 -3
Documentation/devices.txt
··· 3099 3099 129 = /dev/ipath_sma Device used by Subnet Management Agent 3100 3100 130 = /dev/ipath_diag Device used by diagnostics programs 3101 3101 3102 - 234-239 UNASSIGNED 3103 - 3104 - 240-254 char LOCAL/EXPERIMENTAL USE 3102 + 234-254 char RESERVED FOR DYNAMIC ASSIGNMENT 3103 + Character devices that request a dynamic allocation of major number will 3104 + take numbers starting from 254 and downward. 3105 3105 3106 3106 240-254 block LOCAL/EXPERIMENTAL USE 3107 3107 Allocated for local/experimental use. For devices not
+4
fs/char_dev.c
··· 91 91 break; 92 92 } 93 93 94 + if (i < CHRDEV_MAJOR_DYN_END) 95 + pr_warn("CHRDEV \"%s\" major number %d goes below the dynamic allocation range", 96 + name, i); 97 + 94 98 if (i == 0) { 95 99 ret = -EBUSY; 96 100 goto out;
+2
include/linux/fs.h
··· 2385 2385 2386 2386 /* fs/char_dev.c */ 2387 2387 #define CHRDEV_MAJOR_HASH_SIZE 255 2388 + /* Marks the bottom of the first segment of free char majors */ 2389 + #define CHRDEV_MAJOR_DYN_END 234 2388 2390 extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *); 2389 2391 extern int register_chrdev_region(dev_t, unsigned, const char *); 2390 2392 extern int __register_chrdev(unsigned int major, unsigned int baseminor,