Date: Wed, 17 Sep 2003 17:55:45 +0200 From: Stefan Farfeleder <stefan@fafoe.narf.at> To: hackers@freebsd.org Subject: Major numbers reclaiming for make_dev/MAJOR_AUTO Message-ID: <20030917155544.GG697@wombat.fafoe.narf.at>
next in thread | raw e-mail | index | archive | help
--CUfgB8w4ZwR/yMy5 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, attached is a patch that tries to keep track of the major numbers that were assigned automatically by make_dev() if you use MAJOR_AUTO. The number of times make_dev() was called with this major number is stored in the reserved_majors_refcnt array, the entry is decreased again if you call destroy_dev(). If it reaches zero, the major number is released by resetting its reserved_majors entry to 0. This avoid the "Out of major numbers" panic after about 100 make_dev() calls with MAJOR_AUTO. Majors not assigned by MAJOR_AUTO are not affected. Does this look reasonable? Cheers, Stefan Farfeleder --CUfgB8w4ZwR/yMy5 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="reserved_majors.diff" Index: src/sys/kern/kern_conf.c =================================================================== RCS file: /usr/home/ncvs/src/sys/kern/kern_conf.c,v retrieving revision 1.134 diff -u -r1.134 kern_conf.c --- src/sys/kern/kern_conf.c 11 Jun 2003 00:56:55 -0000 1.134 +++ src/sys/kern/kern_conf.c 17 Sep 2003 15:40:12 -0000 @@ -46,6 +46,8 @@ /* Built at compile time from sys/conf/majors */ extern unsigned char reserved_majors[256]; +/* Only used for MAJOR_AUTO, 0 otherwise */ +static unsigned int reserved_majors_refcnt[256]; /* * This is the number of hash-buckets. Experiements with 'real-life' @@ -294,6 +296,7 @@ KASSERT(i > 0, ("Out of major numbers (%s)", devsw->d_name)); devsw->d_maj = i; reserved_majors[i] = i; + reserved_majors_refcnt[i] = 1; } else { if (devsw->d_maj == 256) /* XXX: tty_cons.c is magic */ devsw->d_maj = 0; @@ -305,6 +308,8 @@ devsw->d_maj); reserved_majors[devsw->d_maj] = devsw->d_maj; } + if (reserved_majors_refcnt[devsw->d_maj] > 0) + reserved_majors_refcnt[devsw->d_maj]++; } if (!ready_for_devs) { @@ -397,6 +402,7 @@ void destroy_dev(dev_t dev) { + struct cdevsw *d; if (!(dev->si_flags & SI_NAMED)) { printf( "WARNING: Driver mistake: destroy_dev on %d/%d\n", @@ -404,6 +410,11 @@ panic("don't do that"); } + d = devsw(dev); + if (reserved_majors_refcnt[d->d_maj] > 0) + if (--reserved_majors_refcnt[d->d_maj] == 0) + reserved_majors[d->d_maj] = 0; + devfs_destroy(dev); if (dev->si_flags & SI_CHILD) { LIST_REMOVE(dev, si_siblings); --CUfgB8w4ZwR/yMy5--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030917155544.GG697>