On Fri, 29 Oct 2010, Ted Unangst wrote:

> On Fri, 29 Oct 2010, Ted Unangst wrote:
> 
> > 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.

I'm not sure why the last version didn't apply, but I've updated the diff.  
Also, moved the yield check into the macro as suggested.

Index: pf_table.c
===================================================================
RCS file: /home/tedu/cvs/src/sys/net/pf_table.c,v
retrieving revision 1.87
diff -u -r1.87 pf_table.c
--- pf_table.c  23 Oct 2010 15:38:18 -0000      1.87
+++ pf_table.c  1 Nov 2010 02:33:16 -0000
@@ -61,6 +61,8 @@
        copyout((from), (to), (size)) :         \
        (bcopy((from), (to), (size)), 0))
 
+#define YIELD(cnt, ok) do { if ((cnt % 1024 == 1023) && (ok)) yield(); } while 
(0)
+
 #define        FILLIN_SIN(sin, addr)                   \
        do {                                    \
                (sin).sin_len = sizeof(sin);    \
@@ -261,6 +263,7 @@
                return (ENOMEM);
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               YIELD(i, flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        senderr(EFAULT);
                if (pfr_validate_addr(&ad))
@@ -349,6 +352,7 @@
        } else {
                /* iterate over addresses to delete */
                for (i = 0; i < size; i++) {
+                       YIELD(i, flags & PFR_FLAG_USERIOCTL);
                        if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                                return (EFAULT);
                        if (pfr_validate_addr(&ad))
@@ -360,6 +364,7 @@
        }
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               YIELD(i, flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        senderr(EFAULT);
                if (pfr_validate_addr(&ad))
@@ -429,6 +434,7 @@
        SLIST_INIT(&delq);
        SLIST_INIT(&changeq);
        for (i = 0; i < size; i++) {
+               YIELD(i, flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        senderr(EFAULT);
                if (pfr_validate_addr(&ad))
@@ -527,6 +533,7 @@
                return (ESRCH);
 
        for (i = 0; i < size; i++) {
+               YIELD(i, flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        return (EFAULT);
                if (pfr_validate_addr(&ad))
@@ -650,6 +657,7 @@
                return (ESRCH);
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               YIELD(i, flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        senderr(EFAULT);
                if (pfr_validate_addr(&ad))
@@ -823,8 +831,10 @@
 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) {
+               YIELD(i, 1);
                q = SLIST_NEXT(p, pfrke_workq);
                pfr_destroy_kentry(p);
        }
@@ -855,6 +865,7 @@
                }
                p->pfrke_tzero = tzero;
                ++n;
+               YIELD(n, 1);
        }
        kt->pfrkt_cnt += n;
 }
@@ -892,6 +903,7 @@
        SLIST_FOREACH(p, workq, pfrke_workq) {
                pfr_unroute_kentry(kt, p);
                ++n;
+               YIELD(n, 1);
        }
        kt->pfrkt_cnt -= n;
        pfr_destroy_kentries(workq);
@@ -934,6 +946,7 @@
        int             i;
 
        for (i = 0; i < size; i++) {
+               YIELD(i, flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        break;
                ad.pfra_fback = PFR_FB_NONE;
@@ -1171,6 +1184,7 @@
        SLIST_INIT(&addq);
        SLIST_INIT(&changeq);
        for (i = 0; i < size; i++) {
+               YIELD(i, 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,
@@ -1247,6 +1261,7 @@
        ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               YIELD(i, 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,
@@ -1364,6 +1379,7 @@
        ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_ADDRSTOO);
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               YIELD(i, 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))
@@ -1397,6 +1413,7 @@
                return (EINVAL);
        SLIST_INIT(&workq);
        for (i = 0; i < size; i++) {
+               YIELD(i, 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,
@@ -1525,6 +1542,7 @@
        }
        SLIST_INIT(&addrq);
        for (i = 0; i < size; i++) {
+               YIELD(i, flags & PFR_FLAG_USERIOCTL);
                if (COPYIN(addr+i, &ad, sizeof(ad), flags))
                        senderr(EFAULT);
                if (pfr_validate_addr(&ad))

Reply via email to