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