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