now that the atomic flag is gone, the yield diff is simpler.  once again, 
the idea is that unbounded (or of unknown bounds) loops in the kernel are 
bad because you hog the cpu.  so be polite and yield from time to time.

anybody use tables heavily want to give it a test? :)

Index: pf_table.c
===================================================================
RCS file: /home/tedu/cvs/src/sys/net/pf_table.c,v
retrieving revision 1.86
diff -u -r1.86 pf_table.c
--- pf_table.c  30 Sep 2010 07:14:02 -0000      1.86
+++ pf_table.c  29 Oct 2010 03:59:20 -0000
@@ -61,6 +61,8 @@
        copyout((from), (to), (size)) :         \
        (bcopy((from), (to), (size)), 0))
 
+#define YIELD(ok) do { if (ok) yield(); } while (0)
+
 #define        FILLIN_SIN(sin, addr)                   \
        do {                                    \
                (sin).sin_len = sizeof(sin);    \
@@ -267,6 +269,8 @@
                return (ENOMEM);
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               if ((i % 1024) == 0)
+                       YIELD(flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        senderr(EFAULT);
                if (pfr_validate_addr(&ad))
@@ -360,6 +364,8 @@
        } else {
                /* iterate over addresses to delete */
                for (i = 0; i < size; i++) {
+                       if ((i % 1024) == 0)
+                               YIELD(flags & PFR_FLAG_USERIOCTL);
                        if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                                return (EFAULT);
                        if (pfr_validate_addr(&ad))
@@ -371,6 +377,8 @@
        }
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               if ((i % 1024) == 0)
+                       YIELD(flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        senderr(EFAULT);
                if (pfr_validate_addr(&ad))
@@ -445,6 +453,8 @@
        SLIST_INIT(&delq);
        SLIST_INIT(&changeq);
        for (i = 0; i < size; i++) {
+               if ((i % 1024) == 0)
+                       YIELD(flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        senderr(EFAULT);
                if (pfr_validate_addr(&ad))
@@ -547,6 +557,8 @@
                return (ESRCH);
 
        for (i = 0; i < size; i++) {
+               if ((i % 1024) == 0)
+                       YIELD(flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        return (EFAULT);
                if (pfr_validate_addr(&ad))
@@ -677,6 +689,8 @@
                return (ESRCH);
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               if ((i % 1024) == 0)
+                       YIELD(flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        senderr(EFAULT);
                if (pfr_validate_addr(&ad))
@@ -854,8 +868,11 @@
 pfr_destroy_kentries(struct pfr_kentryworkq *workq)
 {
        struct pfr_kentry       *p, *q;
+       int                      i;
 
-       for (p = SLIST_FIRST(workq); p != NULL; p = q) {
+       for (i = 0, p = SLIST_FIRST(workq); p != NULL; i++, p = q) {
+               if ((i % 1024) == 0)
+                       YIELD(1);
                q = SLIST_NEXT(p, pfrke_workq);
                pfr_destroy_kentry(p);
        }
@@ -886,6 +903,8 @@
                }
                p->pfrke_tzero = tzero;
                n++;
+               if ((n % 1024) == 0)
+                       YIELD(1);
        }
        kt->pfrkt_cnt += n;
 }
@@ -923,6 +942,8 @@
        SLIST_FOREACH(p, workq, pfrke_workq) {
                pfr_unroute_kentry(kt, p);
                n++;
+               if ((n % 1024) == 0)
+                       YIELD(1);
        }
        kt->pfrkt_cnt -= n;
        pfr_destroy_kentries(workq);
@@ -964,6 +985,8 @@
        int             i;
 
        for (i = 0; i < size; i++) {
+               if ((i % 1024) == 0)
+                       YIELD(flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        break;
                ad.pfra_fback = PFR_FB_NONE;
@@ -1206,6 +1229,8 @@
        SLIST_INIT(&addq);
        SLIST_INIT(&changeq);
        for (i = 0; i < size; i++) {
+               if ((i % 1024) == 0)
+                       YIELD(flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
                        senderr(EFAULT);
                if (pfr_validate_table(&key.pfrkt_t, PFR_TFLAG_USRMASK,
@@ -1286,6 +1311,8 @@
        ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               if ((i % 1024) == 0)
+                       YIELD(flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
                        return (EFAULT);
                if (pfr_validate_table(&key.pfrkt_t, 0,
@@ -1414,6 +1441,8 @@
            PFR_FLAG_ADDRSTOO);
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               if ((i % 1024) == 0)
+                       YIELD(flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
                        return (EFAULT);
                if (pfr_validate_table(&key.pfrkt_t, 0, 0))
@@ -1451,6 +1480,8 @@
                return (EINVAL);
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               if ((i % 1024) == 0)
+                       YIELD(flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
                        return (EFAULT);
                if (pfr_validate_table(&key.pfrkt_t, 0,
@@ -1583,6 +1614,8 @@
        }
        SLIST_INIT(&addrq);
        for (i = 0; i < size; i++) {
+               if ((i % 1024) == 0)
+                       YIELD(flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        senderr(EFAULT);
                if (pfr_validate_addr(&ad))

Reply via email to