Date: Fri, 2 Nov 2007 01:31:52 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 128493 for review Message-ID: <200711020131.lA21VqYU049492@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=128493 Change 128493 by kmacy@freefall_kmacy_iwarp on 2007/11/02 01:31:35 IFtoestack #128449 Affected files ... .. //depot/projects/iwarp/sys/amd64/conf/MULTIQ#2 integrate .. //depot/projects/iwarp/sys/conf/files#3 integrate .. //depot/projects/iwarp/sys/dev/cxgb/cxgb_adapter.h#3 integrate .. //depot/projects/iwarp/sys/dev/cxgb/cxgb_l2t.c#3 integrate .. //depot/projects/iwarp/sys/dev/cxgb/cxgb_l2t.h#3 integrate .. //depot/projects/iwarp/sys/dev/cxgb/cxgb_main.c#3 integrate .. //depot/projects/iwarp/sys/dev/cxgb/cxgb_multiq.c#3 integrate .. //depot/projects/iwarp/sys/dev/cxgb/cxgb_offload.c#3 integrate .. //depot/projects/iwarp/sys/dev/cxgb/cxgb_offload.h#3 integrate .. //depot/projects/iwarp/sys/dev/cxgb/cxgb_sge.c#3 integrate .. //depot/projects/iwarp/sys/dev/cxgb/sys/mvec.h#2 integrate .. //depot/projects/iwarp/sys/dev/cxgb/t3cdev.h#2 integrate .. //depot/projects/iwarp/sys/dev/cxgb/ulp/toecore/toedev.c#1 branch .. //depot/projects/iwarp/sys/dev/cxgb/ulp/toecore/toedev.h#2 integrate .. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#1 branch .. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c#1 branch .. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_defs.h#1 branch .. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_listen.c#1 branch .. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_t3_ddp.h#1 branch .. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_tom.c#1 branch .. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_tom.h#1 branch .. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_tom_sysctl.c#1 branch .. //depot/projects/iwarp/sys/modules/cxgb/Makefile#2 integrate .. //depot/projects/iwarp/sys/modules/cxgb/toecore/Makefile#1 branch .. //depot/projects/iwarp/sys/modules/cxgb/tom/Makefile#1 branch .. //depot/projects/iwarp/sys/net/if.h#2 integrate .. //depot/projects/iwarp/sys/net/route.c#3 integrate .. //depot/projects/iwarp/sys/net/route.h#2 integrate .. //depot/projects/iwarp/sys/netinet/if_ether.c#3 integrate .. //depot/projects/iwarp/sys/netinet/ip_icmp.c#3 integrate .. //depot/projects/iwarp/sys/netinet/tcp_ofld.c#1 branch .. //depot/projects/iwarp/sys/netinet/tcp_ofld.h#1 branch .. //depot/projects/iwarp/sys/netinet/tcp_subr.c#3 integrate .. //depot/projects/iwarp/sys/netinet/tcp_usrreq.c#3 integrate .. //depot/projects/iwarp/sys/netinet/tcp_var.h#2 integrate .. //depot/projects/iwarp/sys/sys/param.h#3 integrate .. //depot/projects/iwarp/sys/sys/socket.h#2 integrate Differences ... ==== //depot/projects/iwarp/sys/amd64/conf/MULTIQ#2 (text+ko) ==== @@ -80,6 +80,8 @@ # CPU frequency control device cpufreq +options HWPMC_HOOKS + # Bus support. device acpi device pci ==== //depot/projects/iwarp/sys/conf/files#3 (text+ko) ==== @@ -1893,6 +1893,7 @@ netinet/tcp_timer.c optional inet netinet/tcp_timewait.c optional inet netinet/tcp_usrreq.c optional inet +netinet/tcp_ofld.c optional inet netinet/udp_usrreq.c optional inet netinet/libalias/alias.c optional libalias | netgraph_nat netinet/libalias/alias_db.c optional libalias | netgraph_nat ==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_adapter.h#3 (text+ko) ==== @@ -151,11 +151,9 @@ #define RSPQ_Q_SIZE 1024 #define TX_ETH_Q_SIZE 1024 -/* - * Types of Tx queues in each queue set. Order here matters, do not change. - * XXX TOE is not implemented yet, so the extra queues are just placeholders. - */ -enum { TXQ_ETH, TXQ_OFLD, TXQ_CTRL }; +enum { TXQ_ETH = 0, + TXQ_OFLD = 1, + TXQ_CTRL = 2, }; /* careful, the following are set on priv_flags and must not collide with ==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_l2t.c#3 (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,11 +103,8 @@ RT_ADDREF(rt); RT_UNLOCK(rt); - if (e->neigh) { - RT_LOCK(e->neigh); - RT_REMREF(e->neigh); - RT_UNLOCK(e->neigh); - } + if (e->neigh) + RTFREE(e->neigh); e->neigh = rt; } @@ -130,13 +127,14 @@ * XXX MH_ALIGN */ req = mtod(m, struct cpl_l2t_write_req *); + m->m_pkthdr.len = m->m_len = sizeof(*req); + req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, e->idx)); req->params = htonl(V_L2T_W_IDX(e->idx) | V_L2T_W_IFF(e->smt_idx) | 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); @@ -172,17 +170,14 @@ struct l2t_entry *e) { struct rtentry *rt; - struct mbuf *m0; - if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL) - return (ENOMEM); - 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, m0, rt->rt_gateway, 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; @@ -197,9 +192,8 @@ } arpq_enqueue(e, m); mtx_unlock(&e->lock); - - if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL) - return (ENOMEM); + printf("enqueueing arp request\n"); + /* * Only the first packet added to the arpq should kick off * resolution. However, because the m_gethdr below can fail, @@ -208,7 +202,10 @@ * A better way would be to use a work request to retry L2T * entries when there's no memory. */ - if (arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, 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); mtx_lock(&e->lock); if (e->arpq_head) @@ -216,7 +213,8 @@ else m_freem(m); 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->rt_gateway, 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->rt_gateway, RT_ENADDR(rt)); + arpresolve(rt->rt_ifp, rt, m0, rt_key(rt), e->dmac); } return; @@ -301,6 +299,7 @@ } e->state = L2T_STATE_UNUSED; } + return e; } @@ -318,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. @@ -346,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) @@ -379,14 +380,20 @@ /* Need to allocate a new entry */ e = alloc_l2e(d); if (e) { + printf("initializing new entry\n"); + mtx_lock(&e->lock); /* avoid race with t3_l2t_free */ e->next = d->l2tab[hash].first; d->l2tab[hash].first = e; + rw_wunlock(&d->lock); + e->state = L2T_STATE_RESOLVING; e->addr = addr; e->ifindex = ifidx; e->smt_idx = smt_idx; atomic_store_rel_int(&e->refcnt, 1); + e->neigh = NULL; + neigh_replace(e, neigh); #ifdef notyet /* @@ -398,7 +405,10 @@ #endif e->vlan = VLAN_NONE; mtx_unlock(&e->lock); + + return (e); } + done: rw_wunlock(&d->lock); return e; @@ -433,11 +443,6 @@ } -#if defined(NETEVENT) || !defined(CONFIG_CHELSIO_T3_MODULE) -/* - * Called when the host's ARP layer makes a change to some entry that is - * loaded into the HW L2 table. - */ void t3_l2t_update(struct t3cdev *dev, struct rtentry *neigh) { @@ -448,7 +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), edst); + rw_rlock(&d->lock); for (e = d->l2tab[hash].first; e; e = e->next) if (e->addr == addr && e->ifindex == ifidx) { @@ -460,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); @@ -470,12 +481,11 @@ if (la->la_asked >= 5 /* arp_maxtries */) { arpq = e->arpq_head; e->arpq_head = e->arpq_tail = NULL; - } else if (la->la_hold == NULL) + } else setup_l2e_send_pending(dev, NULL, e); } else { - e->state = (la->la_hold == NULL) ? - L2T_STATE_VALID : L2T_STATE_STALE; - if (memcmp(e->dmac, RT_ENADDR(neigh), 6)) + e->state = L2T_STATE_VALID; + if (memcmp(e->dmac, RT_ENADDR(neigh->rt_gateway), 6)) setup_l2e_send_pending(dev, NULL, e); } } @@ -484,72 +494,7 @@ if (arpq) handle_failed_resolution(dev, arpq); } -#else -/* - * Called from a kprobe, interrupts are off. - */ -void -t3_l2t_update(struct t3cdev *dev, struct rtentry *neigh) -{ - struct l2t_entry *e; - struct l2t_data *d = L2DATA(dev); - u32 addr = *(u32 *) rt_key(neigh); - int ifidx = neigh->dev->ifindex; - int hash = arp_hash(addr, ifidx, d); - - rw_rlock(&d->lock); - for (e = d->l2tab[hash].first; e; e = e->next) - if (e->addr == addr && e->ifindex == ifidx) { - mtx_lock(&e->lock); - if (atomic_load_acq_int(&e->refcnt)) { - if (neigh != e->neigh) - neigh_replace(e, neigh); - e->tdev = dev; - mod_timer(&e->update_timer, jiffies + 1); - } - mtx_unlock(&e->lock); - break; - } - rw_runlock(&d->lock); -} - -static void -update_timer_cb(unsigned long data) -{ - struct mbuf *arpq = NULL; - struct l2t_entry *e = (struct l2t_entry *)data; - struct rtentry *neigh = e->neigh; - struct t3cdev *dev = e->tdev; - barrier(); - if (!atomic_load_acq_int(&e->refcnt)) - return; - - rw_rlock(&neigh->lock); - mtx_lock(&e->lock); - - if (atomic_load_acq_int(&e->refcnt)) { - if (e->state == L2T_STATE_RESOLVING) { - if (neigh->nud_state & NUD_FAILED) { - arpq = e->arpq_head; - e->arpq_head = e->arpq_tail = NULL; - } else if (neigh_is_connected(neigh) && e->arpq_head) - setup_l2e_send_pending(dev, NULL, e); - } else { - e->state = neigh_is_connected(neigh) ? - L2T_STATE_VALID : L2T_STATE_STALE; - if (memcmp(e->dmac, RT_ENADDR(neigh), sizeof(e->dmac))) - setup_l2e_send_pending(dev, NULL, e); - } - } - mtx_unlock(&e->lock); - rw_runlock(&neigh->lock); - - if (arpq) - handle_failed_resolution(dev, arpq); -} -#endif - struct l2t_data * t3_init_l2t(unsigned int l2t_capacity) { @@ -570,12 +515,6 @@ d->l2tab[i].state = L2T_STATE_UNUSED; mtx_init(&d->l2tab[i].lock, "L2TAB", NULL, MTX_DEF); atomic_store_rel_int(&d->l2tab[i].refcnt, 0); -#ifndef NETEVENT -#ifdef CONFIG_CHELSIO_T3_MODULE - setup_timer(&d->l2tab[i].update_timer, update_timer_cb, - (unsigned long)&d->l2tab[i]); -#endif -#endif } return d; } @@ -583,86 +522,6 @@ void t3_free_l2t(struct l2t_data *d) { -#ifndef NETEVENT -#ifdef CONFIG_CHELSIO_T3_MODULE - int i; - - /* Stop all L2T timers */ - for (i = 0; i < d->nentries; ++i) - del_timer_sync(&d->l2tab[i].update_timer); -#endif -#endif cxgb_free_mem(d); } -#ifdef CONFIG_PROC_FS -#include <linux/module.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> - -static inline void * -l2t_get_idx(struct seq_file *seq, loff_t pos) -{ - struct l2t_data *d = seq->private; - - return pos >= d->nentries ? NULL : &d->l2tab[pos]; -} - -static void * -l2t_seq_start(struct seq_file *seq, loff_t *pos) -{ - return *pos ? l2t_get_idx(seq, *pos) : SEQ_START_TOKEN; -} - -static void * -l2t_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - v = l2t_get_idx(seq, *pos + 1); - if (v) - ++*pos; - return v; -} - -static void -l2t_seq_stop(struct seq_file *seq, void *v) -{ -} - -static char -l2e_state(const struct l2t_entry *e) -{ - switch (e->state) { - case L2T_STATE_VALID: return 'V'; /* valid, fast-path entry */ - case L2T_STATE_STALE: return 'S'; /* needs revalidation, but usable */ - case L2T_STATE_RESOLVING: - return e->arpq_head ? 'A' : 'R'; - default: - return 'U'; - } -} - -static int -l2t_seq_show(struct seq_file *seq, void *v) -{ - if (v == SEQ_START_TOKEN) - seq_puts(seq, "Index IP address Ethernet address VLAN " - "Prio State Users SMTIDX Port\n"); - else { - char ip[20]; - struct l2t_entry *e = v; - - mtx_lock(&e->lock); - sprintf(ip, "%u.%u.%u.%u", NIPQUAD(e->addr)); - seq_printf(seq, "%-5u %-15s %02x:%02x:%02x:%02x:%02x:%02x %4d" - " %3u %c %7u %4u %s\n", - e->idx, ip, e->dmac[0], e->dmac[1], e->dmac[2], - e->dmac[3], e->dmac[4], e->dmac[5], - e->vlan & EVL_VLID_MASK, vlan_prio(e), - l2e_state(e), atomic_load_acq_int(&e->refcnt), e->smt_idx, - e->neigh ? e->neigh->dev->name : ""); - mtx_unlock(&e->lock); - } - return 0; -} - -#endif ==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_l2t.h#3 (text+ko) ==== @@ -76,12 +76,6 @@ struct mtx lock; volatile uint32_t refcnt; /* entry reference count */ uint8_t dmac[6]; /* neighbour's MAC address */ -#ifndef NETEVENT -#ifdef CONFIG_CHELSIO_T3_MODULE - struct timer_list update_timer; - struct t3cdev *tdev; -#endif -#endif }; struct l2t_data { @@ -95,6 +89,9 @@ typedef void (*arp_failure_handler_func)(struct t3cdev *dev, struct mbuf *m); +typedef void (*opaque_arp_failure_handler_func)(void *dev, + struct mbuf *m); + /* * Callback stored in an skb to handle address resolution failure. */ @@ -111,10 +108,10 @@ static __inline void set_arp_failure_handler(struct mbuf *m, arp_failure_handler_func hnd) { -#if 0 - L2T_SKB_CB(skb)->arp_failure_handler = hnd; -#endif - panic("implement me"); + struct toe_mbuf *tm = (struct toe_mbuf *)m; + + tm->m_toe.mt_arp_fail = (opaque_arp_failure_handler_func)hnd; + } /* @@ -145,9 +142,14 @@ static inline int l2t_send(struct t3cdev *dev, struct mbuf *m, struct l2t_entry *e) { - if (__predict_true(e->state == L2T_STATE_VALID)) - return cxgb_ofld_send(dev, m); - return t3_l2t_send_slow(dev, m, e); + if (__predict_true(e->state == L2T_STATE_VALID)) { + printf ("l2t_entry state is valid\n"); + + return cxgb_ofld_send(dev, (struct mbuf *)m); + } + printf("send slow\n"); + + return t3_l2t_send_slow(dev, (struct mbuf *)m, e); } static inline void l2t_release(struct l2t_data *d, struct l2t_entry *e) ==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_main.c#3 (text+ko) ==== @@ -120,10 +120,7 @@ static int cxgb_get_regs_len(void); static int offload_open(struct port_info *pi); static void touch_bars(device_t dev); - -#ifdef notyet static int offload_close(struct t3cdev *tdev); -#endif static device_method_t cxgb_controller_methods[] = { DEVMETHOD(device_probe, cxgb_controller_probe), @@ -694,14 +691,14 @@ bus_generic_detach(sc->dev); if (sc->tq != NULL) taskqueue_free(sc->tq); -#ifdef notyet if (is_offload(sc)) { cxgb_adapter_unofld(sc); if (isset(&sc->open_device_map, OFFLOAD_DEVMAP_BIT)) offload_close(&sc->tdev); - } -#endif - + else + printf("cxgb_free: DEVMAP_BIT not set\n"); + } else + printf("not offloading set\n"); #ifndef IFNET_MULTIQUEUE t3_free_sge_resources(sc); #endif @@ -1039,7 +1036,7 @@ ether_ifdetach(p->ifp); printf("waiting for callout to stop ..."); - DELAY(100000); + DELAY(1000000); printf("done\n"); /* * the lock may be acquired in ifdetach @@ -1289,9 +1286,7 @@ { int ret; - critical_enter(); ret = t3_offload_tx(tdev, m); - critical_exit(); return (ret); } @@ -1306,6 +1301,8 @@ return (ENOMEM); req = mtod(m, struct cpl_smt_write_req *); + m->m_pkthdr.len = m->m_len = sizeof(struct cpl_smt_write_req); + req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, idx)); req->mtu_idx = NMTUS - 1; /* should be 0 but there's a T3 bug */ @@ -1592,6 +1589,8 @@ cxgb_teardown_msix(sc); ADAPTER_UNLOCK(sc); + callout_stop(&sc->cxgb_tick_ch); + callout_stop(&sc->sge_timer_ch); callout_drain(&sc->cxgb_tick_ch); callout_drain(&sc->sge_timer_ch); @@ -1606,15 +1605,22 @@ offload_open(struct port_info *pi) { struct adapter *adapter = pi->adapter; - struct t3cdev *tdev = T3CDEV(pi->ifp); + struct t3cdev *tdev = &adapter->tdev; +#ifdef notyet + T3CDEV(pi->ifp); +#endif int adap_up = adapter->open_device_map & PORT_MASK; int err = 0; + printf("device_map=0x%x\n", adapter->open_device_map); if (atomic_cmpset_int(&adapter->open_device_map, - (adapter->open_device_map & ~OFFLOAD_DEVMAP_BIT), - (adapter->open_device_map | OFFLOAD_DEVMAP_BIT)) == 0) + (adapter->open_device_map & ~(1<<OFFLOAD_DEVMAP_BIT)), + (adapter->open_device_map | (1<<OFFLOAD_DEVMAP_BIT))) == 0) return (0); + + if (!isset(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT)) + printf("offload_open: DEVMAP_BIT did not get set 0x%x\n", adapter->open_device_map); ADAPTER_LOCK(pi->adapter); if (!adap_up) err = cxgb_up(adapter); @@ -1623,7 +1629,7 @@ return (err); t3_tp_set_offload_mode(adapter, 1); - tdev->lldev = adapter->port[0].ifp; + tdev->lldev = pi->ifp; err = cxgb_offload_activate(adapter); if (err) goto out; @@ -1647,15 +1653,18 @@ } return (err); } -#ifdef notyet + static int offload_close(struct t3cdev *tdev) { struct adapter *adapter = tdev2adap(tdev); - if (!isset(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT)) + if (!isset(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT)) { + printf("offload_close: DEVMAP_BIT not set\n"); + return (0); - + } + /* Call back all registered clients */ cxgb_remove_clients(tdev); tdev->lldev = NULL; @@ -1663,13 +1672,15 @@ t3_tp_set_offload_mode(adapter, 0); clrbit(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT); + ADAPTER_LOCK(adapter); if (!adapter->open_device_map) - cxgb_down(adapter); - + cxgb_down_locked(adapter); + else + ADAPTER_UNLOCK(adapter); cxgb_offload_deactivate(adapter); return (0); } -#endif + static void cxgb_init(void *arg) @@ -1709,6 +1720,8 @@ if (err) log(LOG_WARNING, "Could not initialize offload capabilities\n"); + else + printf("offload opened\n"); } cxgb_link_start(p); t3_link_changed(sc, p->port_id); @@ -1752,7 +1765,6 @@ ADAPTER_LOCK(p->adapter); clrbit(&p->adapter->open_device_map, p->port_id); - if (p->adapter->open_device_map == 0) { cxgb_down_locked(p->adapter); } else @@ -1941,7 +1953,7 @@ struct sge_qset *qs; struct sge_txq *txq; struct port_info *p = ifp->if_softc; - int err, qsidx = 0; + int err; if (!p->link_config.link_ok) return (ENXIO); @@ -1950,10 +1962,7 @@ return (ENOBUFS); } - if (p->adapter->params.nports <= 2) - qsidx = p->first_qset; - - qs = &p->adapter->sge.qs[qsidx]; + qs = &p->adapter->sge.qs[p->first_qset]; txq = &qs->txq[TXQ_ETH]; err = 0; ==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_multiq.c#3 (text+ko) ==== @@ -489,7 +489,7 @@ qs = &pi->adapter->sge.qs[qidx]; } else qs = &pi->adapter->sge.qs[pi->first_qset]; - + txq = &qs->txq[TXQ_ETH]; if (((sc->tunq_coalesce == 0) || (buf_ring_count(&txq->txq_mr) > TX_WR_COUNT_MAX)) && mtx_trylock(&txq->lock)) { @@ -638,9 +638,6 @@ int qidx; uint32_t tmp; - /* - * Will probably need to be changed for 4-port XXX - */ tmp = pi->tx_chan ? cookie : cookie & ((RSS_TABLE_SIZE>>1)-1); DPRINTF(" tmp=%d ", tmp); qidx = (tmp & (pi->nqsets -1)) + pi->first_qset; @@ -681,6 +678,7 @@ for (i = 0; i < sc->params.nports; i++) { struct port_info *pi = &sc->port[i]; int first = pi->first_qset; + for (j = 0; j < pi->nqsets; j++) { struct sge_qset *qs = &sc->sge.qs[first + j]; ==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_offload.c#3 (text+ko) ==== @@ -108,9 +108,14 @@ TAILQ_INSERT_TAIL(&client_list, client, client_entry); if (client->add) { - TAILQ_FOREACH(tdev, &ofld_dev_list, ofld_entry) { + printf("client->add set\n"); + + TAILQ_FOREACH(tdev, &ofld_dev_list, entry) { if (offload_activated(tdev)) client->add(tdev); + else + printf("%p not activated\n", tdev); + } } mtx_unlock(&cxgb_db_lock); @@ -132,7 +137,7 @@ TAILQ_REMOVE(&client_list, client, client_entry); if (client->remove) { - TAILQ_FOREACH(tdev, &ofld_dev_list, ofld_entry) { + TAILQ_FOREACH(tdev, &ofld_dev_list, entry) { if (offload_activated(tdev)) client->remove(tdev); } @@ -480,7 +485,7 @@ cxgb_set_dummy_ops(struct t3cdev *dev) { dev->recv = rx_offload_blackhole; - dev->neigh_update = dummy_neigh_update; + dev->arp_update = dummy_neigh_update; } /* @@ -539,6 +544,7 @@ m_set_priority(m, CPL_PRIORITY_SETUP); req = mtod(m, struct cpl_tid_release *); + m->m_pkthdr.len = m->m_len = sizeof(*req); req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, tid)); } @@ -818,6 +824,8 @@ } } + + static int do_set_tcb_rpl(struct t3cdev *dev, struct mbuf *m) { @@ -865,225 +873,57 @@ return (0); } -#if defined(FOO) -#include <linux/config.h> -#include <linux/kallsyms.h> -#include <linux/kprobes.h> -#include <net/arp.h> - -static int (*orig_arp_constructor)(struct ifnet *); - static void -neigh_suspect(struct ifnet *neigh) +cxgb_route_event(void *unused, int event, struct rtentry *rt0, struct rtentry *rt1) { - struct hh_cache *hh; + struct toedev *tdev0, *tdev1 = NULL; - neigh->output = neigh->ops->output; - - for (hh = neigh->hh; hh; hh = hh->hh_next) - hh->hh_output = neigh->ops->output; -} - -static void -neigh_connect(struct ifnet *neigh) -{ - struct hh_cache *hh; - - neigh->output = neigh->ops->connected_output; - - for (hh = neigh->hh; hh; hh = hh->hh_next) - hh->hh_output = neigh->ops->hh_output; -} - -static inline int -neigh_max_probes(const struct neighbour *n) -{ - const struct neigh_parms *p = n->parms; - return (n->nud_state & NUD_PROBE ? - p->ucast_probes : - p->ucast_probes + p->app_probes + p->mcast_probes); -} - -static void -neigh_timer_handler_offload(unsigned long arg) -{ - unsigned long now, next; - struct neighbour *neigh = (struct neighbour *)arg; - unsigned state; - int notify = 0; - - write_lock(&neigh->lock); - - state = neigh->nud_state; - now = jiffies; - next = now + HZ; - - if (!(state & NUD_IN_TIMER)) { -#ifndef CONFIG_SMP - log(LOG_WARNING, "neigh: timer & !nud_in_timer\n"); -#endif - goto out; + /* + * ignore events on non-offloaded interfaces + */ + + tdev0 = TOEDEV(rt0->rt_ifp); + if (rt1) + tdev1 = TOEDEV(rt1->rt_ifp); + if (tdev0 == NULL && tdev1 == NULL) + return; + /* + * avoid LORs by dropping the route lock but keeping a reference + * + */ + RT_ADDREF(rt0); + RT_UNLOCK(rt0); + if (rt1) { + RT_ADDREF(rt1); + RT_UNLOCK(rt1); } - if (state & NUD_REACHABLE) { - if (time_before_eq(now, - neigh->confirmed + - neigh->parms->reachable_time)) { - next = neigh->confirmed + neigh->parms->reachable_time; - } else if (time_before_eq(now, - neigh->used + - neigh->parms->delay_probe_time)) { - neigh->nud_state = NUD_DELAY; - neigh->updated = jiffies; - neigh_suspect(neigh); - next = now + neigh->parms->delay_probe_time; - } else { - neigh->nud_state = NUD_STALE; - neigh->updated = jiffies; - neigh_suspect(neigh); - cxgb_neigh_update(neigh); + switch (event) { + case RTEVENT_ARP_UPDATE: { + cxgb_neigh_update(rt0); + break; } - } else if (state & NUD_DELAY) { - if (time_before_eq(now, - neigh->confirmed + - neigh->parms->delay_probe_time)) { - neigh->nud_state = NUD_REACHABLE; - neigh->updated = jiffies; - neigh_connect(neigh); - cxgb_neigh_update(neigh); - next = neigh->confirmed + neigh->parms->reachable_time; - } else { - neigh->nud_state = NUD_PROBE; - neigh->updated = jiffies; - atomic_set_int(&neigh->probes, 0); - next = now + neigh->parms->retrans_time; + case RTEVENT_REDIRECT_UPDATE: { + cxgb_redirect(rt0, rt1); + cxgb_neigh_update(rt1); + + break; } - } else { - /* NUD_PROBE|NUD_INCOMPLETE */ - next = now + neigh->parms->retrans_time; + case RTEVENT_PMTU_UPDATE: + default: + break; } - /* - * Needed for read of probes - */ - mb(); - if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && - neigh->probes >= neigh_max_probes(neigh)) { - struct mbuf *m; - neigh->nud_state = NUD_FAILED; - neigh->updated = jiffies; - notify = 1; - cxgb_neigh_update(neigh); - NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed); - - /* It is very thin place. report_unreachable is very - complicated routine. Particularly, it can hit the same - neighbour entry! - So that, we try to be accurate and avoid dead loop. --ANK - */ - while (neigh->nud_state == NUD_FAILED && - (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { - write_unlock(&neigh->lock); - neigh->ops->error_report(neigh, skb); - write_lock(&neigh->lock); - } - skb_queue_purge(&neigh->arp_queue); + RT_LOCK(rt0); + RT_REMREF(rt0); + if (rt1) { + RT_LOCK(rt1); + RT_REMREF(rt1); } - - if (neigh->nud_state & NUD_IN_TIMER) { - if (time_before(next, jiffies + HZ/2)) - next = jiffies + HZ/2; - if (!mod_timer(&neigh->timer, next)) - neigh_hold(neigh); - } - if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { - struct mbuf *m = skb_peek(&neigh->arp_queue); >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200711020131.lA21VqYU049492>