From 0cfa6e748791a5c8a58a1f1f19c38f642cd81b15 Mon Sep 17 00:00:00 2001 From: thorpej Date: Wed, 9 Apr 2008 05:11:20 +0000 Subject: [PATCH] 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()). --- sys/kern/subr_percpu.c | 25 ++++++++++++++++++++----- sys/kern/uipc_mbuf.c | 26 ++++++++++++-------------- sys/sys/percpu.h | 19 ++++++++++--------- 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/sys/kern/subr_percpu.c b/sys/kern/subr_percpu.c index 42b43f919fc0..35023404306d 100644 --- a/sys/kern/subr_percpu.c +++ b/sys/kern/subr_percpu.c @@ -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 -__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 #include @@ -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. diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 6cab44cca6c3..bdb26b0a52f6 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -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 -__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; } diff --git a/sys/sys/percpu.h b/sys/sys/percpu.h index a7d5eac639ee..8513af5deebb 100644 --- a/sys/sys/percpu.h +++ b/sys/sys/percpu.h @@ -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 -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_ */