On Mon, Dec 05, 2022 at 11:26:21AM +0100, Alexandr Nedvedicky wrote: > Hello, > On Mon, Dec 05, 2022 at 11:46:07AM +1000, David Gwynne wrote: > > > > yes, you're right. the diff below includes the simple fix to that. > > > > this demonstrates how subtle the reference counting around the trees > > is though. maybe it would be more obvious to take another refcnt > > before giving the pf_state_key to the tree(s), and then give the > > pf_state_key_attach callers reference to the pf_state struct. at > > the moment we give the callers reference to the tree while holding > > the PF_LOCK, and borrow it to give another one to the state while > > the lock is still held. > > Either way is fine in my opinion. > > </snip> > > @@ -766,44 +777,53 @@ pf_state_key_attach(struct pf_state_key > > /* remove late or sks can go away */ > > olds = si->s; > > } else { > > - pool_put(&pf_state_key_pl, sk); > > - return (-1); /* collision! */ > > + pf_state_key_unref(sk); > > + return (NULL); /* collision! */ > > } > > } > > - pool_put(&pf_state_key_pl, sk); > > - s->key[idx] = cur; > > - } else > > - s->key[idx] = sk; > > + } > > + > > + /* reuse the existing state key */ > > + pf_state_key_unref(sk); > > + sk = cur; > > + } > > > > if ((si = pool_get(&pf_state_item_pl, PR_NOWAIT)) == NULL) { > > - pf_state_key_detach(s, idx); > > - return (-1); > > + if (TAILQ_EMPTY(&sk->states)) { > > + KASSERT(cur == NULL); > > + RB_REMOVE(pf_state_tree, &pf_statetbl, sk); > > + sk->removed = 1; > > + pf_state_key_unref(sk); > > + } > > + > > + return (NULL); > > } > > I like your fix above. > > I also wonder if pf_state_insert() should be always setting *skwp, *sksp to > NULL. Just to indicate to caller the 'reference ownership got transferred' and > there is nothing left to worry about. This can be done right at the beginning > of pf_state_insert() after we assign to local variables skw/sks. Just a > thought/nit.
pf_test_rule uses the skw and sks pointers after pf_state_insert sets them via pf_create_state. i would happily change pf_test rule so it reads the pf_state_key pointers out of pf_state rather than carry them around on the stack like that, but i figured the diff was big enough as it was. > the recent diff is OK by me. thanks. i'll wait until i can be around to look after it before i commit it.