]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / dev / cxgb / ulp / tom / cxgb_cpl_socket.c
1 /**************************************************************************
2
3 Copyright (c) 2007-2008, Chelsio Inc.
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8
9  1. Redistributions of source code must retain the above copyright notice,
10     this list of conditions and the following disclaimer.
11
12  2. Neither the name of the Chelsio Corporation nor the names of its
13     contributors may be used to endorse or promote products derived from
14     this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 POSSIBILITY OF SUCH DAMAGE.
27
28 ***************************************************************************/
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/types.h>
36 #include <sys/fcntl.h>
37 #include <sys/kernel.h>
38 #include <sys/limits.h>
39 #include <sys/lock.h>
40 #include <sys/mbuf.h>
41 #include <sys/condvar.h>
42 #include <sys/mutex.h>
43 #include <sys/proc.h>
44 #include <sys/smp.h>
45 #include <sys/sockstate.h>
46 #include <sys/sockopt.h>
47 #include <sys/socket.h>
48 #include <sys/sockbuf.h>
49 #include <sys/syslog.h>
50 #include <sys/uio.h>
51 #include <sys/file.h>
52
53 #include <machine/bus.h>
54 #include <machine/cpu.h>
55
56 #include <net/if.h>
57 #include <net/route.h>
58
59 #include <netinet/in.h>
60 #include <netinet/in_pcb.h>
61 #include <netinet/in_systm.h>
62 #include <netinet/in_var.h>
63
64 #include <cxgb_osdep.h>
65 #include <sys/mbufq.h>
66 #include <ulp/tom/cxgb_tcp_offload.h>
67 #include <netinet/tcp.h>
68 #include <netinet/tcp_var.h>
69 #include <netinet/tcp_fsm.h>
70 #include <netinet/tcp_offload.h>
71 #include <net/route.h>
72
73 #include <t3cdev.h>
74 #include <common/cxgb_firmware_exports.h>
75 #include <common/cxgb_t3_cpl.h>
76 #include <common/cxgb_tcb.h>
77 #include <common/cxgb_ctl_defs.h>
78 #include <cxgb_offload.h>
79
80 #include <vm/vm.h>
81 #include <vm/vm_page.h>
82 #include <vm/vm_map.h>
83 #include <vm/vm_extern.h>
84 #include <vm/pmap.h>
85
86 #include <sys/mvec.h>
87 #include <ulp/toecore/cxgb_toedev.h>
88 #include <ulp/tom/cxgb_defs.h>
89 #include <ulp/tom/cxgb_tom.h>
90 #include <ulp/tom/cxgb_t3_ddp.h>
91 #include <ulp/tom/cxgb_toepcb.h>
92 #include <ulp/tom/cxgb_tcp.h>
93 #include <ulp/tom/cxgb_vm.h>
94
95
96 static int      (*pru_sosend)(struct socket *so, struct sockaddr *addr,
97     struct uio *uio, struct mbuf *top, struct mbuf *control,
98     int flags, struct thread *td);
99
100 static int      (*pru_soreceive)(struct socket *so, struct sockaddr **paddr,
101     struct uio *uio, struct mbuf **mp0, struct mbuf **controlp,
102     int *flagsp);
103
104 #define TMP_IOV_MAX 16
105 #ifndef PG_FRAME
106 #define PG_FRAME        ~PAGE_MASK
107 #endif
108 #define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
109
110 void
111 t3_init_socket_ops(void)
112 {
113         struct protosw *prp;
114
115         prp = pffindtype(AF_INET, SOCK_STREAM);
116         pru_sosend = prp->pr_usrreqs->pru_sosend;
117         pru_soreceive = prp->pr_usrreqs->pru_soreceive;
118 }
119
120 struct cxgb_dma_info {
121         size_t                  cdi_mapped;
122         int                     cdi_nsegs;
123         bus_dma_segment_t       *cdi_segs;
124         
125 };
126
127 static void
128 cxgb_dma_callback(void *arg, bus_dma_segment_t *segs, int nsegs,
129     bus_size_t mapsize, int error)
130 {
131         struct cxgb_dma_info *cdi = arg;
132         
133         cdi->cdi_mapped = mapsize;
134         cdi->cdi_nsegs = nsegs;
135         cdi->cdi_segs = segs;
136 }
137
138 static void
139 iov_adj(struct iovec **iov, int *iovcnt, size_t count)
140 {
141         struct iovec *iovtmp;
142         int iovcnttmp;
143         caddr_t ptmp;
144         
145         if (count > 0) {
146                 iovtmp = *iov;
147                 iovcnttmp = *iovcnt;
148                 while (count > 0) {
149                         if (count < iovtmp->iov_len) {
150                                 ptmp = iovtmp->iov_base;
151                                 ptmp += count; 
152                                 iovtmp->iov_base = ptmp;
153                                 iovtmp->iov_len -= count;
154                                 break;
155                         } else 
156                                 count -= iovtmp->iov_len;
157                         iovtmp++;
158                         iovcnttmp--;
159                 } 
160                 *iov = iovtmp;
161                 *iovcnt = iovcnttmp;
162         } else if (count < 0) {
163                 iovtmp = &(*iov)[*iovcnt - 1];
164                 iovcnttmp = *iovcnt;
165                 while (count < 0) {
166                         if (-count < iovtmp->iov_len) {
167                                 iovtmp->iov_len += count;
168                                 break;
169                         } else
170                                 count += iovtmp->iov_len;
171                         iovtmp--;
172                         iovcnttmp--;
173                 }
174                 *iovcnt = iovcnttmp;
175         }
176 }
177
178 static void
179 cxgb_zero_copy_free(void *cl, void *arg)
180 {
181         struct mbuf_vec *mv;
182         struct mbuf *m = (struct mbuf *)cl;
183
184         mv = mtomv(m);
185         /*
186          * Physical addresses, don't try to free should be unheld separately from sbdrop
187          *
188          */
189         mv->mv_count = 0;
190         m_free_iovec(m, m->m_type);
191 }
192
193
194 static int
195 cxgb_hold_iovec_pages(struct uio *uio, vm_page_t *m, int *held, vm_prot_t prot)
196 {
197         struct iovec *iov = uio->uio_iov;
198         int iovcnt = uio->uio_iovcnt;
199         int err, i, count, totcount, maxcount, totbytes, npages, curbytes;
200         uint64_t start, end;
201         vm_page_t *mp;
202         vm_map_t map;
203
204         map = &uio->uio_td->td_proc->p_vmspace->vm_map;
205         totbytes = totcount = 0;
206         maxcount = *held;
207
208         mp = m;
209         for (totcount = i = 0; (i < iovcnt) && (totcount < maxcount);  i++, iov++) {
210                 count = maxcount - totcount;
211                     
212                 start = (uintptr_t)iov->iov_base;
213                 end = (uintptr_t)((caddr_t)iov->iov_base + iov->iov_len);
214                 start &= PG_FRAME;
215                 end += PAGE_MASK;
216                 end &= PG_FRAME;
217                 npages = (end - start) >> PAGE_SHIFT;
218                 
219                 count = min(count, npages);
220
221                 err = vm_fault_hold_user_pages(map,
222                         (vm_offset_t)iov->iov_base, mp, count, prot);
223                 mp += count;
224                 totcount += count;
225                 curbytes = iov->iov_len;
226                 if (count != npages)
227                         curbytes = count*PAGE_SIZE - (((uintptr_t)iov->iov_base)&PAGE_MASK);
228                 totbytes += curbytes;
229         }
230         uio->uio_resid -= totbytes;
231
232         return (0);
233 }
234
235 /*
236  * Returns whether a connection should enable DDP.  This happens when all of
237  * the following conditions are met:
238  * - the connection's ULP mode is DDP
239  * - DDP is not already enabled
240  * - the last receive was above the DDP threshold
241  * - receive buffers are in user space
242  * - receive side isn't shutdown (handled by caller)
243  * - the connection's receive window is big enough so that sizable buffers
244  *   can be posted without closing the window in the middle of DDP (checked
245  *   when the connection is offloaded)
246  */
247 static int
248 so_should_ddp(const struct toepcb *toep, int last_recv_len)
249 {
250
251         DPRINTF("ulp_mode=%d last_recv_len=%d ddp_thresh=%d rcv_wnd=%ld ddp_copy_limit=%d\n",
252             toep->tp_ulp_mode, last_recv_len,  TOM_TUNABLE(toep->tp_toedev, ddp_thres),
253             toep->tp_tp->rcv_wnd, (TOM_TUNABLE(toep->tp_toedev, ddp_copy_limit) + DDP_RSVD_WIN));
254
255         return toep->tp_ulp_mode == ULP_MODE_TCPDDP && (toep->tp_ddp_state.kbuf[0] == NULL) &&
256                last_recv_len > TOM_TUNABLE(toep->tp_toedev, ddp_thres) &&
257                toep->tp_tp->rcv_wnd > 
258                    (TOM_TUNABLE(toep->tp_toedev, ddp_copy_limit) + DDP_RSVD_WIN);
259 }
260
261 static inline int
262 is_ddp(const struct mbuf *m)
263 {
264         return ((m->m_flags & M_DDP) != 0);
265 }
266
267 static inline int
268 is_ddp_psh(const struct mbuf *m)
269 {
270         return ((is_ddp(m) && (m->m_pkthdr.csum_flags & DDP_BF_PSH)) != 0);
271 }
272
273 static int
274 m_uiomove(const struct mbuf *m, int offset, int len, struct uio *uio)
275 {
276         int curlen, startlen, resid_init, err = 0;
277         caddr_t buf;
278
279         DPRINTF("m_uiomove(m=%p, offset=%d, len=%d, ...)\n",
280             m, offset, len);
281
282         startlen = len;
283         resid_init = uio->uio_resid;
284         while (m && len) {
285                 buf = mtod(m, caddr_t);
286                 curlen = m->m_len;
287                 if (offset && (offset < curlen)) {
288                         curlen -= offset;
289                         buf += offset;
290                         offset = 0;
291                 } else if (offset) {
292                         offset -= curlen;
293                         m = m->m_next;
294                         continue;
295                 }
296                 err = uiomove(buf, min(len, curlen), uio);
297                 if (err) {
298                         printf("uiomove returned %d\n", err);
299                         return (err);
300                 }
301                 
302                 len -= min(len, curlen);
303                 m = m->m_next;
304         }
305         DPRINTF("copied %d bytes - resid_init=%d uio_resid=%d\n",
306             startlen - len, resid_init, uio->uio_resid);
307         return (err);
308 }
309
310 /*
311  * Copy data from an sk_buff to an iovec.  Deals with RX_DATA, which carry the
312  * data in the sk_buff body, and with RX_DATA_DDP, which place the data in a
313  * DDP buffer.
314  */
315 static inline int
316 copy_data(const struct mbuf *m, int offset, int len, struct uio *uio)
317 {
318         struct iovec *to = uio->uio_iov;
319         int err;
320         
321         if (__predict_true(!is_ddp(m)))                              /* RX_DATA */
322                 return m_uiomove(m, offset, len, uio);
323         if (__predict_true(m->m_ddp_flags & DDP_BF_NOCOPY)) { /* user DDP */
324                 to->iov_len -= len;
325                 to->iov_base = ((caddr_t)to->iov_base) + len;
326                 uio->uio_iov = to;
327                 uio->uio_resid -= len;
328                 return (0);
329         }
330         err = t3_ddp_copy(m, offset, uio, len);             /* kernel DDP */
331         return (err);
332 }
333
334 static void
335 cxgb_wait_dma_completion(struct toepcb *toep)
336 {
337         struct rwlock *lock;
338         
339         lock = &toep->tp_tp->t_inpcb->inp_lock;
340         inp_wlock(toep->tp_tp->t_inpcb);
341         cv_wait_unlock(&toep->tp_cv, lock);
342 }
343
344 static int
345 cxgb_vm_page_to_miov(struct toepcb *toep, struct uio *uio, struct mbuf **m)
346 {
347         int i, seg_count, err, type;
348         struct mbuf *m0;
349         struct cxgb_dma_info cdi;
350         struct mbuf_vec *mv;
351         struct mbuf_iovec *mi;
352         bus_dma_segment_t *segs;
353         
354         err = bus_dmamap_load_uio(toep->tp_tx_dmat, toep->tp_dmamap, uio,
355             cxgb_dma_callback, &cdi, 0);
356
357         if (err)
358                 return (err);
359         seg_count = cdi.cdi_nsegs;      
360         if ((m0 = mcl_alloc(seg_count, &type)) == NULL) {
361                 bus_dmamap_unload(toep->tp_tx_dmat, toep->tp_dmamap);
362                 return (ENOMEM);
363         }
364         segs = cdi.cdi_segs;
365         m0->m_type = type;
366         m0->m_flags = (M_EXT|M_NOFREE);
367         m0->m_ext.ext_type = EXT_EXTREF;
368         m0->m_ext.ext_free = cxgb_zero_copy_free;
369 #if __FreeBSD_version >= 800016
370         m0->m_ext.ext_arg1 = NULL;      /* XXX: probably wrong /phk */
371         m0->m_ext.ext_arg2 = NULL;
372 #else
373         m0->m_ext.ext_args = NULL;
374 #endif
375     
376         mv = mtomv(m0);
377         mv->mv_count = seg_count;
378         mv->mv_first = 0;
379         for (i = 0, mi = mv->mv_vec; i < seg_count; mi++, segs++, i++)
380                 mi_collapse_sge(mi, segs);
381
382         *m = m0;
383
384         /*
385          * This appears to be a no-op at the moment
386          * as busdma is all or nothing need to make
387          * sure the tag values are large enough
388          *
389          */
390         if (cdi.cdi_mapped < uio->uio_resid) {
391                 uio->uio_resid -= cdi.cdi_mapped;
392         } else
393                 uio->uio_resid = 0;
394
395         return (0);
396 }
397
398 static int
399 t3_sosend(struct socket *so, struct uio *uio)
400 {
401         int rv, count, hold_resid, sent, iovcnt;
402         struct iovec iovtmp[TMP_IOV_MAX], *iovtmpp, *iov;
403         struct tcpcb *tp = so_sototcpcb(so);
404         struct toepcb *toep = tp->t_toe;
405         struct mbuf *m;
406         struct uio uiotmp;
407         struct sockbuf *snd;
408         
409         /*
410          * Events requiring iteration:
411          *  - number of pages exceeds max hold pages for process or system
412          *  - number of pages exceeds maximum sg entries for a single WR
413          *
414          * We're limited to holding 128 pages at once - and we're limited to
415          * 34 SG entries per work request, but each SG entry can be any number 
416          * of contiguous pages
417          *
418          */
419
420         uiotmp = *uio;
421         iovcnt = uio->uio_iovcnt;
422         iov = uio->uio_iov;
423         sent = 0;
424         snd = so_sockbuf_snd(so);
425 sendmore:
426         /*
427          * Make sure we don't exceed the socket buffer
428          */
429         count = min(toep->tp_page_count, (sockbuf_sbspace(snd) >> PAGE_SHIFT) + 2*PAGE_SIZE);
430         rv = cxgb_hold_iovec_pages(&uiotmp, toep->tp_pages, &count, VM_PROT_READ);
431         hold_resid = uiotmp.uio_resid;
432         if (rv)
433                 return (rv);
434
435         /*
436          * Bump past sent and shave off the unheld amount
437          */
438         if (hold_resid  > 0) {
439                 iovtmpp = iovtmp;
440                 memcpy(iovtmp, iov, iovcnt*sizeof(*iov));
441                 if (sent)
442                         iov_adj(&iovtmpp, &iovcnt, sent);
443                 iov_adj(&iovtmpp, &iovcnt, -hold_resid);
444                 uiotmp.uio_iov = iovtmpp;
445                 uiotmp.uio_iovcnt = iovcnt;
446
447         }
448         uiotmp.uio_resid = uio->uio_resid - hold_resid;
449         
450         /*
451          * Push off all held pages
452          *
453          */
454         while (uiotmp.uio_resid > 0) {
455                 rv = cxgb_vm_page_to_miov(toep, &uiotmp, &m);
456                 if (rv) {
457                         vm_fault_unhold_pages(toep->tp_pages, count);
458                         return (rv);
459                 }
460                 uio->uio_resid -= m->m_pkthdr.len;
461                 sent += m->m_pkthdr.len;
462                 sbappend(snd, m);
463                 t3_push_frames(so, TRUE);
464                 iov_adj(&uiotmp.uio_iov, &iovcnt, uiotmp.uio_resid);
465         }
466
467         /*
468          * Wait for pending I/O to be DMA'd to the card 
469          * 
470          */
471         cxgb_wait_dma_completion(toep);
472         vm_fault_unhold_pages(toep->tp_pages, count);
473         /*
474          * If there is more data to send adjust local copy of iov
475          * to point to teh start
476          */
477         if (hold_resid) {
478                 iovtmpp = iovtmp;
479                 memcpy(iovtmp, iov, iovcnt*sizeof(*iov));
480                 iov_adj(&iovtmpp, &iovcnt, sent);
481                 uiotmp = *uio;
482                 uiotmp.uio_iov = iovtmpp;
483                 uiotmp.uio_iovcnt = iovcnt;
484                 goto sendmore;
485         }
486
487         return (0);
488 }
489
490 static int
491 cxgb_sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
492     struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
493 {
494         struct tcpcb *tp = so_sototcpcb(so);
495         struct toedev *tdev; 
496         int zcopy_thres, zcopy_enabled, rv;
497
498         /*
499          * In order to use DMA direct from userspace the following
500          * conditions must be met:
501          *  - the connection is currently offloaded
502          *  - ddp is enabled
503          *  - the number of bytes to be transferred exceeds the threshold
504          *  - the number of bytes currently in flight won't exceed the in-flight
505          *    threshold XXX TODO
506          *  - vm_fault_hold_user_pages succeeds
507          *  - blocking socket XXX for now
508          *
509          */
510         if (tp && tp->t_flags & TF_TOE) {
511                 struct toepcb *toep = tp->t_toe;
512                 
513                 tdev = toep->tp_toedev;
514                 zcopy_thres = TOM_TUNABLE(tdev, zcopy_sosend_partial_thres);
515                 zcopy_enabled = TOM_TUNABLE(tdev, zcopy_sosend_enabled);
516
517                 if (uio && (uio->uio_resid > zcopy_thres) &&
518                     (uio->uio_iovcnt < TMP_IOV_MAX) &&  ((so_state_get(so) & SS_NBIO) == 0)
519                     && zcopy_enabled) {
520                         rv = t3_sosend(so, uio);
521                         if (rv != EAGAIN)
522                                 return (rv);
523                 }
524         }
525         return pru_sosend(so, addr, uio, top, control, flags, td);
526 }
527
528 /*
529  * Following replacement or removal of the first mbuf on the first mbuf chain
530  * of a socket buffer, push necessary state changes back into the socket
531  * buffer so that other consumers see the values consistently.  'nextrecord'
532  * is the callers locally stored value of the original value of
533  * sb->sb_mb->m_nextpkt which must be restored when the lead mbuf changes.
534  * NOTE: 'nextrecord' may be NULL.
535  */
536 static __inline void
537 sockbuf_pushsync(struct sockbuf *sb, struct mbuf *nextrecord)
538 {
539         sockbuf_lock_assert(sb);
540         /*
541          * First, update for the new value of nextrecord.  If necessary, make
542          * it the first record.
543          */
544         if (sb->sb_mb != NULL)
545                 sb->sb_mb->m_nextpkt = nextrecord;
546         else
547                 sb->sb_mb = nextrecord;
548
549         /*
550          * Now update any dependent socket buffer fields to reflect the new
551          * state.  This is an expanded inline of SB_EMPTY_FIXUP(), with the
552          * addition of a second clause that takes care of the case where
553          * sb_mb has been updated, but remains the last record.
554          */
555         if (sb->sb_mb == NULL) {
556                 sb->sb_mbtail = NULL;
557                 sb->sb_lastrecord = NULL;
558         } else if (sb->sb_mb->m_nextpkt == NULL)
559                 sb->sb_lastrecord = sb->sb_mb;
560 }
561
562 #define IS_NONBLOCKING(so)      (so_state_get(so) & SS_NBIO)
563
564 static int
565 t3_soreceive(struct socket *so, int *flagsp, struct uio *uio)
566 {
567         struct tcpcb *tp = so_sototcpcb(so);
568         struct toepcb *toep = tp->t_toe;
569         struct mbuf *m;
570         uint32_t offset;
571         int err, flags, avail, len, copied, copied_unacked;
572         int target;             /* Read at least this many bytes */
573         int user_ddp_ok;
574         struct ddp_state *p;
575         struct inpcb *inp = so_sotoinpcb(so);
576         int socket_state, socket_error;
577         struct sockbuf *rcv;
578         
579         avail = offset = copied = copied_unacked = 0;
580         flags = flagsp ? (*flagsp &~ MSG_EOR) : 0;
581         rcv = so_sockbuf_rcv(so);
582         
583         err = sblock(rcv, SBLOCKWAIT(flags));
584         p = &toep->tp_ddp_state;
585
586         if (err)
587                 return (err);
588
589         rcv = so_sockbuf_rcv(so);
590         sockbuf_lock(rcv);
591         if ((tp->t_flags & TF_TOE) == 0) {
592                 sockbuf_unlock(rcv);
593                 err = EAGAIN;
594                 goto done_unlocked;
595         }
596         
597         p->user_ddp_pending = 0;
598 restart:
599         if ((tp->t_flags & TF_TOE) == 0) {
600                 sockbuf_unlock(rcv);
601                 err = EAGAIN;
602                 goto done_unlocked;
603         }
604
605         len = uio->uio_resid;
606         m = rcv->sb_mb;
607         target = (flags & MSG_WAITALL) ? len : rcv->sb_lowat;
608         user_ddp_ok = p->ubuf_ddp_ready;
609         p->cancel_ubuf = 0;
610         
611         if (len == 0)
612                 goto done;
613         if (m) 
614                 goto got_mbuf;
615
616         /* empty receive queue */
617         if (copied >= target && (rcv->sb_mb == NULL) &&
618             !p->user_ddp_pending)
619                 goto done;
620
621         socket_state = so_state_get(so);
622         socket_error = so_error_get(so);
623         rcv = so_sockbuf_rcv(so);
624         
625         if (copied) {
626                 if (socket_error || tp->t_state == TCPS_CLOSED || 
627                     (socket_state & (SS_ISDISCONNECTING|SS_ISDISCONNECTED)))
628                         goto done;
629         } else {
630                 if (socket_state & SS_NOFDREF)
631                         goto done;
632                 if (socket_error) {
633                         err = socket_error;
634                         socket_error = 0;
635                         goto done;
636                 }
637                 if (rcv->sb_state & SBS_CANTRCVMORE) 
638                         goto done;
639                 if (socket_state & (SS_ISDISCONNECTING|SS_ISDISCONNECTED))
640                         goto done;
641                 if (tp->t_state == TCPS_CLOSED) {
642                         err = ENOTCONN; 
643                         goto done;
644                 }
645         }
646         if (rcv->sb_mb && !p->user_ddp_pending) {
647                 sockbuf_unlock(rcv);
648                 inp_wlock(inp);
649                 t3_cleanup_rbuf(tp, copied_unacked);
650                 inp_wunlock(inp);
651                 sockbuf_lock(rcv);
652                 copied_unacked = 0;
653                 goto restart;
654         }
655         if (p->kbuf[0] && user_ddp_ok && !p->user_ddp_pending && 
656             uio->uio_iov->iov_len > p->kbuf[0]->dgl_length &&
657             p->ubuf_ddp_ready) {
658                 p->user_ddp_pending =
659                     !t3_overlay_ubuf(toep, rcv, uio,
660                         IS_NONBLOCKING(so), flags, 1, 1);
661                 if (p->user_ddp_pending) {
662                         p->kbuf_posted++;
663                         user_ddp_ok = 0;
664                 }
665         }
666         if (p->kbuf[0] && (p->kbuf_posted == 0)) {
667                 t3_post_kbuf(toep, 1, IS_NONBLOCKING(so));
668                 p->kbuf_posted++;
669         }
670         if (p->user_ddp_pending) {
671                 /* One shot at DDP if we already have enough data */
672                 if (copied >= target)
673                         user_ddp_ok = 0;
674
675                 if (rcv->sb_state & SBS_CANTRCVMORE) 
676                         goto done;
677                 CTR0(KTR_TOM, "ddp pending -- waiting");
678                 if ((err = sbwait(rcv)) != 0)
679                         goto done;
680 //for timers to work                    await_ddp_completion(sk, flags, &timeo);
681         } else if (copied >= target)
682                 goto done;
683         else {
684                 if (copied_unacked) {
685                         int i = 0;
686
687                         sockbuf_unlock(rcv);
688                         inp_wlock(inp);
689                         t3_cleanup_rbuf(tp, copied_unacked);
690                         inp_wunlock(inp);
691                         copied_unacked = 0;
692                         if (mp_ncpus > 1)
693                                 while (i++ < 200 && rcv->sb_mb == NULL)
694                                         cpu_spinwait();
695                         sockbuf_lock(rcv);
696                 }
697                 if (rcv->sb_mb)
698                         goto restart;
699
700                 if (rcv->sb_state & SBS_CANTRCVMORE)
701                         goto done;
702
703                 CTR0(KTR_TOM, "no buffers -- waiting");
704
705                 if ((err = sbwait(rcv)) != 0) 
706                         goto done;
707         }
708         goto restart;
709 got_mbuf:
710         /*
711          * Adjust the mbuf seqno if it has already been partially processed by
712          * soreceive_generic
713          */
714         if (m->m_pkthdr.len != m->m_len) {
715                 m->m_seq += m->m_pkthdr.len - m->m_len;
716                 m->m_pkthdr.len = m->m_len;
717         }
718             
719         CTR6(KTR_TOM, "t3_soreceive: ddp_flags=0x%x m_len=%u resid=%u "
720             "m_seq=0x%08x c_seq=0x%08x c_unack=%u",
721             (is_ddp(m) ? m->m_ddp_flags : 0), m->m_pkthdr.len, len,
722             m->m_seq, toep->tp_copied_seq, copied_unacked);
723         KASSERT(((m->m_flags & M_EXT) && (m->m_ext.ext_type == EXT_EXTREF)) || !(m->m_flags & M_EXT),
724             ("unexpected type M_EXT=%d ext_type=%d m_len=%d m_pktlen=%d\n", !!(m->m_flags & M_EXT),
725                 m->m_ext.ext_type, m->m_len, m->m_pkthdr.len));
726         KASSERT(m->m_next != (struct mbuf *)0xffffffff, ("bad next value m_next=%p m_nextpkt=%p"
727                 " m_flags=0x%x m->m_len=%d", m->m_next, m->m_nextpkt, m->m_flags, m->m_len));
728         if (m->m_pkthdr.len == 0) {
729                 if ((m->m_ddp_flags & DDP_BF_NOCOPY) == 0)
730                         panic("empty mbuf and NOCOPY not set\n");
731                 CTR0(KTR_TOM, "ddp done notification");
732                 p->user_ddp_pending = 0;
733                 sbdroprecord_locked(rcv);
734                 goto done;
735         }
736
737         KASSERT((int32_t)(toep->tp_copied_seq + copied_unacked - m->m_seq) >= 0,
738             ("offset will go negative: offset=%d copied_seq=0x%08x copied_unacked=%d m_seq=0x%08x",
739                 offset, toep->tp_copied_seq, copied_unacked, m->m_seq));
740         offset = toep->tp_copied_seq + copied_unacked - m->m_seq;
741         
742         if (offset >= m->m_pkthdr.len)
743                 panic("t3_soreceive: OFFSET >= LEN offset %d copied_seq 0x%x "
744                     "seq 0x%x pktlen %d ddp flags 0x%x", offset,
745                     toep->tp_copied_seq + copied_unacked, m->m_seq,
746                     m->m_pkthdr.len, m->m_ddp_flags);
747
748         avail = m->m_pkthdr.len - offset;
749         if (len < avail) {
750                 if (is_ddp(m) && (m->m_ddp_flags & DDP_BF_NOCOPY)) 
751                         panic("bad state in t3_soreceive len=%d avail=%d offset=%d\n", len, avail, offset);
752                 avail = len;
753                 rcv->sb_flags |= SB_IN_TOE;
754         } else if (p->kbuf_posted == 0 && p->user_ddp_pending == 0)
755                 rcv->sb_flags &= ~SB_IN_TOE;
756                 
757 #ifdef URGENT_DATA_SUPPORTED
758         /*
759          * Check if the data we are preparing to copy contains urgent
760          * data.  Either stop short of urgent data or skip it if it's
761          * first and we are not delivering urgent data inline.
762          */
763         if (__predict_false(toep->tp_urg_data)) {
764                 uint32_t urg_offset = tp->rcv_up - tp->copied_seq + copied_unacked;
765                 
766                 if (urg_offset < avail) {
767                         if (urg_offset) {
768                                 /* stop short of the urgent data */
769                                 avail = urg_offset;
770                         } else if ((so_options_get(so) & SO_OOBINLINE) == 0) {
771                                 /* First byte is urgent, skip */
772                                 toep->tp_copied_seq++;
773                                 offset++;
774                                 avail--;
775                                 if (!avail)
776                                         goto skip_copy;
777                         }       
778                 }       
779         }       
780 #endif
781         if (is_ddp_psh(m) || offset || (rcv->sb_mb && !is_ddp(m))) {
782                 user_ddp_ok = 0;
783 #ifdef T3_TRACE 
784                 T3_TRACE0(TIDTB(so), "t3_sosend: PSH");
785 #endif  
786         }
787         
788         if (user_ddp_ok && !p->user_ddp_pending &&
789             uio->uio_iov->iov_len > p->kbuf[0]->dgl_length &&
790             p->ubuf_ddp_ready) {
791                 p->user_ddp_pending = 
792                     !t3_overlay_ubuf(toep, rcv, uio,
793                         IS_NONBLOCKING(so), flags, 1, 1);
794                 if (p->user_ddp_pending) {
795                         p->kbuf_posted++;
796                         user_ddp_ok = 0;
797                 }
798                 DPRINTF("user_ddp_pending=%d\n", p->user_ddp_pending);
799         } else
800                 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",
801                     user_ddp_ok, p->user_ddp_pending, uio->uio_iov->iov_len, p->kbuf[0] ? p->kbuf[0]->dgl_length : 0,
802                     p->ubuf_ddp_ready, toep->tp_ulp_mode, !!is_ddp(m), m->m_ddp_flags, p->ubuf, p->kbuf_posted);
803         
804         /*
805          * If MSG_TRUNC is specified the data is discarded.
806          * XXX need to check pr_atomic
807          */
808         KASSERT(avail > 0, ("avail=%d resid=%d offset=%d", avail,  uio->uio_resid, offset));
809         if (__predict_true(!(flags & MSG_TRUNC))) {
810                 int resid = uio->uio_resid;
811                 
812                 sockbuf_unlock(rcv);
813                 if ((err = copy_data(m, offset, avail, uio))) {
814                         if (err)
815                                 err = EFAULT;
816                         goto done_unlocked;
817                 }
818                             
819                 sockbuf_lock(rcv);
820                 if (avail != (resid - uio->uio_resid))
821                         printf("didn't copy all bytes :-/ avail=%d offset=%d pktlen=%d resid=%d uio_resid=%d copied=%d copied_unacked=%d is_ddp(m)=%d\n",
822                             avail, offset, m->m_pkthdr.len, resid, uio->uio_resid, copied, copied_unacked, is_ddp(m));
823
824                 if ((tp->t_flags & TF_TOE) == 0) {
825                         sockbuf_unlock(rcv);
826                         err = EAGAIN;
827                         goto done_unlocked;
828                 }
829         }
830         
831         copied += avail;
832         copied_unacked += avail;
833         len -= avail;
834         
835 #ifdef URGENT_DATA_SUPPORTED
836 skip_copy:
837         if (tp->urg_data && after(tp->copied_seq + copied_unacked, tp->urg_seq))
838                 tp->urg_data = 0;
839 #endif
840         /*
841          * If the buffer is fully consumed free it.  If it's a DDP
842          * buffer also handle any events it indicates.
843          */
844         if (avail + offset >= m->m_pkthdr.len) {
845                 unsigned int fl = m->m_ddp_flags;
846                 int exitnow, got_psh = 0, nomoredata = 0;
847                 int count;
848                 struct mbuf *nextrecord;
849
850                 if (p->kbuf[0] != NULL && is_ddp(m) && (fl & 1)) {
851                         if (is_ddp_psh(m) && p->user_ddp_pending)
852                                 got_psh = 1;
853                         
854                         if (fl & DDP_BF_NOCOPY)
855                                 p->user_ddp_pending = 0;
856                         else if ((fl & DDP_BF_NODATA) && IS_NONBLOCKING(so)) {
857                                 p->kbuf_posted--;
858                                 nomoredata = 1;
859                         } else {
860                                 p->kbuf_posted--;
861                                 p->ubuf_ddp_ready = 1;
862                         }
863                 }
864
865                 nextrecord = m->m_nextpkt;
866                 count = m->m_pkthdr.len;
867                 while (count > 0) {
868                         count -= m->m_len;
869                         KASSERT(((m->m_flags & M_EXT) && (m->m_ext.ext_type == EXT_EXTREF)) || !(m->m_flags & M_EXT), ("unexpected type M_EXT=%d ext_type=%d m_len=%d\n", !!(m->m_flags & M_EXT), m->m_ext.ext_type, m->m_len));
870                         CTR2(KTR_TOM, "freeing mbuf m_len = %d pktlen = %d", m->m_len, m->m_pkthdr.len);
871                         sbfree(rcv, m);
872                         rcv->sb_mb = m_free(m);
873                         m = rcv->sb_mb;
874                 }
875                 sockbuf_pushsync(rcv, nextrecord);
876 #if 0
877                 sbdrop_locked(rcv, m->m_pkthdr.len);
878 #endif          
879                 exitnow = got_psh || nomoredata;
880                 if  (copied >= target && (rcv->sb_mb == NULL) && exitnow)
881                         goto done;
882                 if (copied_unacked > (rcv->sb_hiwat >> 2)) {
883                         sockbuf_unlock(rcv);
884                         inp_wlock(inp);
885                         t3_cleanup_rbuf(tp, copied_unacked);
886                         inp_wunlock(inp);
887                         copied_unacked = 0;
888                         sockbuf_lock(rcv);
889                 }
890         } 
891         if (len > 0)
892                 goto restart;
893
894         done:
895         if ((tp->t_flags & TF_TOE) == 0) {
896                 sockbuf_unlock(rcv);
897                 err = EAGAIN;
898                 goto done_unlocked;
899         }
900         /*
901          * If we can still receive decide what to do in preparation for the
902          * next receive.  Note that RCV_SHUTDOWN is set if the connection
903          * transitioned to CLOSE but not if it was in that state to begin with.
904          */
905         if (__predict_true((so_state_get(so) & (SS_ISDISCONNECTING|SS_ISDISCONNECTED)) == 0)) {
906                 if (p->user_ddp_pending) {
907                         user_ddp_ok = 0;
908                         t3_cancel_ubuf(toep, rcv);
909                         if (rcv->sb_mb) {
910                                 if (copied < 0)
911                                         copied = 0;
912                                 if (len > 0)
913                                         goto restart;
914                         }
915                         p->user_ddp_pending = 0;
916                 }
917                 if ((p->kbuf[0] != NULL) && (p->kbuf_posted == 0)) {
918 #ifdef T3_TRACE
919                         T3_TRACE0(TIDTB(so),
920                           "chelsio_recvmsg: about to exit, repost kbuf");
921 #endif
922
923                         t3_post_kbuf(toep, 1, IS_NONBLOCKING(so));
924                         p->kbuf_posted++;
925                 } else if (so_should_ddp(toep, copied) && uio->uio_iovcnt == 1) {
926                         CTR1(KTR_TOM ,"entering ddp on tid=%u", toep->tp_tid);
927                         if (!t3_enter_ddp(toep, TOM_TUNABLE(toep->tp_toedev,
928                                     ddp_copy_limit), 0, IS_NONBLOCKING(so))) {
929                                 rcv->sb_flags |= SB_IN_TOE;
930                                 p->kbuf_posted = 1;
931                         }
932                         
933                 }
934         }
935 #ifdef T3_TRACE
936         T3_TRACE5(TIDTB(so),
937                   "chelsio_recvmsg <-: copied %d len %d buffers_freed %d "
938                   "kbuf_posted %d user_ddp_pending %u",
939                   copied, len, buffers_freed, p ? p->kbuf_posted : -1, 
940             p->user_ddp_pending);
941 #endif
942         sockbuf_unlock(rcv);
943 done_unlocked:  
944         if (copied_unacked && (tp->t_flags & TF_TOE)) {
945                 inp_wlock(inp);
946                 t3_cleanup_rbuf(tp, copied_unacked);
947                 inp_wunlock(inp);
948         }
949         sbunlock(rcv);
950
951         return (err);
952 }
953
954 static int
955 cxgb_soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio,
956     struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
957 {
958         struct toedev *tdev;
959         int rv, zcopy_thres, zcopy_enabled, flags;
960         struct tcpcb *tp = so_sototcpcb(so);
961         struct sockbuf *rcv = so_sockbuf_rcv(so);
962         
963         flags = flagsp ? *flagsp &~ MSG_EOR : 0;
964         
965         /*
966          * In order to use DMA direct from userspace the following
967          * conditions must be met:
968          *  - the connection is currently offloaded
969          *  - ddp is enabled
970          *  - the number of bytes to be transferred exceeds the threshold
971          *  - the number of bytes currently in flight won't exceed the in-flight
972          *    threshold XXX TODO
973          *  - vm_fault_hold_user_pages succeeds
974          *  - blocking socket XXX for now
975          *  - iovcnt is 1
976          *
977          */
978         if (tp && (tp->t_flags & TF_TOE) && uio && ((flags & (MSG_OOB|MSG_PEEK|MSG_DONTWAIT)) == 0)
979             && (uio->uio_iovcnt == 1) && (mp0 == NULL) &&
980             ((rcv->sb_flags & SB_IN_TOE) || (uio->uio_iovcnt == 1))) {
981                 struct toepcb *toep = tp->t_toe;
982                 
983                 tdev =  toep->tp_toedev;
984                 zcopy_thres = TOM_TUNABLE(tdev, ddp_thres);
985                 zcopy_enabled = TOM_TUNABLE(tdev, ddp);
986                 if ((rcv->sb_flags & SB_IN_TOE) ||((uio->uio_resid > zcopy_thres) &&
987                         (uio->uio_iovcnt == 1) && zcopy_enabled)) {
988                         CTR4(KTR_TOM, "cxgb_soreceive: sb_flags=0x%x t_flags=0x%x flags=0x%x uio_resid=%d",
989                             rcv->sb_flags, tp->t_flags, flags, uio->uio_resid);
990                         rv = t3_soreceive(so, flagsp, uio);
991                         if (rv != EAGAIN)
992                                 return (rv);
993                         else
994                                 printf("returned EAGAIN\n");
995                 } 
996         } else if (tp && (tp->t_flags & TF_TOE) && uio && mp0 == NULL) {
997                 struct sockbuf *rcv = so_sockbuf_rcv(so);
998                 
999                 log(LOG_INFO, "skipping t3_soreceive flags=0x%x iovcnt=%d sb_state=0x%x\n",
1000                     flags, uio->uio_iovcnt, rcv->sb_state);
1001         }
1002         
1003         return pru_soreceive(so, psa, uio, mp0, controlp, flagsp);
1004 }
1005
1006 struct protosw cxgb_protosw;
1007 struct pr_usrreqs cxgb_tcp_usrreqs;
1008
1009 void
1010 t3_install_socket_ops(struct socket *so)
1011 {
1012         static int copied = 0;
1013         struct pr_usrreqs *pru;
1014         struct protosw *psw;
1015         
1016         if (copied == 0) {
1017                 psw = so_protosw_get(so);       
1018                 pru = psw->pr_usrreqs;
1019
1020                 bcopy(psw, &cxgb_protosw, sizeof(*psw));
1021                 bcopy(pru, &cxgb_tcp_usrreqs, sizeof(*pru));
1022
1023                 cxgb_protosw.pr_ctloutput = t3_ctloutput;
1024                 cxgb_protosw.pr_usrreqs = &cxgb_tcp_usrreqs;
1025                 cxgb_tcp_usrreqs.pru_sosend = cxgb_sosend;
1026                 cxgb_tcp_usrreqs.pru_soreceive = cxgb_soreceive;
1027         }
1028         so_protosw_set(so, &cxgb_protosw);
1029         
1030 #if 0   
1031         so->so_proto->pr_usrreqs->pru_sosend = cxgb_sosend;
1032         so->so_proto->pr_usrreqs->pru_soreceive = cxgb_soreceive;
1033 #endif
1034 }