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
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);
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to