tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: passive references



   Date: Wed, 10 Feb 2016 17:20:15 +0900
   From: Kengo NAKAHARA <k-nakahara%iij.ad.jp@localhost>

   I tried to use passive reference for a encaptab list itself instead of
   pserialize_read_enter().
   # As you know, packet processing path encap4_lookup() can sleep at
   # ep->func.

   I try to reuse psref for the encaptab list itself, however that must not
   be a normal usage, I see.

I think you can interleave pserialize read sections and passive
references like so:


struct encaptab *ep, *match, *next;
struct psref epref, matchref;
int s;

match = NULL;
s = pserialize_read_enter();
for (ep = encaptab.first; ep != NULL; ep = next) {
	membar_datadep_consumer();
	if (ep->af != AF_INET)
		continue;
	...
	if (psref_acquire(&epref, &ep->psrtarget, encaptab_psrclass) != 0)
		continue;
	pserialize_read_exit(s);
	prio = (*ep->func)(m, off, proto, ep->arg);
	if (prio > matchprio) {
		psref_copy(&matchref, &epref, encaptab_psrclass);
		match = ep;
		matchprio = prio;
	}
	s = pserialize_read_enter();
	next = ep->next;
	psref_release(&epref, &ep->psrtarget, encaptab_psrclass);
}
pserialize_read_exit(s);


We would need to add psref_copy, but that should be easy enough.


void
psref_copy(struct psref *new, const struct psref *old,
    struct psref_class *class)
{
	struct psref_cpu *cpu;
	int s;

	KASSERTMSG((kpreempt_disabled() || cpu_softintr_p() ||
		ISSET(curlwp->l_pflag, LP_BOUND)),
	    "passive references are CPU-local,"
	    " but preemption is enabled and the caller is not"
	    " in a softint or CPU-bound LWP");

#ifdef PSREF_DEBUG
	KASSERT(old->psref_lwp == curlwp);
	KASSERT(old->psref_cpu == curcpu());
	KASSERT(old->psref_target->prt_class == class);
#endif

	s = splraiseipl(class->prc_iplcookie);
	pcpu = percpu_getref(class->prc_percpu);
	LIST_INSERT_HEAD(&pcpu->pcpu_head, new, psref_entry);
	new->psref_target = old->psref_target;
#ifdef PSREF_DEBUG
	new->psref_lwp = curlwp;
	new->psref_cpu = curcpu();
#endif
	percpu_putref(class->prc_percpu);
	splx(s);
}


Home | Main Index | Thread Index | Old Index