Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'nfsd-5.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux

Pull more nfsd updates from Chuck Lever:
"Here are a few additional NFSD commits for the merge window:

Optimization:
- Cork the socket while there are queued replies

Fixes:
- DRC shutdown ordering
- svc_rdma_accept() lockdep splat"

* tag 'nfsd-5.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
SUNRPC: Further clean up svc_tcp_sendmsg()
SUNRPC: Remove redundant socket flags from svc_tcp_sendmsg()
SUNRPC: Use TCP_CORK to optimise send performance on the server
svcrdma: Hold private mutex while invoking rdma_accept()
nfsd: register pernet ops last, unregister first

+29 -28
+7 -7
fs/nfsd/nfsctl.c
··· 1525 1525 int retval; 1526 1526 printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); 1527 1527 1528 - retval = register_pernet_subsys(&nfsd_net_ops); 1529 - if (retval < 0) 1530 - return retval; 1531 1528 retval = register_cld_notifier(); 1532 1529 if (retval) 1533 - goto out_unregister_pernet; 1530 + return retval; 1534 1531 retval = nfsd4_init_slabs(); 1535 1532 if (retval) 1536 1533 goto out_unregister_notifier; ··· 1546 1549 goto out_free_lockd; 1547 1550 retval = register_filesystem(&nfsd_fs_type); 1548 1551 if (retval) 1552 + goto out_free_exports; 1553 + retval = register_pernet_subsys(&nfsd_net_ops); 1554 + if (retval < 0) 1549 1555 goto out_free_all; 1550 1556 return 0; 1551 1557 out_free_all: 1558 + unregister_pernet_subsys(&nfsd_net_ops); 1559 + out_free_exports: 1552 1560 remove_proc_entry("fs/nfs/exports", NULL); 1553 1561 remove_proc_entry("fs/nfs", NULL); 1554 1562 out_free_lockd: ··· 1567 1565 nfsd4_free_slabs(); 1568 1566 out_unregister_notifier: 1569 1567 unregister_cld_notifier(); 1570 - out_unregister_pernet: 1571 - unregister_pernet_subsys(&nfsd_net_ops); 1572 1568 return retval; 1573 1569 } 1574 1570 1575 1571 static void __exit exit_nfsd(void) 1576 1572 { 1573 + unregister_pernet_subsys(&nfsd_net_ops); 1577 1574 nfsd_drc_slab_free(); 1578 1575 remove_proc_entry("fs/nfs/exports", NULL); 1579 1576 remove_proc_entry("fs/nfs", NULL); ··· 1582 1581 nfsd4_exit_pnfs(); 1583 1582 unregister_filesystem(&nfsd_fs_type); 1584 1583 unregister_cld_notifier(); 1585 - unregister_pernet_subsys(&nfsd_net_ops); 1586 1584 } 1587 1585 1588 1586 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
+2
include/linux/sunrpc/svcsock.h
··· 35 35 /* Total length of the data (not including fragment headers) 36 36 * received so far in the fragments making up this rpc: */ 37 37 u32 sk_datalen; 38 + /* Number of queued send requests */ 39 + atomic_t sk_sendqlen; 38 40 39 41 struct page * sk_pages[RPCSVC_MAXPAGES]; /* received data */ 40 42 };
+17 -18
net/sunrpc/svcsock.c
··· 1078 1078 * In addition, the logic assumes that * .bv_len is never larger 1079 1079 * than PAGE_SIZE. 1080 1080 */ 1081 - static int svc_tcp_sendmsg(struct socket *sock, struct msghdr *msg, 1082 - struct xdr_buf *xdr, rpc_fraghdr marker, 1083 - unsigned int *sentp) 1081 + static int svc_tcp_sendmsg(struct socket *sock, struct xdr_buf *xdr, 1082 + rpc_fraghdr marker, unsigned int *sentp) 1084 1083 { 1085 1084 const struct kvec *head = xdr->head; 1086 1085 const struct kvec *tail = xdr->tail; ··· 1087 1088 .iov_base = &marker, 1088 1089 .iov_len = sizeof(marker), 1089 1090 }; 1090 - int flags, ret; 1091 + struct msghdr msg = { 1092 + .msg_flags = 0, 1093 + }; 1094 + int ret; 1091 1095 1092 1096 *sentp = 0; 1093 1097 xdr_alloc_bvec(xdr, GFP_KERNEL); 1094 1098 1095 - msg->msg_flags = MSG_MORE; 1096 - ret = kernel_sendmsg(sock, msg, &rm, 1, rm.iov_len); 1099 + ret = kernel_sendmsg(sock, &msg, &rm, 1, rm.iov_len); 1097 1100 if (ret < 0) 1098 1101 return ret; 1099 1102 *sentp += ret; 1100 1103 if (ret != rm.iov_len) 1101 1104 return -EAGAIN; 1102 1105 1103 - flags = head->iov_len < xdr->len ? MSG_MORE | MSG_SENDPAGE_NOTLAST : 0; 1104 - ret = svc_tcp_send_kvec(sock, head, flags); 1106 + ret = svc_tcp_send_kvec(sock, head, 0); 1105 1107 if (ret < 0) 1106 1108 return ret; 1107 1109 *sentp += ret; ··· 1116 1116 bvec = xdr->bvec + (xdr->page_base >> PAGE_SHIFT); 1117 1117 offset = offset_in_page(xdr->page_base); 1118 1118 remaining = xdr->page_len; 1119 - flags = MSG_MORE | MSG_SENDPAGE_NOTLAST; 1120 1119 while (remaining > 0) { 1121 - if (remaining <= PAGE_SIZE && tail->iov_len == 0) 1122 - flags = 0; 1123 - 1124 1120 len = min(remaining, bvec->bv_len - offset); 1125 1121 ret = kernel_sendpage(sock, bvec->bv_page, 1126 1122 bvec->bv_offset + offset, 1127 - len, flags); 1123 + len, 0); 1128 1124 if (ret < 0) 1129 1125 return ret; 1130 1126 *sentp += ret; ··· 1159 1163 struct xdr_buf *xdr = &rqstp->rq_res; 1160 1164 rpc_fraghdr marker = cpu_to_be32(RPC_LAST_STREAM_FRAGMENT | 1161 1165 (u32)xdr->len); 1162 - struct msghdr msg = { 1163 - .msg_flags = 0, 1164 - }; 1165 1166 unsigned int sent; 1166 1167 int err; 1167 1168 1168 1169 svc_tcp_release_rqst(rqstp); 1169 1170 1171 + atomic_inc(&svsk->sk_sendqlen); 1170 1172 mutex_lock(&xprt->xpt_mutex); 1171 1173 if (svc_xprt_is_dead(xprt)) 1172 1174 goto out_notconn; 1173 - err = svc_tcp_sendmsg(svsk->sk_sock, &msg, xdr, marker, &sent); 1175 + tcp_sock_set_cork(svsk->sk_sk, true); 1176 + err = svc_tcp_sendmsg(svsk->sk_sock, xdr, marker, &sent); 1174 1177 xdr_free_bvec(xdr); 1175 1178 trace_svcsock_tcp_send(xprt, err < 0 ? err : sent); 1176 1179 if (err < 0 || sent != (xdr->len + sizeof(marker))) 1177 1180 goto out_close; 1181 + if (atomic_dec_and_test(&svsk->sk_sendqlen)) 1182 + tcp_sock_set_cork(svsk->sk_sk, false); 1178 1183 mutex_unlock(&xprt->xpt_mutex); 1179 1184 return sent; 1180 1185 1181 1186 out_notconn: 1187 + atomic_dec(&svsk->sk_sendqlen); 1182 1188 mutex_unlock(&xprt->xpt_mutex); 1183 1189 return -ENOTCONN; 1184 1190 out_close: ··· 1190 1192 (err < 0) ? err : sent, xdr->len); 1191 1193 set_bit(XPT_CLOSE, &xprt->xpt_flags); 1192 1194 svc_xprt_enqueue(xprt); 1195 + atomic_dec(&svsk->sk_sendqlen); 1193 1196 mutex_unlock(&xprt->xpt_mutex); 1194 1197 return -EAGAIN; 1195 1198 } ··· 1260 1261 svsk->sk_datalen = 0; 1261 1262 memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages)); 1262 1263 1263 - tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; 1264 + tcp_sock_set_nodelay(sk); 1264 1265 1265 1266 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 1266 1267 switch (sk->sk_state) {
+3 -3
net/sunrpc/xprtrdma/svc_rdma_transport.c
··· 475 475 if (!svc_rdma_post_recvs(newxprt)) 476 476 goto errout; 477 477 478 - /* Swap out the handler */ 479 - newxprt->sc_cm_id->event_handler = svc_rdma_cma_handler; 480 - 481 478 /* Construct RDMA-CM private message */ 482 479 pmsg.cp_magic = rpcrdma_cmp_magic; 483 480 pmsg.cp_version = RPCRDMA_CMP_VERSION; ··· 495 498 } 496 499 conn_param.private_data = &pmsg; 497 500 conn_param.private_data_len = sizeof(pmsg); 501 + rdma_lock_handler(newxprt->sc_cm_id); 502 + newxprt->sc_cm_id->event_handler = svc_rdma_cma_handler; 498 503 ret = rdma_accept(newxprt->sc_cm_id, &conn_param); 504 + rdma_unlock_handler(newxprt->sc_cm_id); 499 505 if (ret) { 500 506 trace_svcrdma_accept_err(newxprt, ret); 501 507 goto errout;