Hello, > Lets switch to IPI method for fetch, similar to clear. > I do not think that the cost of fetch is too important comparing with > the race. > > diff --git a/sys/i386/include/counter.h b/sys/i386/include/counter.h > index 7fd26d2a960..278f89123a4 100644 > --- a/sys/i386/include/counter.h > +++ b/sys/i386/include/counter.h > @@ -72,7 +72,12 @@ counter_64_inc_8b(uint64_t *p, int64_t inc) > } > > #ifdef IN_SUBR_COUNTER_C > -static inline uint64_t > +struct counter_u64_fetch_cx8_arg { > + uint64_t res; > + uint64_t *p; > +}; > + > +static uint64_t > counter_u64_read_one_8b(uint64_t *p) > { > uint32_t res_lo, res_high; > @@ -87,9 +92,22 @@ counter_u64_read_one_8b(uint64_t *p) > return (res_lo + ((uint64_t)res_high << 32)); > } > > +static void > +counter_u64_fetch_cx8_one(void *arg1) > +{ > + struct counter_u64_fetch_cx8_arg *arg; > + uint64_t val; > + > + arg = arg1; > + val = counter_u64_read_one_8b((uint64_t *)((char *)arg->p + > + UMA_PCPU_ALLOC_SIZE * PCPU_GET(cpuid))); > + atomic_add_64(&arg->res, val); > +} > + > static inline uint64_t > counter_u64_fetch_inline(uint64_t *p) > { > + struct counter_u64_fetch_cx8_arg arg; > uint64_t res; > int i; > > @@ -108,9 +126,10 @@ counter_u64_fetch_inline(uint64_t *p) > } > critical_exit(); > } else { > - CPU_FOREACH(i) > - res += counter_u64_read_one_8b((uint64_t *)((char *)p + > - UMA_PCPU_ALLOC_SIZE * i)); > + arg.p = p; > + arg.res = 0; > + smp_rendezvous(NULL, counter_u64_fetch_cx8_one, NULL, &arg); > + res = arg.res; > } > return (res); > }
I have integrated this i386 counter(9) patch and using original pf.c to some of my test servers and everything runs fine. Today I have added my main firewall machine and will report in two weeks the result. I suppose running counter_u64_fetch() in parallel to counter_u64_add() is not a problem anymore. Andreas _______________________________________________ freebsd-pf@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-pf To unsubscribe, send any mail to "freebsd-pf-unsubscr...@freebsd.org"