Whamcloud - gitweb
5b0a9e9083928429ad26897291cb5f68c39b266c
[fs/lustre-release.git] / lnet / klnds / socklnd / socklnd_lib-linux.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #include "socklnd.h"
38
39 # if defined(CONFIG_SYSCTL) && !CFS_SYSFS_MODULE_PARM
40
41 #ifndef HAVE_SYSCTL_UNNUMBERED
42
43 enum {
44         SOCKLND_TIMEOUT = 1,
45         SOCKLND_CREDITS,
46         SOCKLND_PEER_CREDITS,
47         SOCKLND_NCONNDS,
48         SOCKLND_RECONNECTS_MIN,
49         SOCKLND_RECONNECTS_MAX,
50         SOCKLND_EAGER_ACK,
51         SOCKLND_ZERO_COPY,
52         SOCKLND_TYPED,
53         SOCKLND_BULK_MIN,
54         SOCKLND_RX_BUFFER_SIZE,
55         SOCKLND_TX_BUFFER_SIZE,
56         SOCKLND_NAGLE,
57         SOCKLND_IRQ_AFFINITY,
58         SOCKLND_KEEPALIVE_IDLE,
59         SOCKLND_KEEPALIVE_COUNT,
60         SOCKLND_KEEPALIVE_INTVL,
61         SOCKLND_BACKOFF_INIT,
62         SOCKLND_BACKOFF_MAX,
63         SOCKLND_PROTOCOL,
64         SOCKLND_ZERO_COPY_RECV,
65         SOCKLND_ZERO_COPY_RECV_MIN_NFRAGS
66 };
67 #else
68
69 #define SOCKLND_TIMEOUT         CTL_UNNUMBERED
70 #define SOCKLND_CREDITS         CTL_UNNUMBERED
71 #define SOCKLND_PEER_CREDITS    CTL_UNNUMBERED
72 #define SOCKLND_NCONNDS         CTL_UNNUMBERED
73 #define SOCKLND_RECONNECTS_MIN  CTL_UNNUMBERED
74 #define SOCKLND_RECONNECTS_MAX  CTL_UNNUMBERED
75 #define SOCKLND_EAGER_ACK       CTL_UNNUMBERED
76 #define SOCKLND_ZERO_COPY       CTL_UNNUMBERED
77 #define SOCKLND_TYPED           CTL_UNNUMBERED
78 #define SOCKLND_BULK_MIN        CTL_UNNUMBERED
79 #define SOCKLND_RX_BUFFER_SIZE  CTL_UNNUMBERED
80 #define SOCKLND_TX_BUFFER_SIZE  CTL_UNNUMBERED
81 #define SOCKLND_NAGLE           CTL_UNNUMBERED
82 #define SOCKLND_IRQ_AFFINITY    CTL_UNNUMBERED
83 #define SOCKLND_KEEPALIVE_IDLE  CTL_UNNUMBERED
84 #define SOCKLND_KEEPALIVE_COUNT CTL_UNNUMBERED
85 #define SOCKLND_KEEPALIVE_INTVL CTL_UNNUMBERED
86 #define SOCKLND_BACKOFF_INIT    CTL_UNNUMBERED
87 #define SOCKLND_BACKOFF_MAX     CTL_UNNUMBERED
88 #define SOCKLND_PROTOCOL        CTL_UNNUMBERED
89 #define SOCKLND_ZERO_COPY_RECV  CTL_UNNUMBERED
90 #define SOCKLND_ZERO_COPY_RECV_MIN_NFRAGS CTL_UNNUMBERED
91 #endif
92
93 static cfs_sysctl_table_t ksocknal_ctl_table[] = {
94         {
95                 .ctl_name = SOCKLND_TIMEOUT,
96                 .procname = "timeout",
97                 .data     = &ksocknal_tunables.ksnd_timeout,
98                 .maxlen   = sizeof (int),
99                 .mode     = 0644,
100                 .proc_handler = &proc_dointvec,
101                 .strategy = &sysctl_intvec,
102         },
103         {
104                 .ctl_name = SOCKLND_CREDITS,
105                 .procname = "credits",
106                 .data     = &ksocknal_tunables.ksnd_credits,
107                 .maxlen   = sizeof (int),
108                 .mode     = 0444,
109                 .proc_handler = &proc_dointvec,
110                 .strategy = &sysctl_intvec,
111         },
112          {
113                 .ctl_name = SOCKLND_PEER_CREDITS,
114                 .procname = "peer_credits",
115                 .data     = &ksocknal_tunables.ksnd_peercredits,
116                 .maxlen   = sizeof (int),
117                 .mode     = 0444,
118                 .proc_handler = &proc_dointvec,
119                 .strategy = &sysctl_intvec,
120         },
121         {
122                 .ctl_name = SOCKLND_NCONNDS,
123                 .procname = "nconnds",
124                 .data     = &ksocknal_tunables.ksnd_nconnds,
125                 .maxlen   = sizeof (int),
126                 .mode     = 0444,
127                 .proc_handler = &proc_dointvec,
128                 .strategy = &sysctl_intvec,
129         },
130         {
131                 .ctl_name = SOCKLND_RECONNECTS_MIN,
132                 .procname = "min_reconnectms",
133                 .data     = &ksocknal_tunables.ksnd_min_reconnectms,
134                 .maxlen   = sizeof (int),
135                 .mode     = 0444,
136                 .proc_handler = &proc_dointvec,
137                 .strategy = &sysctl_intvec,
138         },
139         {
140                 .ctl_name = SOCKLND_RECONNECTS_MAX,
141                 .procname = "max_reconnectms",
142                 .data     = &ksocknal_tunables.ksnd_max_reconnectms,
143                 .maxlen   = sizeof (int),
144                 .mode     = 0444,
145                 .proc_handler = &proc_dointvec,
146                 .strategy = &sysctl_intvec,
147         },
148         {
149                 .ctl_name = SOCKLND_EAGER_ACK,
150                 .procname = "eager_ack",
151                 .data     = &ksocknal_tunables.ksnd_eager_ack,
152                 .maxlen   = sizeof (int),
153                 .mode     = 0644,
154                 .proc_handler = &proc_dointvec,
155                 .strategy = &sysctl_intvec,
156         },
157         {
158                 .ctl_name = SOCKLND_ZERO_COPY,
159                 .procname = "zero_copy",
160                 .data     = &ksocknal_tunables.ksnd_zc_min_frag,
161                 .maxlen   = sizeof (int),
162                 .mode     = 0644,
163                 .proc_handler = &proc_dointvec,
164                 .strategy = &sysctl_intvec,
165         },
166         {
167                 .ctl_name = SOCKLND_ZERO_COPY_RECV,
168                 .procname = "zero_copy_recv",
169                 .data     = &ksocknal_tunables.ksnd_zc_recv,
170                 .maxlen   = sizeof (int),
171                 .mode     = 0644,
172                 .proc_handler = &proc_dointvec,
173                 .strategy = &sysctl_intvec,
174         },
175
176         {
177                 .ctl_name = SOCKLND_ZERO_COPY_RECV_MIN_NFRAGS,
178                 .procname = "zero_copy_recv",
179                 .data     = &ksocknal_tunables.ksnd_zc_recv_min_nfrags,
180                 .maxlen   = sizeof (int),
181                 .mode     = 0644,
182                 .proc_handler = &proc_dointvec,
183                 .strategy = &sysctl_intvec,
184         },
185         {
186                 .ctl_name = SOCKLND_TYPED,
187                 .procname = "typed",
188                 .data     = &ksocknal_tunables.ksnd_typed_conns,
189                 .maxlen   = sizeof (int),
190                 .mode     = 0444,
191                 .proc_handler = &proc_dointvec,
192                 .strategy = &sysctl_intvec,
193         },
194         {
195                 .ctl_name = SOCKLND_BULK_MIN,
196                 .procname = "min_bulk",
197                 .data     = &ksocknal_tunables.ksnd_min_bulk,
198                 .maxlen   = sizeof (int),
199                 .mode     = 0644,
200                 .proc_handler = &proc_dointvec,
201                 .strategy = &sysctl_intvec,
202         },
203         {
204                 .ctl_name = SOCKLND_RX_BUFFER_SIZE,
205                 .procname = "rx_buffer_size",
206                 .data     = &ksocknal_tunables.ksnd_rx_buffer_size,
207                 .maxlen   = sizeof(int),
208                 .mode     = 0644,
209                 .proc_handler = &proc_dointvec,
210                 .strategy = &sysctl_intvec,
211         },
212         {
213                 .ctl_name = SOCKLND_TX_BUFFER_SIZE,
214                 .procname = "tx_buffer_size",
215                 .data     = &ksocknal_tunables.ksnd_tx_buffer_size,
216                 .maxlen   = sizeof(int),
217                 .mode     = 0644,
218                 .proc_handler = &proc_dointvec,
219                 .strategy = &sysctl_intvec,
220         },
221         {
222                 .ctl_name = SOCKLND_NAGLE,
223                 .procname = "nagle",
224                 .data     = &ksocknal_tunables.ksnd_nagle,
225                 .maxlen   = sizeof(int),
226                 .mode     = 0644,
227                 .proc_handler = &proc_dointvec,
228                 .strategy = &sysctl_intvec,
229         },
230 #ifdef CPU_AFFINITY
231         {
232                 .ctl_name = SOCKLND_IRQ_AFFINITY,
233                 .procname = "irq_affinity",
234                 .data     = &ksocknal_tunables.ksnd_irq_affinity,
235                 .maxlen   = sizeof(int),
236                 .mode     = 0644,
237                 .proc_handler = &proc_dointvec,
238                 .strategy = &sysctl_intvec,
239         },
240 #endif
241         {
242                 .ctl_name = SOCKLND_KEEPALIVE_IDLE,
243                 .procname = "keepalive_idle",
244                 .data     = &ksocknal_tunables.ksnd_keepalive_idle,
245                 .maxlen   = sizeof(int),
246                 .mode     = 0644,
247                 .proc_handler = &proc_dointvec,
248                 .strategy = &sysctl_intvec,
249         },
250         {
251                 .ctl_name = SOCKLND_KEEPALIVE_COUNT,
252                 .procname = "keepalive_count",
253                 .data     = &ksocknal_tunables.ksnd_keepalive_count,
254                 .maxlen   = sizeof(int),
255                 .mode     = 0644,
256                 .proc_handler = &proc_dointvec,
257                 .strategy = &sysctl_intvec,
258         },
259         {
260                 .ctl_name = SOCKLND_KEEPALIVE_INTVL,
261                 .procname = "keepalive_intvl",
262                 .data     = &ksocknal_tunables.ksnd_keepalive_intvl,
263                 .maxlen   = sizeof(int),
264                 .mode     = 0644,
265                 .proc_handler = &proc_dointvec,
266                 .strategy = &sysctl_intvec,
267         },
268 #ifdef SOCKNAL_BACKOFF
269         {
270                 .ctl_name = SOCKLND_BACKOFF_INIT,
271                 .procname = "backoff_init",
272                 .data     = &ksocknal_tunables.ksnd_backoff_init,
273                 .maxlen   = sizeof(int),
274                 .mode     = 0644,
275                 .proc_handler = &proc_dointvec,
276                 .strategy = &sysctl_intvec,
277         },
278         {
279                 .ctl_name = SOCKLND_BACKOFF_MAX,
280                 .procname = "backoff_max",
281                 .data     = &ksocknal_tunables.ksnd_backoff_max,
282                 .maxlen   = sizeof(int),
283                 .mode     = 0644,
284                 .proc_handler = &proc_dointvec,
285                 .strategy = &sysctl_intvec,
286         },
287 #endif
288 #if SOCKNAL_VERSION_DEBUG
289         {
290                 .ctl_name = SOCKLND_PROTOCOL,
291                 .procname = "protocol",
292                 .data     = &ksocknal_tunables.ksnd_protocol,
293                 .maxlen   = sizeof(int),
294                 .mode     = 0644,
295                 .proc_handler = &proc_dointvec,
296                 .strategy = &sysctl_intvec,
297         },
298 #endif
299         {0}
300 };
301
302
303 cfs_sysctl_table_t ksocknal_top_ctl_table[] = {
304         {
305                 .ctl_name = CTL_SOCKLND,
306                 .procname = "socknal",
307                 .data     = NULL,
308                 .maxlen   = 0,
309                 .mode     = 0555,
310                 .child    = ksocknal_ctl_table
311         },
312         { 0 }
313 };
314
315 int
316 ksocknal_lib_tunables_init ()
317 {
318         if (*ksocknal_tunables.ksnd_zc_recv_min_nfrags < 2)
319                 *ksocknal_tunables.ksnd_zc_recv_min_nfrags = 2;
320         if (*ksocknal_tunables.ksnd_zc_recv_min_nfrags > LNET_MAX_IOV)
321                 *ksocknal_tunables.ksnd_zc_recv_min_nfrags = LNET_MAX_IOV;
322
323         ksocknal_tunables.ksnd_sysctl =
324                 cfs_register_sysctl_table(ksocknal_top_ctl_table, 0);
325
326         if (ksocknal_tunables.ksnd_sysctl == NULL)
327                 CWARN("Can't setup /proc tunables\n");
328
329         return 0;
330 }
331
332 void
333 ksocknal_lib_tunables_fini ()
334 {
335         if (ksocknal_tunables.ksnd_sysctl != NULL)
336                 cfs_unregister_sysctl_table(ksocknal_tunables.ksnd_sysctl);
337 }
338 #else
339 int
340 ksocknal_lib_tunables_init ()
341 {
342         return 0;
343 }
344
345 void
346 ksocknal_lib_tunables_fini ()
347 {
348 }
349 #endif /* # if CONFIG_SYSCTL && !CFS_SYSFS_MODULE_PARM */
350
351 void
352 ksocknal_lib_bind_irq (unsigned int irq)
353 {
354 #if (defined(CONFIG_SMP) && defined(CPU_AFFINITY))
355         int              bind;
356         int              cpu;
357         char             cmdline[64];
358         ksock_irqinfo_t *info;
359         char            *argv[] = {"/bin/sh",
360                                    "-c",
361                                    cmdline,
362                                    NULL};
363         char            *envp[] = {"HOME=/",
364                                    "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
365                                    NULL};
366
367         LASSERT (irq < NR_IRQS);
368         if (irq == 0)              /* software NIC or affinity disabled */
369                 return;
370
371         info = &ksocknal_data.ksnd_irqinfo[irq];
372
373         cfs_write_lock_bh (&ksocknal_data.ksnd_global_lock);
374
375         LASSERT (info->ksni_valid);
376         bind = !info->ksni_bound;
377         info->ksni_bound = 1;
378
379         cfs_write_unlock_bh (&ksocknal_data.ksnd_global_lock);
380
381         if (!bind)                              /* bound already */
382                 return;
383
384         cpu = ksocknal_irqsched2cpu(info->ksni_sched);
385         snprintf (cmdline, sizeof (cmdline),
386                   "echo %d > /proc/irq/%u/smp_affinity", 1 << cpu, irq);
387
388         LCONSOLE_INFO("Binding irq %u to CPU %d with cmd: %s\n",
389                       irq, cpu, cmdline);
390
391         /* FIXME: Find a better method of setting IRQ affinity...
392          */
393
394         USERMODEHELPER(argv[0], argv, envp);
395 #endif
396 }
397
398 int
399 ksocknal_lib_get_conn_addrs (ksock_conn_t *conn)
400 {
401         int rc = libcfs_sock_getaddr(conn->ksnc_sock, 1,
402                                      &conn->ksnc_ipaddr,
403                                      &conn->ksnc_port);
404
405         /* Didn't need the {get,put}connsock dance to deref ksnc_sock... */
406         LASSERT (!conn->ksnc_closing);
407
408         if (rc != 0) {
409                 CERROR ("Error %d getting sock peer IP\n", rc);
410                 return rc;
411         }
412
413         rc = libcfs_sock_getaddr(conn->ksnc_sock, 0,
414                                  &conn->ksnc_myipaddr, NULL);
415         if (rc != 0) {
416                 CERROR ("Error %d getting sock local IP\n", rc);
417                 return rc;
418         }
419
420         return 0;
421 }
422
423 unsigned int
424 ksocknal_lib_sock_irq (struct socket *sock)
425 {
426         int                irq = 0;
427 #ifdef CPU_AFFINITY
428         struct dst_entry  *dst;
429
430         if (!*ksocknal_tunables.ksnd_irq_affinity)
431                 return 0;
432
433         dst = sk_dst_get (sock->sk);
434         if (dst != NULL) {
435                 if (dst->dev != NULL) {
436                         irq = dst->dev->irq;
437                         if (irq >= NR_IRQS) {
438                                 CERROR ("Unexpected IRQ %x\n", irq);
439                                 irq = 0;
440                         }
441                 }
442                 dst_release (dst);
443         }
444
445 #endif
446         return irq;
447 }
448
449 int
450 ksocknal_lib_zc_capable(struct socket *sock)
451 {
452         int  caps = sock->sk->sk_route_caps;
453
454         /* ZC if the socket supports scatter/gather and doesn't need software
455          * checksums */
456         return ((caps & NETIF_F_SG) != 0 &&
457                 (caps & (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)) != 0);
458 }
459
460 int
461 ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
462 {
463         struct socket *sock = conn->ksnc_sock;
464         int            nob;
465         int            rc;
466
467         if (*ksocknal_tunables.ksnd_enable_csum        && /* checksum enabled */
468             conn->ksnc_proto == &ksocknal_protocol_v2x && /* V2.x connection  */
469             tx->tx_nob == tx->tx_resid                 && /* frist sending    */
470             tx->tx_msg.ksm_csum == 0)                     /* not checksummed  */
471                 ksocknal_lib_csum_tx(tx);
472
473         /* NB we can't trust socket ops to either consume our iovs
474          * or leave them alone. */
475
476         {
477 #if SOCKNAL_SINGLE_FRAG_TX
478                 struct iovec    scratch;
479                 struct iovec   *scratchiov = &scratch;
480                 unsigned int    niov = 1;
481 #else
482                 struct iovec   *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
483                 unsigned int    niov = tx->tx_niov;
484 #endif
485                 struct msghdr msg = {
486                         .msg_name       = NULL,
487                         .msg_namelen    = 0,
488                         .msg_iov        = scratchiov,
489                         .msg_iovlen     = niov,
490                         .msg_control    = NULL,
491                         .msg_controllen = 0,
492                         .msg_flags      = MSG_DONTWAIT
493                 };
494                 mm_segment_t oldmm = get_fs();
495                 int  i;
496
497                 for (nob = i = 0; i < niov; i++) {
498                         scratchiov[i] = tx->tx_iov[i];
499                         nob += scratchiov[i].iov_len;
500                 }
501
502                 if (!list_empty(&conn->ksnc_tx_queue) ||
503                     nob < tx->tx_resid)
504                         msg.msg_flags |= MSG_MORE;
505
506                 set_fs (KERNEL_DS);
507                 rc = sock_sendmsg(sock, &msg, nob);
508                 set_fs (oldmm);
509         }
510         return rc;
511 }
512
513 int
514 ksocknal_lib_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
515 {
516         struct socket *sock = conn->ksnc_sock;
517         lnet_kiov_t    *kiov = tx->tx_kiov;
518         int            rc;
519         int            nob;
520
521         /* NB we can't trust socket ops to either consume our iovs
522          * or leave them alone. */
523
524         if (kiov->kiov_len >= *ksocknal_tunables.ksnd_zc_min_frag &&
525             tx->tx_msg.ksm_zc_req_cookie != 0) {
526                 /* Zero copy is enabled */
527                 struct sock   *sk = sock->sk;
528                 struct page   *page = kiov->kiov_page;
529                 int            offset = kiov->kiov_offset;
530                 int            fragsize = kiov->kiov_len;
531                 int            msgflg = MSG_DONTWAIT;
532
533                 CDEBUG(D_NET, "page %p + offset %x for %d\n",
534                                page, offset, kiov->kiov_len);
535
536                 if (!list_empty(&conn->ksnc_tx_queue) ||
537                     fragsize < tx->tx_resid)
538                         msgflg |= MSG_MORE;
539
540                 if (sk->sk_prot->sendpage != NULL) {
541                         rc = sk->sk_prot->sendpage(sk, page,
542                                                    offset, fragsize, msgflg);
543                 } else {
544                         rc = tcp_sendpage(sock, page, offset, fragsize, msgflg);
545                 }
546         } else {
547 #if SOCKNAL_SINGLE_FRAG_TX || !SOCKNAL_RISK_KMAP_DEADLOCK
548                 struct iovec  scratch;
549                 struct iovec *scratchiov = &scratch;
550                 unsigned int  niov = 1;
551 #else
552 #ifdef CONFIG_HIGHMEM
553 #warning "XXX risk of kmap deadlock on multiple frags..."
554 #endif
555                 struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
556                 unsigned int  niov = tx->tx_nkiov;
557 #endif
558                 struct msghdr msg = {
559                         .msg_name       = NULL,
560                         .msg_namelen    = 0,
561                         .msg_iov        = scratchiov,
562                         .msg_iovlen     = niov,
563                         .msg_control    = NULL,
564                         .msg_controllen = 0,
565                         .msg_flags      = MSG_DONTWAIT
566                 };
567                 mm_segment_t  oldmm = get_fs();
568                 int           i;
569
570                 for (nob = i = 0; i < niov; i++) {
571                         scratchiov[i].iov_base = kmap(kiov[i].kiov_page) +
572                                                  kiov[i].kiov_offset;
573                         nob += scratchiov[i].iov_len = kiov[i].kiov_len;
574                 }
575
576                 if (!list_empty(&conn->ksnc_tx_queue) ||
577                     nob < tx->tx_resid)
578                         msg.msg_flags |= MSG_MORE;
579
580                 set_fs (KERNEL_DS);
581                 rc = sock_sendmsg(sock, &msg, nob);
582                 set_fs (oldmm);
583
584                 for (i = 0; i < niov; i++)
585                         kunmap(kiov[i].kiov_page);
586         }
587         return rc;
588 }
589
590 void
591 ksocknal_lib_eager_ack (ksock_conn_t *conn)
592 {
593         int            opt = 1;
594         mm_segment_t   oldmm = get_fs();
595         struct socket *sock = conn->ksnc_sock;
596
597         /* Remind the socket to ACK eagerly.  If I don't, the socket might
598          * think I'm about to send something it could piggy-back the ACK
599          * on, introducing delay in completing zero-copy sends in my
600          * peer. */
601
602         set_fs(KERNEL_DS);
603         sock->ops->setsockopt (sock, SOL_TCP, TCP_QUICKACK,
604                                (char *)&opt, sizeof (opt));
605         set_fs(oldmm);
606 }
607
608 int
609 ksocknal_lib_recv_iov (ksock_conn_t *conn)
610 {
611 #if SOCKNAL_SINGLE_FRAG_RX
612         struct iovec  scratch;
613         struct iovec *scratchiov = &scratch;
614         unsigned int  niov = 1;
615 #else
616         struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
617         unsigned int  niov = conn->ksnc_rx_niov;
618 #endif
619         struct iovec *iov = conn->ksnc_rx_iov;
620         struct msghdr msg = {
621                 .msg_name       = NULL,
622                 .msg_namelen    = 0,
623                 .msg_iov        = scratchiov,
624                 .msg_iovlen     = niov,
625                 .msg_control    = NULL,
626                 .msg_controllen = 0,
627                 .msg_flags      = 0
628         };
629         mm_segment_t oldmm = get_fs();
630         int          nob;
631         int          i;
632         int          rc;
633         int          fragnob;
634         int          sum;
635         __u32        saved_csum;
636
637         /* NB we can't trust socket ops to either consume our iovs
638          * or leave them alone. */
639         LASSERT (niov > 0);
640
641         for (nob = i = 0; i < niov; i++) {
642                 scratchiov[i] = iov[i];
643                 nob += scratchiov[i].iov_len;
644         }
645         LASSERT (nob <= conn->ksnc_rx_nob_wanted);
646
647         set_fs (KERNEL_DS);
648         rc = sock_recvmsg (conn->ksnc_sock, &msg, nob, MSG_DONTWAIT);
649         /* NB this is just a boolean..........................^ */
650         set_fs (oldmm);
651
652         saved_csum = 0;
653         if (conn->ksnc_proto == &ksocknal_protocol_v2x) {
654                 saved_csum = conn->ksnc_msg.ksm_csum;
655                 conn->ksnc_msg.ksm_csum = 0;
656         }
657
658         if (saved_csum != 0) {
659                 /* accumulate checksum */
660                 for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
661                         LASSERT (i < niov);
662
663                         fragnob = iov[i].iov_len;
664                         if (fragnob > sum)
665                                 fragnob = sum;
666
667                         conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
668                                                            iov[i].iov_base, fragnob);
669                 }
670                 conn->ksnc_msg.ksm_csum = saved_csum;
671         }
672
673         return rc;
674 }
675
676 static void
677 ksocknal_lib_kiov_vunmap(void *addr)
678 {
679         if (addr == NULL)
680                 return;
681
682         vunmap(addr);
683 }
684
685 static void *
686 ksocknal_lib_kiov_vmap(lnet_kiov_t *kiov, int niov,
687                        struct iovec *iov, struct page **pages)
688 {
689         void             *addr;
690         int               nob;
691         int               i;
692
693         if (!*ksocknal_tunables.ksnd_zc_recv || pages == NULL)
694                 return NULL;
695
696         LASSERT (niov <= LNET_MAX_IOV);
697
698         if (niov < 2 ||
699             niov < *ksocknal_tunables.ksnd_zc_recv_min_nfrags)
700                 return NULL;
701
702         for (nob = i = 0; i < niov; i++) {
703                 if ((kiov[i].kiov_offset != 0 && i > 0) ||
704                     (kiov[i].kiov_offset + kiov[i].kiov_len != CFS_PAGE_SIZE && i < niov - 1))
705                         return NULL;
706
707                 pages[i] = kiov[i].kiov_page;
708                 nob += kiov[i].kiov_len;
709         }
710
711         addr = vmap(pages, niov, VM_MAP, PAGE_KERNEL);
712         if (addr == NULL)
713                 return NULL;
714
715         iov->iov_base = addr + kiov[0].kiov_offset;
716         iov->iov_len = nob;
717
718         return addr;
719 }
720
721 int
722 ksocknal_lib_recv_kiov (ksock_conn_t *conn)
723 {
724 #if SOCKNAL_SINGLE_FRAG_RX || !SOCKNAL_RISK_KMAP_DEADLOCK
725         struct iovec   scratch;
726         struct iovec  *scratchiov = &scratch;
727         struct page  **pages      = NULL;
728         unsigned int   niov       = 1;
729 #else
730 #ifdef CONFIG_HIGHMEM
731 #warning "XXX risk of kmap deadlock on multiple frags..."
732 #endif
733         struct iovec  *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
734         struct page  **pages      = conn->ksnc_scheduler->kss_rx_scratch_pgs;
735         unsigned int   niov       = conn->ksnc_rx_nkiov;
736 #endif
737         lnet_kiov_t   *kiov = conn->ksnc_rx_kiov;
738         struct msghdr msg = {
739                 .msg_name       = NULL,
740                 .msg_namelen    = 0,
741                 .msg_iov        = scratchiov,
742                 .msg_control    = NULL,
743                 .msg_controllen = 0,
744                 .msg_flags      = 0
745         };
746         mm_segment_t oldmm = get_fs();
747         int          nob;
748         int          i;
749         int          rc;
750         void        *base;
751         void        *addr;
752         int          sum;
753         int          fragnob;
754
755         /* NB we can't trust socket ops to either consume our iovs
756          * or leave them alone. */
757         if ((addr = ksocknal_lib_kiov_vmap(kiov, niov, scratchiov, pages)) != NULL) {
758                 nob = scratchiov[0].iov_len;
759                 msg.msg_iovlen = 1;
760
761         } else {
762                 for (nob = i = 0; i < niov; i++) {
763                         nob += scratchiov[i].iov_len = kiov[i].kiov_len;
764                         scratchiov[i].iov_base = kmap(kiov[i].kiov_page) +
765                                                  kiov[i].kiov_offset;
766                 }
767                 msg.msg_iovlen = niov;
768         }
769
770         LASSERT (nob <= conn->ksnc_rx_nob_wanted);
771
772         set_fs (KERNEL_DS);
773         rc = sock_recvmsg (conn->ksnc_sock, &msg, nob, MSG_DONTWAIT);
774         /* NB this is just a boolean.......................^ */
775         set_fs (oldmm);
776
777         if (conn->ksnc_msg.ksm_csum != 0) {
778                 for (i = 0, sum = rc; sum > 0; i++, sum -= fragnob) {
779                         LASSERT (i < niov);
780
781                         /* Dang! have to kmap again because I have nowhere to stash the
782                          * mapped address.  But by doing it while the page is still
783                          * mapped, the kernel just bumps the map count and returns me
784                          * the address it stashed. */
785                         base = kmap(kiov[i].kiov_page) + kiov[i].kiov_offset;
786                         fragnob = kiov[i].kiov_len;
787                         if (fragnob > sum)
788                                 fragnob = sum;
789
790                         conn->ksnc_rx_csum = ksocknal_csum(conn->ksnc_rx_csum,
791                                                            base, fragnob);
792
793                         kunmap(kiov[i].kiov_page);
794                 }
795         }
796
797         if (addr != NULL) {
798                 ksocknal_lib_kiov_vunmap(addr);
799         } else {
800                 for (i = 0; i < niov; i++)
801                         kunmap(kiov[i].kiov_page);
802         }
803
804         return (rc);
805 }
806
807 void
808 ksocknal_lib_csum_tx(ksock_tx_t *tx)
809 {
810         int          i;
811         __u32        csum;
812         void        *base;
813
814         LASSERT(tx->tx_iov[0].iov_base == (void *)&tx->tx_msg);
815         LASSERT(tx->tx_conn != NULL);
816         LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x);
817
818         tx->tx_msg.ksm_csum = 0;
819
820         csum = ksocknal_csum(~0, (void *)tx->tx_iov[0].iov_base,
821                              tx->tx_iov[0].iov_len);
822
823         if (tx->tx_kiov != NULL) {
824                 for (i = 0; i < tx->tx_nkiov; i++) {
825                         base = kmap(tx->tx_kiov[i].kiov_page) +
826                                tx->tx_kiov[i].kiov_offset;
827
828                         csum = ksocknal_csum(csum, base, tx->tx_kiov[i].kiov_len);
829
830                         kunmap(tx->tx_kiov[i].kiov_page);
831                 }
832         } else {
833                 for (i = 1; i < tx->tx_niov; i++)
834                         csum = ksocknal_csum(csum, tx->tx_iov[i].iov_base,
835                                              tx->tx_iov[i].iov_len);
836         }
837
838         if (*ksocknal_tunables.ksnd_inject_csum_error) {
839                 csum++;
840                 *ksocknal_tunables.ksnd_inject_csum_error = 0;
841         }
842
843         tx->tx_msg.ksm_csum = csum;
844 }
845
846 int
847 ksocknal_lib_get_conn_tunables (ksock_conn_t *conn, int *txmem, int *rxmem, int *nagle)
848 {
849         mm_segment_t   oldmm = get_fs ();
850         struct socket *sock = conn->ksnc_sock;
851         int            len;
852         int            rc;
853
854         rc = ksocknal_connsock_addref(conn);
855         if (rc != 0) {
856                 LASSERT (conn->ksnc_closing);
857                 *txmem = *rxmem = *nagle = 0;
858                 return (-ESHUTDOWN);
859         }
860
861         rc = libcfs_sock_getbuf(sock, txmem, rxmem);
862         if (rc == 0) {
863                 len = sizeof(*nagle);
864                 set_fs(KERNEL_DS);
865                 rc = sock->ops->getsockopt(sock, SOL_TCP, TCP_NODELAY,
866                                            (char *)nagle, &len);
867                 set_fs(oldmm);
868         }
869
870         ksocknal_connsock_decref(conn);
871
872         if (rc == 0)
873                 *nagle = !*nagle;
874         else
875                 *txmem = *rxmem = *nagle = 0;
876
877         return (rc);
878 }
879
880 int
881 ksocknal_lib_setup_sock (struct socket *sock)
882 {
883         mm_segment_t    oldmm = get_fs ();
884         int             rc;
885         int             option;
886         int             keep_idle;
887         int             keep_intvl;
888         int             keep_count;
889         int             do_keepalive;
890         struct linger   linger;
891
892         sock->sk->sk_allocation = GFP_NOFS;
893
894         /* Ensure this socket aborts active sends immediately when we close
895          * it. */
896
897         linger.l_onoff = 0;
898         linger.l_linger = 0;
899
900         set_fs (KERNEL_DS);
901         rc = sock_setsockopt (sock, SOL_SOCKET, SO_LINGER,
902                               (char *)&linger, sizeof (linger));
903         set_fs (oldmm);
904         if (rc != 0) {
905                 CERROR ("Can't set SO_LINGER: %d\n", rc);
906                 return (rc);
907         }
908
909         option = -1;
910         set_fs (KERNEL_DS);
911         rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_LINGER2,
912                                     (char *)&option, sizeof (option));
913         set_fs (oldmm);
914         if (rc != 0) {
915                 CERROR ("Can't set SO_LINGER2: %d\n", rc);
916                 return (rc);
917         }
918
919         if (!*ksocknal_tunables.ksnd_nagle) {
920                 option = 1;
921
922                 set_fs (KERNEL_DS);
923                 rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_NODELAY,
924                                             (char *)&option, sizeof (option));
925                 set_fs (oldmm);
926                 if (rc != 0) {
927                         CERROR ("Can't disable nagle: %d\n", rc);
928                         return (rc);
929                 }
930         }
931
932         rc = libcfs_sock_setbuf(sock,
933                                 *ksocknal_tunables.ksnd_tx_buffer_size,
934                                 *ksocknal_tunables.ksnd_rx_buffer_size);
935         if (rc != 0) {
936                 CERROR ("Can't set buffer tx %d, rx %d buffers: %d\n",
937                         *ksocknal_tunables.ksnd_tx_buffer_size,
938                         *ksocknal_tunables.ksnd_rx_buffer_size, rc);
939                 return (rc);
940         }
941
942 /* TCP_BACKOFF_* sockopt tunables unsupported in stock kernels */
943 #ifdef SOCKNAL_BACKOFF
944         if (*ksocknal_tunables.ksnd_backoff_init > 0) {
945                 option = *ksocknal_tunables.ksnd_backoff_init;
946 #ifdef SOCKNAL_BACKOFF_MS
947                 option *= 1000;
948 #endif
949
950                 set_fs (KERNEL_DS);
951                 rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_BACKOFF_INIT,
952                                             (char *)&option, sizeof (option));
953                 set_fs (oldmm);
954                 if (rc != 0) {
955                         CERROR ("Can't set initial tcp backoff %d: %d\n",
956                                 option, rc);
957                         return (rc);
958                 }
959         }
960
961         if (*ksocknal_tunables.ksnd_backoff_max > 0) {
962                 option = *ksocknal_tunables.ksnd_backoff_max;
963 #ifdef SOCKNAL_BACKOFF_MS
964                 option *= 1000;
965 #endif
966
967                 set_fs (KERNEL_DS);
968                 rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_BACKOFF_MAX,
969                                             (char *)&option, sizeof (option));
970                 set_fs (oldmm);
971                 if (rc != 0) {
972                         CERROR ("Can't set maximum tcp backoff %d: %d\n",
973                                 option, rc);
974                         return (rc);
975                 }
976         }
977 #endif
978
979         /* snapshot tunables */
980         keep_idle  = *ksocknal_tunables.ksnd_keepalive_idle;
981         keep_count = *ksocknal_tunables.ksnd_keepalive_count;
982         keep_intvl = *ksocknal_tunables.ksnd_keepalive_intvl;
983
984         do_keepalive = (keep_idle > 0 && keep_count > 0 && keep_intvl > 0);
985
986         option = (do_keepalive ? 1 : 0);
987         set_fs (KERNEL_DS);
988         rc = sock_setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE,
989                               (char *)&option, sizeof (option));
990         set_fs (oldmm);
991         if (rc != 0) {
992                 CERROR ("Can't set SO_KEEPALIVE: %d\n", rc);
993                 return (rc);
994         }
995
996         if (!do_keepalive)
997                 return (0);
998
999         set_fs (KERNEL_DS);
1000         rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPIDLE,
1001                                     (char *)&keep_idle, sizeof (keep_idle));
1002         set_fs (oldmm);
1003         if (rc != 0) {
1004                 CERROR ("Can't set TCP_KEEPIDLE: %d\n", rc);
1005                 return (rc);
1006         }
1007
1008         set_fs (KERNEL_DS);
1009         rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPINTVL,
1010                                     (char *)&keep_intvl, sizeof (keep_intvl));
1011         set_fs (oldmm);
1012         if (rc != 0) {
1013                 CERROR ("Can't set TCP_KEEPINTVL: %d\n", rc);
1014                 return (rc);
1015         }
1016
1017         set_fs (KERNEL_DS);
1018         rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPCNT,
1019                                     (char *)&keep_count, sizeof (keep_count));
1020         set_fs (oldmm);
1021         if (rc != 0) {
1022                 CERROR ("Can't set TCP_KEEPCNT: %d\n", rc);
1023                 return (rc);
1024         }
1025
1026         return (0);
1027 }
1028
1029 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
1030 struct tcp_opt *sock2tcp_opt(struct sock *sk)
1031 {
1032         return &(sk->tp_pinfo.af_tcp);
1033 }
1034 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))
1035 #define sock2tcp_opt(sk) tcp_sk(sk)
1036 #else
1037 struct tcp_opt *sock2tcp_opt(struct sock *sk)
1038 {
1039         struct tcp_sock *s = (struct tcp_sock *)sk;
1040         return &s->tcp;
1041 }
1042 #endif
1043
1044 void
1045 ksocknal_lib_push_conn (ksock_conn_t *conn)
1046 {
1047         struct sock    *sk;
1048 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11))
1049         struct tcp_opt *tp;
1050 #else
1051         struct tcp_sock *tp;
1052 #endif
1053         int             nonagle;
1054         int             val = 1;
1055         int             rc;
1056         mm_segment_t    oldmm;
1057
1058         rc = ksocknal_connsock_addref(conn);
1059         if (rc != 0)                            /* being shut down */
1060                 return;
1061
1062         sk = conn->ksnc_sock->sk;
1063         tp = sock2tcp_opt(sk);
1064
1065         lock_sock (sk);
1066         nonagle = tp->nonagle;
1067         tp->nonagle = 1;
1068         release_sock (sk);
1069
1070         oldmm = get_fs ();
1071         set_fs (KERNEL_DS);
1072
1073         rc = sk->sk_prot->setsockopt (sk, SOL_TCP, TCP_NODELAY,
1074                                       (char *)&val, sizeof (val));
1075         LASSERT (rc == 0);
1076
1077         set_fs (oldmm);
1078
1079         lock_sock (sk);
1080         tp->nonagle = nonagle;
1081         release_sock (sk);
1082
1083         ksocknal_connsock_decref(conn);
1084 }
1085
1086 extern void ksocknal_read_callback (ksock_conn_t *conn);
1087 extern void ksocknal_write_callback (ksock_conn_t *conn);
1088 /*
1089  * socket call back in Linux
1090  */
1091 static void
1092 ksocknal_data_ready (struct sock *sk, int n)
1093 {
1094         ksock_conn_t  *conn;
1095         ENTRY;
1096
1097         /* interleave correctly with closing sockets... */
1098         LASSERT(!in_irq());
1099         cfs_read_lock (&ksocknal_data.ksnd_global_lock);
1100
1101         conn = sk->sk_user_data;
1102         if (conn == NULL) {             /* raced with ksocknal_terminate_conn */
1103                 LASSERT (sk->sk_data_ready != &ksocknal_data_ready);
1104                 sk->sk_data_ready (sk, n);
1105         } else
1106                 ksocknal_read_callback(conn);
1107
1108         cfs_read_unlock (&ksocknal_data.ksnd_global_lock);
1109
1110         EXIT;
1111 }
1112
1113 static void
1114 ksocknal_write_space (struct sock *sk)
1115 {
1116         ksock_conn_t  *conn;
1117         int            wspace;
1118         int            min_wpace;
1119
1120         /* interleave correctly with closing sockets... */
1121         LASSERT(!in_irq());
1122         cfs_read_lock (&ksocknal_data.ksnd_global_lock);
1123
1124         conn = sk->sk_user_data;
1125         wspace = SOCKNAL_WSPACE(sk);
1126         min_wpace = SOCKNAL_MIN_WSPACE(sk);
1127
1128         CDEBUG(D_NET, "sk %p wspace %d low water %d conn %p%s%s%s\n",
1129                sk, wspace, min_wpace, conn,
1130                (conn == NULL) ? "" : (conn->ksnc_tx_ready ?
1131                                       " ready" : " blocked"),
1132                (conn == NULL) ? "" : (conn->ksnc_tx_scheduled ?
1133                                       " scheduled" : " idle"),
1134                (conn == NULL) ? "" : (list_empty (&conn->ksnc_tx_queue) ?
1135                                       " empty" : " queued"));
1136
1137         if (conn == NULL) {             /* raced with ksocknal_terminate_conn */
1138                 LASSERT (sk->sk_write_space != &ksocknal_write_space);
1139                 sk->sk_write_space (sk);
1140
1141                 cfs_read_unlock (&ksocknal_data.ksnd_global_lock);
1142                 return;
1143         }
1144
1145         if (wspace >= min_wpace) {              /* got enough space */
1146                 ksocknal_write_callback(conn);
1147
1148                 /* Clear SOCK_NOSPACE _after_ ksocknal_write_callback so the
1149                  * ENOMEM check in ksocknal_transmit is race-free (think about
1150                  * it). */
1151
1152                 clear_bit (SOCK_NOSPACE, &sk->sk_socket->flags);
1153         }
1154
1155         cfs_read_unlock (&ksocknal_data.ksnd_global_lock);
1156 }
1157
1158 void
1159 ksocknal_lib_save_callback(struct socket *sock, ksock_conn_t *conn)
1160 {
1161         conn->ksnc_saved_data_ready = sock->sk->sk_data_ready;
1162         conn->ksnc_saved_write_space = sock->sk->sk_write_space;
1163 }
1164
1165 void
1166 ksocknal_lib_set_callback(struct socket *sock,  ksock_conn_t *conn)
1167 {
1168         sock->sk->sk_user_data = conn;
1169         sock->sk->sk_data_ready = ksocknal_data_ready;
1170         sock->sk->sk_write_space = ksocknal_write_space;
1171         return;
1172 }
1173
1174 void
1175 ksocknal_lib_reset_callback(struct socket *sock, ksock_conn_t *conn)
1176 {
1177         /* Remove conn's network callbacks.
1178          * NB I _have_ to restore the callback, rather than storing a noop,
1179          * since the socket could survive past this module being unloaded!! */
1180         sock->sk->sk_data_ready = conn->ksnc_saved_data_ready;
1181         sock->sk->sk_write_space = conn->ksnc_saved_write_space;
1182
1183         /* A callback could be in progress already; they hold a read lock
1184          * on ksnd_global_lock (to serialise with me) and NOOP if
1185          * sk_user_data is NULL. */
1186         sock->sk->sk_user_data = NULL;
1187
1188         return ;
1189 }
1190
1191 int
1192 ksocknal_lib_memory_pressure(ksock_conn_t *conn)
1193 {
1194         int            rc = 0;
1195         ksock_sched_t *sched;
1196         
1197         sched = conn->ksnc_scheduler;
1198         cfs_spin_lock_bh (&sched->kss_lock);
1199         
1200         if (!SOCK_TEST_NOSPACE(conn->ksnc_sock) &&
1201             !conn->ksnc_tx_ready) {
1202                 /* SOCK_NOSPACE is set when the socket fills
1203                  * and cleared in the write_space callback
1204                  * (which also sets ksnc_tx_ready).  If
1205                  * SOCK_NOSPACE and ksnc_tx_ready are BOTH
1206                  * zero, I didn't fill the socket and
1207                  * write_space won't reschedule me, so I
1208                  * return -ENOMEM to get my caller to retry
1209                  * after a timeout */
1210                 rc = -ENOMEM;
1211         }
1212         
1213         cfs_spin_unlock_bh (&sched->kss_lock);
1214
1215         return rc;
1216 }
1217
1218 __u64
1219 ksocknal_lib_new_incarnation(void)
1220 {
1221         struct timeval tv;
1222
1223         /* The incarnation number is the time this module loaded and it
1224          * identifies this particular instance of the socknal.  Hopefully
1225          * we won't be able to reboot more frequently than 1MHz for the
1226          * forseeable future :) */
1227
1228         do_gettimeofday(&tv);
1229
1230         return (((__u64)tv.tv_sec) * 1000000) + tv.tv_usec;
1231 }
1232
1233 int
1234 ksocknal_lib_bind_thread_to_cpu(int id)
1235 {
1236 #if defined(CONFIG_SMP) && defined(CPU_AFFINITY)
1237         id = ksocknal_sched2cpu(id);
1238         if (cpu_online(id)) {
1239                 cpumask_t m = CPU_MASK_NONE;
1240                 cpu_set(id, m);
1241                 set_cpus_allowed(current, m);
1242                 return 0;
1243         }
1244
1245         return -1;
1246
1247 #else
1248         return 0;
1249 #endif
1250 }