Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Nov 2007 05:56:22 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 128449 for review
Message-ID:  <200711010556.lA15uMkG097219@repoman.freebsd.org>

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

Change 128449 by kmacy@kmacy:storage:toestack on 2007/11/01 05:55:26

	don't trash rtentry's fields - we should be copying into rt_gateway
	be more careful about GC'ing rtentrys

Affected files ...

.. //depot/projects/toestack/sys/dev/cxgb/cxgb_l2t.c#11 edit

Differences ...

==== //depot/projects/toestack/sys/dev/cxgb/cxgb_l2t.c#11 (text+ko) ====

@@ -59,7 +59,7 @@
 
 #define VLAN_NONE 0xfff
 #define SDL(s) ((struct sockaddr_dl *)s) 
-#define RT_ENADDR(rt)  ((u_char *)LLADDR(SDL((rt))))
+#define RT_ENADDR(sa)  ((u_char *)LLADDR(SDL((sa))))
 #define rt_expire rt_rmx.rmx_expire 
 
 struct llinfo_arp { 
@@ -103,10 +103,8 @@
 	RT_ADDREF(rt);
 	RT_UNLOCK(rt);
 	
-	if (e->neigh) {
-		RT_LOCK(e->neigh);
-		RTFREE_LOCKED(e->neigh);
-	}
+	if (e->neigh)
+		RTFREE(e->neigh);
 	e->neigh = rt;
 }
 
@@ -137,7 +135,6 @@
 			    V_L2T_W_VLAN(e->vlan & EVL_VLID_MASK) |
 			    V_L2T_W_PRIO(vlan_prio(e)));
 
-	memcpy(e->dmac, RT_ENADDR(e->neigh), sizeof(e->dmac));
 	memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac));
 	m_set_priority(m, CPL_PRIORITY_CONTROL);
 	cxgb_ofld_send(dev, m);
@@ -173,12 +170,14 @@
 		     struct l2t_entry *e)
 {
 	struct rtentry *rt;
-
+	
 	rt = e->neigh;
+	printf("send slow on rt=%p\n", rt);
+	
 again:
 	switch (e->state) {
 	case L2T_STATE_STALE:     /* entry is stale, kick off revalidation */
-		arpresolve(rt->rt_ifp, rt, NULL, rt_key(rt), RT_ENADDR(rt));
+		arpresolve(rt->rt_ifp, rt, NULL, rt_key(rt), e->dmac);
 		mtx_lock(&e->lock);
 		if (e->state == L2T_STATE_STALE)
 			e->state = L2T_STATE_VALID;
@@ -203,8 +202,8 @@
 		 * A better way would be to use a work request to retry L2T
 		 * entries when there's no memory.
 		 */
-		printf("doing arpresolve\n");	
-		if (arpresolve(rt->rt_ifp, rt, NULL, rt_key(rt), RT_ENADDR(rt)) == 0) {
+		printf("doing arpresolve\n");
+		if (arpresolve(rt->rt_ifp, rt, NULL, rt_key(rt), e->dmac) == 0) {
 			if ((m = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
 				return (ENOMEM);
 
@@ -216,7 +215,6 @@
 			mtx_unlock(&e->lock);
 		} else
 			printf("arpresolve returned non-zero\n");
-		
 	}
 	return 0;
 }
@@ -234,7 +232,7 @@
 again:
 	switch (e->state) {
 	case L2T_STATE_STALE:     /* entry is stale, kick off revalidation */
-		arpresolve(rt->rt_ifp, rt, m0, rt_key(rt), RT_ENADDR(rt));
+		arpresolve(rt->rt_ifp, rt, m0, rt_key(rt), e->dmac);
 		mtx_lock(&e->lock);
 		if (e->state == L2T_STATE_STALE) {
 			e->state = L2T_STATE_VALID;
@@ -261,7 +259,7 @@
 		 * A better way would be to use a work request to retry L2T
 		 * entries when there's no memory.
 		 */
-		arpresolve(rt->rt_ifp, rt, m0, rt_key(rt), RT_ENADDR(rt));
+		arpresolve(rt->rt_ifp, rt, m0, rt_key(rt), e->dmac);
 
 	}
 	return;
@@ -319,19 +317,21 @@
 void
 t3_l2e_free(struct l2t_data *d, struct l2t_entry *e)
 {
+	struct rtentry *rt = NULL;
+	
 	mtx_lock(&e->lock);
 	if (atomic_load_acq_int(&e->refcnt) == 0) {  /* hasn't been recycled */
-		if (e->neigh) {
-			RT_LOCK(e->neigh);
-			RT_REMREF(e->neigh);
-			RT_UNLOCK(e->neigh);
-			e->neigh = NULL;
-		}
+		rt = e->neigh;
+		e->neigh = NULL;
 	}
+	
 	mtx_unlock(&e->lock);
 	atomic_add_int(&d->nfree, 1);
+	if (rt)
+		RTFREE(rt);
 }
 
+
 /*
  * Update an L2T entry that was previously used for the same next hop as neigh.
  * Must be called with softirqs disabled.
@@ -347,7 +347,7 @@
 	if (neigh != e->neigh)
 		neigh_replace(e, neigh);
 	
-	if (memcmp(e->dmac, RT_ENADDR(neigh), sizeof(e->dmac)) ||
+	if (memcmp(e->dmac, RT_ENADDR(neigh->rt_gateway), sizeof(e->dmac)) ||
 	    (neigh->rt_expire > time_uptime))
 		e->state = L2T_STATE_RESOLVING;
 	else if (la->la_hold == NULL)
@@ -453,9 +453,11 @@
 	int ifidx = neigh->rt_ifp->if_index;
 	int hash = arp_hash(addr, ifidx, d);
 	struct llinfo_arp *la;
+	u_char edst[ETHER_ADDR_LEN];
+	
 
-	arpresolve(neigh->rt_ifp, neigh, NULL, rt_key(neigh), RT_ENADDR(neigh));
-	    
+	arpresolve(neigh->rt_ifp, neigh, NULL, rt_key(neigh), edst);
+	
 	rw_rlock(&d->lock);
 	for (e = d->l2tab[hash].first; e; e = e->next)
 		if (e->addr == addr && e->ifindex == ifidx) {
@@ -467,6 +469,8 @@
 
 found:
 	rw_runlock(&d->lock);
+	memcpy(e->dmac, edst, ETHER_ADDR_LEN);
+	
 	if (atomic_load_acq_int(&e->refcnt)) {
 		if (neigh != e->neigh)
 			neigh_replace(e, neigh);
@@ -481,7 +485,7 @@
 				setup_l2e_send_pending(dev, NULL, e);
 		} else {
 			e->state = L2T_STATE_VALID;
-			if (memcmp(e->dmac, RT_ENADDR(neigh), 6))
+			if (memcmp(e->dmac, RT_ENADDR(neigh->rt_gateway), 6))
 				setup_l2e_send_pending(dev, NULL, e);
 		}
 	}



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