Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Sep 2007 20:45:15 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 126836 for review
Message-ID:  <200709262045.l8QKjFFS077373@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=126836

Change 126836 by kmacy@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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200709262045.l8QKjFFS077373>