Make the percpu API a little more friendly:

- percpu_getptr() is now called percpu_getref() and implicitly disables
  preemption (via crit_enter()) when it is called.
- Added percpu_putref() which implicitly reenables preemption (via
  crit_exit()).
This commit is contained in:
thorpej 2008-04-09 05:11:20 +00:00
parent 1e77327a1b
commit 0cfa6e7487
3 changed files with 42 additions and 28 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr_percpu.c,v 1.3 2008/03/17 08:27:50 yamt Exp $ */
/* $NetBSD: subr_percpu.c,v 1.4 2008/04/09 05:11:20 thorpej Exp $ */
/*-
* Copyright (c)2007,2008 YAMAMOTO Takashi,
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: subr_percpu.c,v 1.3 2008/03/17 08:27:50 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: subr_percpu.c,v 1.4 2008/04/09 05:11:20 thorpej Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@ -269,19 +269,34 @@ percpu_free(percpu_t *pc, size_t size)
}
/*
* percpu_getptr:
* percpu_getref:
*
* => called with preemption disabled
* => safe to be used in either thread or interrupt context
* => disables preemption; must be bracketed with a percpu_putref()
*/
void *
percpu_getptr(percpu_t *pc)
percpu_getref(percpu_t *pc)
{
crit_enter();
return percpu_getptr_remote(pc, curcpu());
}
/*
* percpu_putref:
*
* => drops the preemption-disabled count after caller is done with per-cpu
* data
*/
void
percpu_putref(percpu_t *pc)
{
crit_exit();
}
/*
* percpu_traverse_enter, percpu_traverse_exit, percpu_getptr_remote:
* helpers to access remote cpu's percpu data.

View File

@ -1,4 +1,4 @@
/* $NetBSD: uipc_mbuf.c,v 1.125 2008/03/24 12:24:37 yamt Exp $ */
/* $NetBSD: uipc_mbuf.c,v 1.126 2008/04/09 05:11:20 thorpej Exp $ */
/*-
* Copyright (c) 1999, 2001 The NetBSD Foundation, Inc.
@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.125 2008/03/24 12:24:37 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.126 2008/04/09 05:11:20 thorpej Exp $");
#include "opt_mbuftrace.h"
#include "opt_ddb.h"
@ -1657,8 +1657,9 @@ mbstat_type_add(int type, int diff)
int s;
s = splvm();
mb = percpu_getptr(mbstat_percpu);
mb = percpu_getref(mbstat_percpu);
mb->m_mtypes[type] += diff;
percpu_putref(mbstat_percpu);
splx(s);
}
@ -1687,13 +1688,6 @@ mowner_detach(struct mowner *mo)
mo->mo_counters = NULL;
}
static struct mowner_counter *
mowner_counter(struct mowner *mo)
{
return percpu_getptr(mo->mo_counters);
}
void
mowner_init(struct mbuf *m, int type)
{
@ -1703,8 +1697,9 @@ mowner_init(struct mbuf *m, int type)
m->m_owner = mo = &unknown_mowners[type];
s = splvm();
mc = mowner_counter(mo);
mc = percpu_getref(mo->mo_counters);
mc->mc_counter[MOWNER_COUNTER_CLAIMS]++;
percpu_putref(mo->mo_counters);
splx(s);
}
@ -1716,11 +1711,12 @@ mowner_ref(struct mbuf *m, int flags)
int s;
s = splvm();
mc = mowner_counter(mo);
mc = percpu_getref(mo->mo_counters);
if ((flags & M_EXT) != 0)
mc->mc_counter[MOWNER_COUNTER_EXT_CLAIMS]++;
if ((flags & M_CLUSTER) != 0)
mc->mc_counter[MOWNER_COUNTER_CLUSTER_CLAIMS]++;
percpu_putref(mo->mo_counters);
splx(s);
}
@ -1732,13 +1728,14 @@ mowner_revoke(struct mbuf *m, bool all, int flags)
int s;
s = splvm();
mc = mowner_counter(mo);
mc = percpu_getref(mo->mo_counters);
if ((flags & M_EXT) != 0)
mc->mc_counter[MOWNER_COUNTER_EXT_RELEASES]++;
if ((flags & M_CLUSTER) != 0)
mc->mc_counter[MOWNER_COUNTER_CLUSTER_RELEASES]++;
if (all)
mc->mc_counter[MOWNER_COUNTER_RELEASES]++;
percpu_putref(mo->mo_counters);
splx(s);
if (all)
m->m_owner = &revoked_mowner;
@ -1752,12 +1749,13 @@ mowner_claim(struct mbuf *m, struct mowner *mo)
int s;
s = splvm();
mc = mowner_counter(mo);
mc = percpu_getref(mo->mo_counters);
mc->mc_counter[MOWNER_COUNTER_CLAIMS]++;
if ((flags & M_EXT) != 0)
mc->mc_counter[MOWNER_COUNTER_EXT_CLAIMS]++;
if ((flags & M_CLUSTER) != 0)
mc->mc_counter[MOWNER_COUNTER_CLUSTER_CLAIMS]++;
percpu_putref(mo->mo_counters);
splx(s);
m->m_owner = mo;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: percpu.h,v 1.2 2008/01/17 09:01:57 yamt Exp $ */
/* $NetBSD: percpu.h,v 1.3 2008/04/09 05:11:20 thorpej Exp $ */
/*-
* Copyright (c)2007,2008 YAMAMOTO Takashi,
@ -31,18 +31,19 @@
#include <sys/percpu_types.h>
void percpu_init(void);
void percpu_init_cpu(struct cpu_info *);
void percpu_init(void);
void percpu_init_cpu(struct cpu_info *);
percpu_t *percpu_alloc(size_t);
void percpu_free(percpu_t *, size_t);
void *percpu_getptr(percpu_t *);
void percpu_free(percpu_t *, size_t);
void *percpu_getref(percpu_t *);
void percpu_putref(percpu_t *);
typedef void (*percpu_callback_t)(void *, void *, struct cpu_info *);
void percpu_foreach(percpu_t *, percpu_callback_t, void *);
void percpu_foreach(percpu_t *, percpu_callback_t, void *);
/* low-level api; don't use unless necessary */
void percpu_traverse_enter(void);
void percpu_traverse_exit(void);
void *percpu_getptr_remote(percpu_t *, struct cpu_info *);
void percpu_traverse_enter(void);
void percpu_traverse_exit(void);
void *percpu_getptr_remote(percpu_t *, struct cpu_info *);
#endif /* _SYS_PERCPU_H_ */