Date: Sat, 2 Feb 2008 05:34:28 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 134631 for review Message-ID: <200802020534.m125YSpr066640@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=134631 Change 134631 by kmacy@kmacy:storage:toehead on 2008/02/02 05:33:56 remove most tracing fix ddp buffer calculations dramatically reduce debug noise add DDP_BF_DATA handling Affected files ... .. //depot/projects/toehead/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#13 edit .. //depot/projects/toehead/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c#14 edit .. //depot/projects/toehead/sys/dev/cxgb/ulp/tom/cxgb_ddp.c#6 edit .. //depot/projects/toehead/sys/dev/cxgb/ulp/tom/cxgb_t3_ddp.h#9 edit .. //depot/projects/toehead/sys/dev/cxgb/ulp/tom/cxgb_tom.c#4 edit Differences ... ==== //depot/projects/toehead/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#13 (text+ko) ==== @@ -1616,7 +1616,6 @@ uint64_t t; __be64 *tcb; - TRACE_ENTER; /* Note that we only accout for CPL_GET_TCB issued by the DDP code. We * really need a cookie in order to dispatch the RPLs. */ @@ -1633,7 +1632,6 @@ m_freem(m); if (__predict_true((so->so_state & SS_NOFDREF) == 0)) sorwakeup(so); - TRACE_EXIT; return; } @@ -1692,7 +1690,6 @@ if (__predict_false(so_no_receive(so) && m->m_pkthdr.len)) { handle_excess_rx(toep, m); - TRACE_EXIT; return; } @@ -1712,7 +1709,7 @@ } #endif m->m_ddp_flags = DDP_BF_PSH | DDP_BF_NOCOPY | 1; - bsp->flags &= ~DDP_BF_NOCOPY; + bsp->flags &= ~(DDP_BF_NOCOPY|DDP_BF_NODATA); q->cur_buf ^= 1; } else if (bsp->flags & DDP_BF_NOFLIP) { @@ -1728,11 +1725,11 @@ * and we need to decrement the posted count. */ if (m->m_pkthdr.len == 0) { - if (ddp_offset == 0) + if (ddp_offset == 0) { q->kbuf_posted--; - panic("length not set"); + bsp->flags |= DDP_BF_NODATA; + } m_free(m); - TRACE_EXIT; return; } } else { @@ -1740,7 +1737,6 @@ * but it got here way late and nobody cares anymore. */ m_free(m); - TRACE_EXIT; return; } @@ -1762,7 +1758,6 @@ sbappend(&so->so_rcv, m); if (__predict_true((so->so_state & SS_NOFDREF) == 0)) sorwakeup(so); - TRACE_EXIT; } /* @@ -1775,9 +1770,10 @@ struct toepcb *toep = (struct toepcb *)ctx; /* OK if socket doesn't exist */ - if (toep == NULL) + if (toep == NULL) { + printf("null toep in do_get_tcb_rpl\n"); return (CPL_RET_BUF_DONE); - + } tcb_rpl_as_ddp_complete(toep, m); return (0); @@ -1950,7 +1946,8 @@ struct cpl_rx_data_ddp *hdr; unsigned int ddp_len, rcv_nxt, ddp_report, end_offset, buf_idx; struct socket *so = toeptoso(toep); - + int nomoredata = 0; + if (__predict_false(so_no_receive(so))) { struct inpcb *inp = sotoinpcb(so); @@ -1960,7 +1957,6 @@ return; } - TRACE_ENTER; tp = sototcpcb(so); q = &toep->tp_ddp_state; hdr = cplhdr(m); @@ -1994,6 +1990,13 @@ * interprets ->len of this packet the usual way. */ m->m_len = m->m_pkthdr.len = tp->rcv_nxt - m->m_seq; + /* + * Length is only meaningful for kbuf + */ + if (!(bsp->flags & DDP_BF_NOCOPY)) + KASSERT(m->m_len <= bsp->gl->dgl_length, + ("length received exceeds ddp pages: len=%d dgl_length=%d", + m->m_len, bsp->gl->dgl_length)); /* * Figure out where the new data was placed in the buffer and store it @@ -2014,7 +2017,7 @@ panic("spurious ddp completion"); } else { m->m_ddp_flags = !!(ddp_report & F_DDP_BUF_COMPLETE); - if (m->m_ddp_flags && !(bsp->flags & DDP_BF_NOFLIP)) + if (m->m_ddp_flags && !(bsp->flags & DDP_BF_NOFLIP)) q->cur_buf ^= 1; /* flip buffers */ } @@ -2025,11 +2028,11 @@ if (ddp_report & F_DDP_PSH) m->m_ddp_flags |= DDP_BF_PSH; - + if (nomoredata) + m->m_ddp_flags |= DDP_BF_NODATA; + tp->t_rcvtime = ticks; - printf("ddp set and ddp_flags=0x%x len=%d m_seq=0x%x rcv_nxt=0x%x\n", m->m_ddp_flags, m->m_len, m->m_seq, rcv_nxt); - SOCKBUF_LOCK(&so->so_rcv); sbappendstream_locked(&so->so_rcv, m); @@ -2037,7 +2040,6 @@ sorwakeup_locked(so); else SOCKBUF_UNLOCK(&so->so_rcv); - TRACE_EXIT; } #define DDP_ERR (F_DDP_PPOD_MISMATCH | F_DDP_LLIMIT_ERR | F_DDP_ULIMIT_ERR |\ @@ -2077,6 +2079,7 @@ struct ddp_buf_state *bsp; struct cpl_rx_ddp_complete *hdr; unsigned int ddp_report, buf_idx, when; + int nomoredata = 0; if (__predict_false(so_no_receive(so))) { struct inpcb *inp = sotoinpcb(so); @@ -2094,7 +2097,7 @@ bsp = &q->buf_state[buf_idx]; when = bsp->cur_offset; - m->m_pkthdr.len = G_DDP_OFFSET(ddp_report) - when; + m->m_len = m->m_pkthdr.len = G_DDP_OFFSET(ddp_report) - when; #ifdef T3_TRACE T3_TRACE5(TIDTB(sk), @@ -2106,9 +2109,12 @@ bsp->cur_offset += m->m_len; - if (!(bsp->flags & DDP_BF_NOFLIP)) + if (!(bsp->flags & DDP_BF_NOFLIP)) { q->cur_buf ^= 1; /* flip buffers */ - + if (G_DDP_OFFSET(ddp_report) < q->kbuf[0]->dgl_length) + nomoredata=1; + } + #ifdef T3_TRACE T3_TRACE4(TIDTB(sk), "process_ddp_complete: tp->rcv_nxt 0x%x cur_offset %u " @@ -2118,9 +2124,12 @@ #endif m->m_ddp_gl = (unsigned char *)bsp->gl; m->m_flags |= M_DDP; - m->m_pkthdr.csum_flags = (bsp->flags & DDP_BF_NOCOPY) | 1; + m->m_ddp_flags = (bsp->flags & DDP_BF_NOCOPY) | 1; if (bsp->flags & DDP_BF_NOCOPY) bsp->flags &= ~DDP_BF_NOCOPY; + if (nomoredata) + m->m_ddp_flags |= DDP_BF_NODATA; + m->m_pkthdr.csum_data = tp->rcv_nxt; tp->rcv_nxt += m->m_len; @@ -2209,7 +2218,7 @@ q = &toep->tp_ddp_state; bsp = &q->buf_state[q->cur_buf]; - m->m_pkthdr.len = rcv_nxt - tp->rcv_nxt; + m->m_len = m->m_pkthdr.len = rcv_nxt - tp->rcv_nxt; m->m_ddp_gl = (unsigned char *)bsp->gl; m->m_flags |= M_DDP; m->m_cur_offset = bsp->cur_offset; @@ -3946,7 +3955,6 @@ struct cpl_set_tcb_field *req; struct ddp_state *p = &toep->tp_ddp_state; - TRACE_ENTER; wrlen = sizeof(*wr) + 3 * sizeof(*req) + sizeof(*getreq); m = m_gethdr_nofail(wrlen); m_set_priority(m, mkprio(CPL_PRIORITY_CONTROL, toep)); @@ -4001,7 +4009,6 @@ bufidx, tag0, tag1, len); #endif cxgb_ofld_send(TOEP_T3C_DEV(toep), m); - TRACE_EXIT; } /* ==== //depot/projects/toehead/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c#14 (text+ko) ==== @@ -256,7 +256,7 @@ so_should_ddp(const struct toepcb *toep, int last_recv_len) { - printf("ulp_mode=%d last_recv_len=%d ddp_thresh=%d rcv_wnd=%ld ddp_copy_limit=%d\n", + DPRINTF("ulp_mode=%d last_recv_len=%d ddp_thresh=%d rcv_wnd=%ld ddp_copy_limit=%d\n", toep->tp_ulp_mode, last_recv_len, TOM_TUNABLE(toep->tp_toedev, ddp_thres), toep->tp_tp->rcv_wnd, (TOM_TUNABLE(toep->tp_toedev, ddp_copy_limit) + DDP_RSVD_WIN)); @@ -330,17 +330,13 @@ if (__predict_true(!is_ddp(m))) { /* RX_DATA */ return m_uiomove(m, offset, len, uio); } if (__predict_true(m->m_ddp_flags & DDP_BF_NOCOPY)) { /* user DDP */ - TRACE_ENTER; to->iov_len -= len; to->iov_base = ((caddr_t)to->iov_base) + len; uio->uio_iov = to; uio->uio_resid -= len; - TRACE_EXIT; return (0); } - TRACE_ENTER; err = t3_ddp_copy(m, offset, uio, len); /* kernel DDP */ - TRACE_EXIT; return (err); } @@ -607,7 +603,7 @@ uio->uio_iov->iov_len > p->kbuf[0]->dgl_length && p->ubuf_ddp_ready) { user_ddp_pending = - !t3_overlay_ubuf(so, uio, 1, 1); + !t3_overlay_ubuf(so, uio, IS_NONBLOCKING(so), flags, 1, 1); if (user_ddp_pending) { p->kbuf_posted++; user_ddp_ok = 0; @@ -635,7 +631,9 @@ INP_UNLOCK(inp); SOCKBUF_LOCK(&so->so_rcv); copied_unacked = 0; - printf("sbwaiting 2\n"); + if (so->so_rcv.sb_mb) + goto restart; + printf("sbwaiting 2 copied=%d target=%d\n", copied, target); if ((err = sbwait(&so->so_rcv)) != 0) goto done; } @@ -650,8 +648,8 @@ goto done; } offset = toep->tp_copied_seq + copied_unacked - m->m_seq; - printf("m=%p copied_seq=0x%x copied_unacked=%d m_seq=0x%x offset=%d pktlen=%d is_ddp(m)=%d\n", - m, toep->tp_copied_seq, copied_unacked, m->m_seq, offset, m->m_pkthdr.len, is_ddp(m)); + DPRINTF("m=%p copied_seq=0x%x copied_unacked=%d m_seq=0x%x offset=%d pktlen=%d is_ddp(m)=%d\n", + m, toep->tp_copied_seq, copied_unacked, m->m_seq, offset, m->m_pkthdr.len, !!is_ddp(m)); if (offset >= m->m_pkthdr.len) panic("t3_soreceive: OFFSET >= LEN offset %d copied_seq 0x%x seq 0x%x " "pktlen %d ddp flags 0x%x", offset, toep->tp_copied_seq + copied_unacked, m->m_seq, @@ -697,14 +695,14 @@ uio->uio_iov->iov_len > p->kbuf[0]->dgl_length && p->ubuf_ddp_ready) { user_ddp_pending = - !t3_overlay_ubuf(so, uio, 1, 1); + !t3_overlay_ubuf(so, uio, IS_NONBLOCKING(so), flags, 1, 1); if (user_ddp_pending) { p->kbuf_posted++; user_ddp_ok = 0; } - printf("user_ddp_pending=%d\n", user_ddp_pending); + DPRINTF("user_ddp_pending=%d\n", user_ddp_pending); } else - printf("user_ddp_ok=%d user_ddp_pending=%d iov_len=%ld dgl_length=%d ubuf_ddp_ready=%d ulp_mode=%d is_ddp(m)=%d flags=0x%x ubuf=%p kbuf_posted=%d\n", + DPRINTF("user_ddp_ok=%d user_ddp_pending=%d iov_len=%ld dgl_length=%d ubuf_ddp_ready=%d ulp_mode=%d is_ddp(m)=%d flags=0x%x ubuf=%p kbuf_posted=%d\n", user_ddp_ok, user_ddp_pending, uio->uio_iov->iov_len, p->kbuf[0] ? p->kbuf[0]->dgl_length : 0, p->ubuf_ddp_ready, toep->tp_ulp_mode, !!is_ddp(m), m->m_ddp_flags, p->ubuf, p->kbuf_posted); @@ -714,6 +712,7 @@ */ if (__predict_true(!(flags & MSG_TRUNC))) { int resid = uio->uio_resid; + SOCKBUF_UNLOCK(&so->so_rcv); if ((err = copy_data(m, offset, avail, uio))) { if (err) @@ -742,7 +741,7 @@ */ if (avail + offset >= m->m_pkthdr.len) { unsigned int fl = m->m_ddp_flags; - int got_psh = 0; + int exitnow, got_psh = 0, nomoredata = 0; if (p->kbuf[0] != NULL && is_ddp(m) && (fl & 1)) { if (is_ddp_psh(m) && user_ddp_pending) @@ -750,14 +749,17 @@ if (fl & DDP_BF_NOCOPY) user_ddp_pending = 0; - else { + else if ((fl & DDP_BF_NODATA) && IS_NONBLOCKING(so)) { + p->kbuf_posted--; + nomoredata = 1; + } else { p->kbuf_posted--; p->ubuf_ddp_ready = 1; - printf("ubuf ddp ready\n"); } } - if ((so->so_rcv.sb_mb == NULL) && got_psh) + exitnow = got_psh || nomoredata; + if ((so->so_rcv.sb_mb == NULL) && exitnow) goto done; } if (len > 0) @@ -771,6 +773,8 @@ * transitioned to CLOSE but not if it was in that state to begin with. */ if (__predict_true((so->so_state & (SS_ISDISCONNECTING|SS_ISDISCONNECTED)) == 0)) { + SOCKBUF_UNLOCK(&so->so_rcv); + SOCKBUF_LOCK(&so->so_rcv); if (user_ddp_pending) { user_ddp_ok = 0; t3_cancel_ubuf(toep); @@ -787,14 +791,10 @@ "chelsio_recvmsg: about to exit, repost kbuf"); #endif - printf("posting kbuf\n"); t3_post_kbuf(so, 1); p->kbuf_posted++; } else if (so_should_ddp(toep, copied) -#ifdef notyet - && !IS_NONBLOCKING(so) -#endif - ) { + && !IS_NONBLOCKING(so)) { printf("entering ddp\n"); t3_enter_ddp(so, TOM_TUNABLE(TOE_DEV(so), ddp_copy_limit), 0); ==== //depot/projects/toehead/sys/dev/cxgb/ulp/tom/cxgb_ddp.c#6 (text+ko) ==== @@ -116,11 +116,11 @@ * a new gather list was allocated it is returned in @newgl. */ static int -t3_pin_pages(bus_dma_tag_t tag, bus_dmamap_t map, unsigned long addr, +t3_pin_pages(bus_dma_tag_t tag, bus_dmamap_t map, vm_offset_t addr, size_t len, struct ddp_gather_list **newgl, const struct ddp_gather_list *gl) { - int i, err; + int i = 0, err; size_t pg_off; unsigned int npages; struct ddp_gather_list *p; @@ -131,7 +131,7 @@ if (addr + len > VM_MAXUSER_ADDRESS) return (EFAULT); - pg_off = addr & ~PAGE_MASK; + pg_off = addr & PAGE_MASK; npages = (pg_off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; p = malloc(sizeof(struct ddp_gather_list) + npages * sizeof(vm_page_t *), M_DEVBUF, M_NOWAIT); @@ -139,13 +139,12 @@ return (ENOMEM); err = vm_fault_hold_user_pages(addr, p->dgl_pages, npages, VM_HOLD_WRITEABLE); - printf("held pages\n"); if (err) goto free_gl; if (gl && gl->dgl_offset == pg_off && gl->dgl_nelem >= npages && gl->dgl_length >= len) { - for (i = 0; i < npages; ++i) + for (i = 0; i < npages; i++) if (p->dgl_pages[i] != gl->dgl_pages[i]) goto different_gl; err = 0; @@ -156,6 +155,8 @@ p->dgl_length = len; p->dgl_offset = pg_off; p->dgl_nelem = npages; + printf("hold %jx -> %jx --- count=%d i=%d\n", addr, addr + npages*PAGE_SIZE, npages, i); + #ifdef NEED_BUSDMA p->phys_addr[0] = pci_map_page(pdev, p->pages[0], pg_off, PAGE_SIZE - pg_off, @@ -165,14 +166,15 @@ PCI_DMA_FROMDEVICE); #endif *newgl = p; - return 0; + return (0); unpin: vm_fault_unhold_pages(p->dgl_pages, npages); free_gl: + free(p, M_DEVBUF); *newgl = NULL; - return err; + return (err); } static void @@ -197,7 +199,7 @@ ddp_gl_free_pages(struct ddp_gather_list *gl, int dirty) { /* - * XXX need to be able to + * XXX mark pages as dirty before unholding */ vm_fault_unhold_pages(gl->dgl_pages, gl->dgl_nelem); } @@ -227,7 +229,7 @@ int err, tag, npages, nppods; struct tom_data *d = TOM_DATA(TOE_DEV(so)); - npages = ((addr & ~PAGE_MASK) + len + PAGE_SIZE - 1) >> PAGE_SHIFT; + npages = ((addr & PAGE_MASK) + len + PAGE_SIZE - 1) >> PAGE_SHIFT; nppods = min(pages2ppods(npages), MAX_PPODS); nppods = roundup2(nppods, PPOD_CLUSTER_SIZE); err = t3_alloc_ppods(d, nppods, &tag); @@ -256,11 +258,10 @@ */ static void t3_repost_kbuf(struct socket *so, unsigned int bufidx, int modulate, - int activate) + int activate, int nonblock) { struct toepcb *toep = sototcpcb(so)->t_toe; struct ddp_state *p = &toep->tp_ddp_state; - TRACE_ENTER; p->buf_state[bufidx].cur_offset = p->kbuf[bufidx]->dgl_offset; p->buf_state[bufidx].flags = p->kbuf_noinval ? DDP_BF_NOINVAL : 0; @@ -283,7 +284,6 @@ V_TF_DDP_BUF1_VALID(1) | V_TF_DDP_ACTIVE_BUF(1), modulate); - TRACE_EXIT; } /* @@ -294,7 +294,7 @@ static __inline unsigned long select_ddp_flags(const struct socket *so, int buf_idx, - int nonblock, int rcv_flags) + int nonblock, int rcv_flags) { if (buf_idx == 1) { if (__predict_false(rcv_flags & MSG_WAITALL)) @@ -338,24 +338,26 @@ struct toepcb *toep = sototcpcb(so)->t_toe; struct ddp_state *p = &toep->tp_ddp_state; struct iovec *iov = uio->uio_iov; - unsigned long addr = (unsigned long)iov->iov_base - oft; + vm_offset_t addr = (vm_offset_t)iov->iov_base - oft; - if (__predict_false(!p->ubuf_nppods)) { + if (__predict_false(p->ubuf_nppods == 0)) { err = alloc_buf1_ppods(so, p, addr, iov->iov_len + oft); if (err) return (err); } len = (p->ubuf_nppods - NUM_SENTINEL_PPODS) * PPOD_PAGES * PAGE_SIZE; - len -= addr & ~PAGE_MASK; + len -= addr & PAGE_MASK; if (len > M_TCB_RX_DDP_BUF0_LEN) len = M_TCB_RX_DDP_BUF0_LEN; len = min(len, sototcpcb(so)->rcv_wnd - 32768); len = min(len, iov->iov_len + oft); - if (len <= p->kbuf[0]->dgl_length) + if (len <= p->kbuf[0]->dgl_length) { + printf("length too short\n"); return (EINVAL); - + } + err = t3_pin_pages(toep->tp_rx_dmat, toep->tp_dmamap, addr, len, &gl, p->ubuf); if (err) return (err); @@ -377,7 +379,6 @@ t3_cancel_ubuf(struct toepcb *toep) { struct ddp_state *p = &toep->tp_ddp_state; - long timeo = MAX_SCHEDULE_TIMEOUT; int ubuf_pending = t3_ddp_ubuf_pending(toep); struct socket *so = toeptoso(toep); @@ -393,12 +394,24 @@ p->buf_state[1].flags & (DDP_BF_NOFLIP | DDP_BF_NOCOPY), p->get_tcb_count); #endif - if (!p->get_tcb_count) + if (p->get_tcb_count == 0) t3_cancel_ddpbuf(toep, p->cur_buf); - do { + else { + int err = 0, timeo, flags, count=0; + timeo = so->so_rcv.sb_timeo; + flags = so->so_rcv.sb_flags; - cv_timedwait(&toep->tp_cv, &toep->tp_tp->t_inpcb->inp_mtx, timeo); - } while (p->get_tcb_count && !(so->so_state & (SS_ISDISCONNECTING|SS_ISDISCONNECTED))); + so->so_rcv.sb_timeo = 3*hz; + while (p->get_tcb_count && !(so->so_state & (SS_ISDISCONNECTING|SS_ISDISCONNECTED))) { + if (count & 0xff) + printf("waiting err=%d get_tcb_count=%d timeo=%d so=%p\n", + err, p->get_tcb_count, so->so_rcv.sb_timeo, so); + count++; + err = sbwait(&so->so_rcv); + } + so->so_rcv.sb_timeo = timeo; + so->so_rcv.sb_flags = flags; + } ubuf_pending = t3_ddp_ubuf_pending(toep); } @@ -417,24 +430,19 @@ */ int t3_overlay_ubuf(struct socket *so, const struct uio *uio, - int nonblock, int rcv_flags) + int nonblock, int rcv_flags, int modulate, int post_kbuf) { int err, len, ubuf_idx; unsigned long flags; struct toepcb *toep = sototcpcb(so)->t_toe; struct ddp_state *p = &toep->tp_ddp_state; - struct ddp_buf_state *dbs; - - TRACE_ENTER; if (p->kbuf[0] == NULL) { - TRACE_EXIT; return (EINVAL); } err = setup_uio_ppods(so, uio, 0, &len); if (err) { - TRACE_EXIT; return (err); } @@ -446,16 +454,18 @@ flags = select_ddp_flags(so, ubuf_idx, nonblock, rcv_flags); - dbs = &p->buf_state[ubuf_idx ^ 1]; - - dbs->cur_offset = 0; - dbs->flags = 0; - dbs->gl = p->kbuf[ubuf_idx ^ 1]; - p->kbuf_idx ^= 1; - flags |= p->kbuf_idx ? - V_TF_DDP_BUF1_VALID(1) | V_TF_DDP_PUSH_DISABLE_1(0) : - V_TF_DDP_BUF0_VALID(1) | V_TF_DDP_PUSH_DISABLE_0(0); - + if (post_kbuf) { + struct ddp_buf_state *dbs = &p->buf_state[ubuf_idx ^ 1]; + + dbs->cur_offset = 0; + dbs->flags = 0; + dbs->gl = p->kbuf[ubuf_idx ^ 1]; + p->kbuf_idx ^= 1; + flags |= p->kbuf_idx ? + V_TF_DDP_BUF1_VALID(1) | V_TF_DDP_PUSH_DISABLE_1(0) : + V_TF_DDP_BUF0_VALID(1) | V_TF_DDP_PUSH_DISABLE_0(0); + } + if (ubuf_idx == 0) { t3_overlay_ddpbuf(toep, 0, p->ubuf_tag << 6, p->kbuf_tag[1] << 6, len); @@ -475,7 +485,6 @@ " kbuf_idx %d", p->ubuf_tag, flags, OVERLAY_MASK, ubuf_idx, p->kbuf_idx); #endif - TRACE_EXIT; return (0); } @@ -540,7 +549,7 @@ TRACE_ENTER; t3_set_ddp_tag(so, p->cur_buf, p->kbuf_tag[p->cur_buf] << 6); t3_set_ddp_buf(so, p->cur_buf, 0, p->kbuf[p->cur_buf]->dgl_length); - t3_repost_kbuf(so, p->cur_buf, modulate, (so->so_state & SS_NBIO)); + t3_repost_kbuf(so, p->cur_buf, modulate, 1, (so->so_state & SS_NBIO)); TRACE_EXIT; #ifdef T3_TRACE T3_TRACE1(TIDTB(so), @@ -614,7 +623,7 @@ } t3_set_ddp_tag(so, 0, p->kbuf_tag[0] << 6); t3_set_ddp_buf(so, 0, 0, p->kbuf[0]->dgl_length); - t3_repost_kbuf(so, 0, 0, nonblock); + t3_repost_kbuf(so, 0, 0, 1, nonblock); t3_set_rcv_coalesce_enable(so, TOM_TUNABLE(TOE_DEV(so), ddp_rcvcoalesce)); @@ -639,20 +648,17 @@ int page_off, resid_init, err; struct ddp_gather_list *gl = (struct ddp_gather_list *)m->m_ddp_gl; - TRACE_ENTER; resid_init = uio->uio_resid; if (!gl->dgl_pages) panic("pages not set\n"); offset += gl->dgl_offset + m->m_cur_offset; - page_off = offset & ~PAGE_MASK; + page_off = offset & PAGE_MASK; + KASSERT(len <= gl->dgl_length, + ("len=%d > dgl_length=%d in ddp_copy\n", len, gl->dgl_length)); err = uiomove_fromphys(gl->dgl_pages, page_off, len, uio); - printf("err=%d resid_init=%d uio_resid=%d offset=%d len=%d\n", - err, resid_init, uio->uio_resid, offset, len); - - TRACE_EXIT; return (err); } ==== //depot/projects/toehead/sys/dev/cxgb/ulp/tom/cxgb_t3_ddp.h#9 (text+ko) ==== @@ -128,6 +128,7 @@ DDP_BF_PSH = 1 << 3, /* set in skb->flags if the a DDP was completed with a segment having the PSH flag set */ + DDP_BF_NODATA = 1 << 4, /* buffer completed before filling */ }; #include <dev/cxgb/ulp/tom/cxgb_toepcb.h> @@ -135,7 +136,8 @@ /* * Returns 1 if a UBUF DMA buffer might be active. */ -static inline int t3_ddp_ubuf_pending(struct toepcb *toep) +static inline int +t3_ddp_ubuf_pending(struct toepcb *toep) { struct ddp_state *p = &toep->tp_ddp_state; @@ -143,6 +145,9 @@ * but DDP_STATE() is only valid if the connection actually enabled * DDP. */ + if (p->kbuf[0] == NULL) + return (0); + return (p->buf_state[0].flags & (DDP_BF_NOFLIP | DDP_BF_NOCOPY)) || (p->buf_state[1].flags & (DDP_BF_NOFLIP | DDP_BF_NOCOPY)); } @@ -160,7 +165,7 @@ int rcv_flags, int modulate, int post_kbuf); void t3_cancel_ubuf(struct toepcb *toep); int t3_overlay_ubuf(struct socket *so, const struct uio *uio, int nonblock, - int rcv_flags); + int rcv_flags, int modulate, int post_kbuf); int t3_enter_ddp(struct socket *so, unsigned int kbuf_size, unsigned int waitall); void t3_cleanup_ddp(struct toepcb *toep); void t3_release_ddp_resources(struct toepcb *toep); ==== //depot/projects/toehead/sys/dev/cxgb/ulp/tom/cxgb_tom.c#4 (text+ko) ==== @@ -264,14 +264,18 @@ return; } +extern void kdb_backetrace(void); + /* * Process a received packet with an unknown/unexpected CPL opcode. */ static int do_bad_cpl(struct t3cdev *cdev, struct mbuf *m, void *ctx) { + kdb_backtrace(); + log(LOG_ERR, "%s: received bad CPL command %u\n", cdev->name, - *mtod(m, unsigned int *)); + 0xFF & *mtod(m, unsigned int *)); return (CPL_RET_BUF_DONE | CPL_RET_BAD_MSG); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802020534.m125YSpr066640>