Date: Mon, 31 Mar 2014 22:41:13 +0300 From: Mikolaj Golub <trociny@FreeBSD.org> To: Martin Matuska <mm@FreeBSD.org> Cc: freebsd-pf@FreeBSD.org Subject: Re: CFR projects/pf: vnet awareness for pf_overloadqueue Message-ID: <20140331194109.GA17582@gmail.com> In-Reply-To: <5337D55A.6030607@FreeBSD.org> References: <5337D55A.6030607@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Mar 30, 2014 at 10:27:06AM +0200, Martin Matuska wrote: > Hi, > > with the pf_mtag_z patch applied, the second patch that fixes panics I > experience is the overload queue patch. > > I have looked into solving this via context (adding a "struct vnet" > member to pf_overload_entry). This leaves unsolved problems - first, we > have now vnet information on per-entry instead of per-queue. > > There are two places in pf_overload_task() where we are not processing > an entry but need vnet information: > > 1. V_pf_idhash[i] in pf_overload_task(): > > for (int i = 0; i <= pf_hashmask; i++) { > struct pf_idhash *ih = &V_pf_idhash[i]; > struct pf_state_key *sk; > struct pf_state *s; > > PF_HASHROW_LOCK(ih); > LIST_FOREACH(s, &ih->states, entry) { > > 2. end of pf_overload_task() but that is only the debug tunable > V_pf_status_debug: > > if (V_pf_status.debug >= PF_DEBUG_MISC) > printf("%s: %u states killed", __func__, killed); > > On the other hand, if we want to keep per-vnet overloadqueues than it > makes sense to store vnet information on queue level. > If we pack vnet information into each entry and the overloadqueue has > global locks anyway, why not keeping a single global queue with entries > from different vnets? > > At the current state the code causes panics if pf_overload_task() is > fired because vnet context is missing. It needs to be fixed in any of > the ways. A patch for adding per-queue vnet information is attached. Martin, I think you missed my point in the message to src@. You don't need to embed vnet into pf_overloadqueue. What you need is a way to access it in a right vnet context, i.e. by passing vnet as an argument to pf_overload_task: pf_vnet_initialize(): - TASK_INIT(&V_pf_overloadtask, 0, pf_overload_task, &V_pf_overloadqueue); + TASK_INIT(&V_pf_overloadtask, 0, pf_overload_task, curvnet); pf_overload_task(void *c, int pending): { + struct vnet *vnet; struct pf_overload_head queue; struct pfr_addr p; struct pf_overload_entry *pfoe, *pfoe1; uint32_t killed = 0; + vnet = (vnet *)c; + CURVNET_SET(vnet); PF_OVERLOADQ_LOCK(); - queue = *(struct pf_overload_head *)c; - SLIST_INIT((struct pf_overload_head *)c); + queue = V_pf_overloadqueue; + SLIST_INIT(V_pf_overloadqueue); PF_OVERLOADQ_UNLOCK(); -- Mikolaj Golub
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140331194109.GA17582>