Date: Sat, 02 Feb 2019 11:26:45 +0100 From: Andreas Longwitz <longwitz@incore.de> To: Konstantin Belousov <kib@freebsd.org> Cc: freebsd-pf@freebsd.org, Gleb Smirnoff <glebius@freebsd.org>, Kristof Provost <kristof@sigsegv.be> Subject: Re: rdr pass for proto tcp sometimes creates states with expire time zero and so breaking connections Message-ID: <5C557065.10600@incore.de> In-Reply-To: <20190125131409.GZ24863@kib.kiev.ua> References: <5BC51424.5000309@incore.de> <C4D1F141-2979-4103-957F-F0314637D978@sigsegv.be> <5BD45882.1000207@incore.de> <D5EEA773-1F0F-4FA0-A39A-486EE323907D@sigsegv.be> <5BEB3B9A.9080402@incore.de> <20181113222533.GJ9744@FreeBSD.org> <5C49ECAA.7060505@incore.de> <20190124203802.GU24863@kib.kiev.ua> <5C4A37A1.80206@incore.de> <20190125131409.GZ24863@kib.kiev.ua>
index | next in thread | previous in thread | raw e-mail
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
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5C557065.10600>
