chrdev: emit a warning when we go below dynamic major range
authorLinus Walleij <linus.walleij@linaro.org>
Fri, 19 Feb 2016 14:36:07 +0000 (15:36 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 29 Mar 2016 17:11:44 +0000 (10:11 -0700)
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>
Documentation/devices.txt
fs/char_dev.c
include/linux/fs.h

index 87b4c5e82d39023094f9b5f9b10cf919e3740f9d..0a3588a9798d717b1b2d0212e2ebfa16a1941873 100644 (file)
@@ -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
index 24b142569ca9b5beea55b5cf6224b8ad81e6a16c..687471dc04a0a515f4a8dc4953297e6156880b64 100644 (file)
@@ -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;
index 14a97194b34ba16ba7906ae8c27b1767f266f317..60082be96de8749c5b9b34a1f72e353077a3ff63 100644 (file)
@@ -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,