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))