PERFORCE change 126836 for review
Kip Macy
kmacy at FreeBSD.org
Wed Sep 26 13:45:16 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=126836
Change 126836 by kmacy at kmacy_home:ethng on 2007/09/26 20:44:42
set ext_free on allocated clusters so that they are cached by the driver on free
temporarily ifdef out prefetch call to avoid null pointer deref
add statistics on the number of cache hits versus allocated clusters
free cached buffers when destroying cxgb cache
fix cluster leak in cxgb_cache_put
add missing handling of non-standard cluster types in free routine
Affected files ...
.. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_sge.c#25 edit
.. //depot/projects/ethng/src/sys/dev/cxgb/sys/cxgb_support.c#3 edit
.. //depot/projects/ethng/src/sys/dev/cxgb/sys/mvec.h#7 edit
.. //depot/projects/ethng/src/sys/dev/cxgb/sys/uipc_mvec.c#7 edit
Differences ...
==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_sge.c#25 (text+ko) ====
@@ -77,8 +77,10 @@
static int recycle_enable = 1;
#endif
extern int cxgb_txq_mbuf_ring_size;
+int cxgb_cached_allocations;
+int cxgb_cached;
+int cxgb_ext_freed;
-
#define USE_GTS 0
#define SGE_RX_SM_BUF_SIZE 1536
@@ -2574,7 +2576,21 @@
#else
static void
-init_cluster_mbuf(caddr_t cl, int flags, int type)
+ext_free_handler(void *cl, void * arg)
+{
+ uintptr_t type = (uintptr_t)arg;
+ uma_zone_t zone;
+ struct mbuf *m;
+
+ m = cl;
+ zone = m_getzonefromtype(type);
+ m->m_ext.ext_type = (int)type;
+ cxgb_ext_freed++;
+ cxgb_cache_put(zone, cl);
+}
+
+static void
+init_cluster_mbuf(caddr_t cl, int flags, int type, uma_zone_t zone)
{
struct mbuf *m;
int header_size;
@@ -2591,7 +2607,9 @@
m->m_ext.ext_buf = cl;
m->m_ext.ref_cnt = (uint32_t *)(cl + header_size - sizeof(uint32_t));
m->m_ext.ext_size = m_getsizefromtype(type);
- m->m_ext.ext_type = type;
+ m->m_ext.ext_free = ext_free_handler;
+ m->m_ext.ext_args = (void *)(uintptr_t)type;
+ m->m_ext.ext_type = EXT_EXTREF;
*(m->m_ext.ref_cnt) = 1;
DPRINTF("data=%p ref_cnt=%p\n", m->m_data, m->m_ext.ref_cnt);
}
@@ -2610,10 +2628,12 @@
void *cl;
int ret = 0;
struct mbuf *m0;
-
- prefetch((sd + 1)->rxsd_cl);
- prefetch((sd + 2)->rxsd_cl);
-
+#if 0
+ if ((sd + 1 )->rxsd_cl)
+ prefetch((sd + 1)->rxsd_cl);
+ if ((sd + 2)->rxsd_cl)
+ prefetch((sd + 2)->rxsd_cl);
+#endif
DPRINTF("rx cpu=%d\n", curcpu);
fl->credits--;
bus_dmamap_sync(fl->entry_tag, sd->map, BUS_DMASYNC_POSTREAD);
@@ -2636,7 +2656,7 @@
case RSPQ_SOP_EOP:
DBG(DBG_RX, ("get_packet: SOP-EOP m %p\n", m));
if (cl == sd->rxsd_cl)
- init_cluster_mbuf(cl, M_PKTHDR, fl->type);
+ init_cluster_mbuf(cl, M_PKTHDR, fl->type, fl->zone);
m0->m_len = m0->m_pkthdr.len = len;
ret = 1;
goto done;
@@ -3095,6 +3115,18 @@
"bogus_imm",
CTLFLAG_RD, &bogus_imm,
0, "#times a bogus immediate response was seen");
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO,
+ "cache_alloc",
+ CTLFLAG_RD, &cxgb_cached_allocations,
+ 0, "#times a cluster was allocated from cache");
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO,
+ "cached",
+ CTLFLAG_RD, &cxgb_cached,
+ 0, "#times a cluster was cached");
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO,
+ "ext_freed",
+ CTLFLAG_RD, &cxgb_ext_freed,
+ 0, "#times a cluster was freed through ext_free");
}
==== //depot/projects/ethng/src/sys/dev/cxgb/sys/cxgb_support.c#3 (text+ko) ====
@@ -137,10 +137,13 @@
static void
cxgb_cache_pcpu_deinit(struct cxgb_cache_pcpu *ccp)
{
- /*
- * XXX free clusters
- */
-
+ void *cl;
+
+ while ((cl = buf_stack_pop(&ccp->ccp_jumbo_free)) != NULL)
+ uma_zfree(ccp->ccp_jumbo_zone, cl);
+ while ((cl = buf_stack_pop(&ccp->ccp_cluster_free)) != NULL)
+ uma_zfree(zone_clust, cl);
+
buf_stack_deinit(&ccp->ccp_jumbo_free);
buf_stack_deinit(&ccp->ccp_cluster_free);
@@ -191,21 +194,23 @@
caddr_t
cxgb_cache_get(uma_zone_t zone)
{
- caddr_t cl;
+ caddr_t cl = NULL;
struct cxgb_cache_pcpu *ccp;
critical_enter();
ccp = &cxgb_caches->ccs_array[curcpu];
if (zone == zone_clust) {
cl = buf_stack_pop(&ccp->ccp_cluster_free);
- } else {
+ } else if (zone == ccp->ccp_jumbo_zone) {
cl = buf_stack_pop(&ccp->ccp_jumbo_free);
}
critical_exit();
if (cl == NULL)
cl = uma_zalloc(zone, M_NOWAIT);
-
+ else
+ cxgb_cached_allocations++;
+
return (cl);
}
@@ -213,7 +218,7 @@
cxgb_cache_put(uma_zone_t zone, void *cl)
{
struct cxgb_cache_pcpu *ccp;
- int err = 0;
+ int err = ENOSPC;
critical_enter();
ccp = &cxgb_caches->ccs_array[curcpu];
@@ -226,6 +231,8 @@
if (err)
uma_zfree(zone, cl);
+ else
+ cxgb_cached++;
}
void
==== //depot/projects/ethng/src/sys/dev/cxgb/sys/mvec.h#7 (text+ko) ====
@@ -42,6 +42,10 @@
void cxgb_cache_rebalance(void);
+extern int cxgb_cached_allocations;
+extern int cxgb_cached;
+extern int cxgb_ext_freed;
+
#define mtomv(m) ((struct mbuf_vec *)((m)->m_pktdat))
#define M_IOVEC 0x100000 /* mbuf immediate data area is used for cluster ptrs */
==== //depot/projects/ethng/src/sys/dev/cxgb/sys/uipc_mvec.c#7 (text+ko) ====
@@ -312,6 +312,20 @@
break;
case EXT_JUMBO16:
uma_zfree(zone_jumbo16, cl);
+ break;
+ case EXT_SFBUF:
+ case EXT_NET_DRV:
+ case EXT_MOD_TYPE:
+ case EXT_DISPOSABLE:
+ *(mi->mi_refcnt) = 0;
+ uma_zfree(zone_ext_refcnt, __DEVOLATILE(u_int *,
+ mi->mi_ext.ref_cnt));
+ /* FALLTHROUGH */
+ case EXT_EXTREF:
+ KASSERT(mi->mi_ext.ext_free != NULL,
+ ("%s: ext_free not set", __func__));
+ (*(mi->mi_ext.ext_free))(mi->mi_ext.ext_buf,
+ mi->mi_ext.ext_args);
break;
default:
panic("unknown mv type in m_free_vec type=%d", type);
More information about the p4-projects
mailing list