chrdev: allocate dynamic chardevs in all unused holes
This is a duct-tape-and-chewing-gum solution to the problem
with the major numbers running out when allocating major
To avoid collisions in the major space, we supply a bitmap with
"holes" that exist in the lower range of major numbers [0-254]
and pick numbers from there, beginning with the unused char
device 8 and moving up through 26, 40, 60-63, 93-94, 102,
120-127, 159, 213-215, 222-223 and 234-254.
The algorithm will behave like the old dynamic assignment
to begin with: dynamic majors will be assigned starting with
254, 253, ... but when it reaches 234 it will make a jump
and assign 223 and so on.
It will also FAIL if we actually fill up all free major
numbers. This seems to me like the reasonable thing to do
since the other numbers are, after all, reserved.
This also deletes the comment /* temporary */ which must be
one of the biggest lies ever.
This also updates the Documentation/devices.txt document to
reflect that all these numbers are used for dynamic assignment.
Reported-by: Ying Huang <firstname.lastname@example.org>
Cc: Linus Torvalds <email@example.com>
Cc: Greg Kroah-Hartman <firstname.lastname@example.org>
Cc: Alan Cox <email@example.com>
Cc: Arnd Bergmann <firstname.lastname@example.org>
Signed-off-by: Linus Walleij <email@example.com>
- Create a new macro, BITS32() in <linux/bitops.> that allow
us to make an intuitive bitmask for the existing major
number. This reuses GENMASK(), clamps the arguments and
switch them around: to me it is atleast most intuitive to
have the lower bit before the higher one.
- Use BITS32() and BIT_MASK() to define the bitlist for
- Assign dynamic majors from the top down (254, 253...) like
the old code was doing. I tried assigning bottom up
(8, 20,...) but that gave rise to "interesting" phenomena
on Intels test servers running random QEMU: character
devices in the lower range would stop probing properly,
even if they have a major number not colliding with the
dynamic assignment. At one time IDE tape (major 37) and
one time ISDN (major 45). No clue as to why.
- Create the BITS() macro in a separate patch. This was
more tangled up than I thought, as the nice build servers
quickly told me.
- Of course I had a dangling hunk for pr_dbg()->pr_debug()
in my working tree. Mea culpa.
- Fix the redefinition of BITS() in select.c to use the
more precise name FDS_BITS() over the generic plural.
- Follow-up on the previous RFC patch, this uses Torvald's
suggested bitmap approach to allocate devices instead of
a list of free numbers.
- As a result of using find_first_zero_bit(), the major
numbers are assigned from low to high instead from high
to low. It's a bit scarier but I guess drivers using
dynamic numbers should be all right with it, I'm more
worried about userspaces expecting dynamic majors to
be in the [234,254] range. Input welcome, maybe I'm
- This still needs to be applied on top of the previous
fix to start warning about going below major 234. If
you prefer to just get this patch and get rid of the
problem then tell me.
4 files changed