PERFORCE change 128449 for review
Kip Macy
kmacy at FreeBSD.org
Wed Oct 31 22:56:23 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=128449
Change 128449 by kmacy at 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);
}
}
More information about the p4-projects
mailing list