Commit 49db08c3 authored by Linus Walleij's avatar Linus Walleij Committed by Greg Kroah-Hartman

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: default avatarYing 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: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 00411b7b
...@@ -3099,9 +3099,9 @@ Your cooperation is appreciated. ...@@ -3099,9 +3099,9 @@ Your cooperation is appreciated.
129 = /dev/ipath_sma Device used by Subnet Management Agent 129 = /dev/ipath_sma Device used by Subnet Management Agent
130 = /dev/ipath_diag Device used by diagnostics programs 130 = /dev/ipath_diag Device used by diagnostics programs
234-239 UNASSIGNED 234-254 char RESERVED FOR DYNAMIC ASSIGNMENT
Character devices that request a dynamic allocation of major number will
240-254 char LOCAL/EXPERIMENTAL USE take numbers starting from 254 and downward.
240-254 block LOCAL/EXPERIMENTAL USE 240-254 block LOCAL/EXPERIMENTAL USE
Allocated for local/experimental use. For devices not Allocated for local/experimental use. For devices not
......
...@@ -91,6 +91,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, ...@@ -91,6 +91,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
break; 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) { if (i == 0) {
ret = -EBUSY; ret = -EBUSY;
goto out; goto out;
......
...@@ -2385,6 +2385,8 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev, ...@@ -2385,6 +2385,8 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev,
/* fs/char_dev.c */ /* fs/char_dev.c */
#define CHRDEV_MAJOR_HASH_SIZE 255 #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 alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
extern int register_chrdev_region(dev_t, unsigned, const char *); extern int register_chrdev_region(dev_t, unsigned, const char *);
extern int __register_chrdev(unsigned int major, unsigned int baseminor, extern int __register_chrdev(unsigned int major, unsigned int baseminor,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment