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>