tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Slight tweak to percpu API
Something about the current percpu API bothers me a little. It
currently says that callers must disable preemption before calling
percpu_getptr().
That seems cumbersome. It seems to be the percpu API could do this
for you. So I've changed the API like so:
- percpu_getptr() is now called percpu_putref() and implicitly
disables preemption (via crit_enter()) when it is called.
- Added percpu_putref() which implicitly reenables preemption (via
crit_exit()).
I also updated the only current in-tree user of the percpu API ...
uipc_mbuf.c.
Attached are the diffs. Any objections?
Index: kern/subr_percpu.c
===================================================================
RCS file: /cvsroot/src/sys/kern/subr_percpu.c,v
retrieving revision 1.3
diff -u -p -r1.3 subr_percpu.c
--- kern/subr_percpu.c 17 Mar 2008 08:27:50 -0000 1.3
+++ kern/subr_percpu.c 5 Apr 2008 20:03:39 -0000
@@ -269,20 +269,35 @@ 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.
*
Index: kern/uipc_mbuf.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.125
diff -u -p -r1.125 uipc_mbuf.c
--- kern/uipc_mbuf.c 24 Mar 2008 12:24:37 -0000 1.125
+++ kern/uipc_mbuf.c 5 Apr 2008 20:03:40 -0000
@@ -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 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 mown
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;
}
Index: sys/percpu.h
===================================================================
RCS file: /cvsroot/src/sys/sys/percpu.h,v
retrieving revision 1.2
diff -u -p -r1.2 percpu.h
--- sys/percpu.h 17 Jan 2008 09:01:57 -0000 1.2
+++ sys/percpu.h 5 Apr 2008 20:03:47 -0000
@@ -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_ */
-- thorpej
Home |
Main Index |
Thread Index |
Old Index