diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2016-02-19 15:36:07 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-03-29 10:11:44 -0700 |
commit | 49db08c358873af11ba3c25401de88156fa5d365 (patch) | |
tree | 1a2cddaae3f112d0239cc61841efa4b8385985e6 | |
parent | 00411b7b1e3ec477b75bb83ccd417c7609832db6 (diff) |
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>
-rw-r--r-- | Documentation/devices.txt | 6 | ||||
-rw-r--r-- | fs/char_dev.c | 4 | ||||
-rw-r--r-- | include/linux/fs.h | 2 |
3 files changed, 9 insertions, 3 deletions
diff --git a/Documentation/devices.txt b/Documentation/devices.txt index 87b4c5e82d39..0a3588a9798d 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -3099,9 +3099,9 @@ Your cooperation is appreciated. 129 = /dev/ipath_sma Device used by Subnet Management Agent 130 = /dev/ipath_diag Device used by diagnostics programs -234-239 UNASSIGNED - -240-254 char LOCAL/EXPERIMENTAL USE +234-254 char RESERVED FOR DYNAMIC ASSIGNMENT + Character devices that request a dynamic allocation of major number will + take numbers starting from 254 and downward. 240-254 block LOCAL/EXPERIMENTAL USE Allocated for local/experimental use. For devices not diff --git a/fs/char_dev.c b/fs/char_dev.c index 24b142569ca9..687471dc04a0 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -91,6 +91,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, break; } + if (i < CHRDEV_MAJOR_DYN_END) + pr_warn("CHRDEV \"%s\" major number %d goes below the dynamic allocation range", + name, i); + if (i == 0) { ret = -EBUSY; goto out; diff --git a/include/linux/fs.h b/include/linux/fs.h index 14a97194b34b..60082be96de8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2385,6 +2385,8 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev, /* fs/char_dev.c */ #define CHRDEV_MAJOR_HASH_SIZE 255 +/* Marks the bottom of the first segment of free char majors */ +#define CHRDEV_MAJOR_DYN_END 234 extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *); extern int register_chrdev_region(dev_t, unsigned, const char *); extern int __register_chrdev(unsigned int major, unsigned int baseminor, |