|
36 | 36 | #include <linux/skbuff.h> |
37 | 37 | #include <linux/file.h> |
38 | 38 | #include <linux/freezer.h> |
| 39 | +#include <linux/bvec.h> |
| 40 | + |
39 | 41 | #include <net/sock.h> |
40 | 42 | #include <net/checksum.h> |
41 | 43 | #include <net/ip.h> |
@@ -1194,77 +1196,52 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) |
1194 | 1196 | return 0; /* record not complete */ |
1195 | 1197 | } |
1196 | 1198 |
|
1197 | | -static int svc_tcp_send_kvec(struct socket *sock, const struct kvec *vec, |
1198 | | - int flags) |
1199 | | -{ |
1200 | | - struct msghdr msg = { .msg_flags = MSG_SPLICE_PAGES | flags, }; |
1201 | | - |
1202 | | - iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, vec, 1, vec->iov_len); |
1203 | | - return sock_sendmsg(sock, &msg); |
1204 | | -} |
1205 | | - |
1206 | 1199 | /* |
1207 | 1200 | * MSG_SPLICE_PAGES is used exclusively to reduce the number of |
1208 | 1201 | * copy operations in this path. Therefore the caller must ensure |
1209 | 1202 | * that the pages backing @xdr are unchanging. |
1210 | 1203 | * |
1211 | | - * In addition, the logic assumes that * .bv_len is never larger |
1212 | | - * than PAGE_SIZE. |
| 1204 | + * Note that the send is non-blocking. The caller has incremented |
| 1205 | + * the reference count on each page backing the RPC message, and |
| 1206 | + * the network layer will "put" these pages when transmission is |
| 1207 | + * complete. |
| 1208 | + * |
| 1209 | + * This is safe for our RPC services because the memory backing |
| 1210 | + * the head and tail components is never kmalloc'd. These always |
| 1211 | + * come from pages in the svc_rqst::rq_pages array. |
1213 | 1212 | */ |
1214 | | -static int svc_tcp_sendmsg(struct socket *sock, struct xdr_buf *xdr, |
| 1213 | +static int svc_tcp_sendmsg(struct svc_sock *svsk, struct svc_rqst *rqstp, |
1215 | 1214 | rpc_fraghdr marker, unsigned int *sentp) |
1216 | 1215 | { |
1217 | | - const struct kvec *head = xdr->head; |
1218 | | - const struct kvec *tail = xdr->tail; |
1219 | 1216 | struct kvec rm = { |
1220 | 1217 | .iov_base = &marker, |
1221 | 1218 | .iov_len = sizeof(marker), |
1222 | 1219 | }; |
1223 | 1220 | struct msghdr msg = { |
1224 | | - .msg_flags = 0, |
| 1221 | + .msg_flags = MSG_MORE, |
1225 | 1222 | }; |
| 1223 | + unsigned int count; |
1226 | 1224 | int ret; |
1227 | 1225 |
|
1228 | 1226 | *sentp = 0; |
1229 | | - ret = xdr_alloc_bvec(xdr, GFP_KERNEL); |
1230 | | - if (ret < 0) |
1231 | | - return ret; |
1232 | 1227 |
|
1233 | | - ret = kernel_sendmsg(sock, &msg, &rm, 1, rm.iov_len); |
| 1228 | + ret = kernel_sendmsg(svsk->sk_sock, &msg, &rm, 1, rm.iov_len); |
1234 | 1229 | if (ret < 0) |
1235 | 1230 | return ret; |
1236 | 1231 | *sentp += ret; |
1237 | 1232 | if (ret != rm.iov_len) |
1238 | 1233 | return -EAGAIN; |
1239 | 1234 |
|
1240 | | - ret = svc_tcp_send_kvec(sock, head, 0); |
1241 | | - if (ret < 0) |
1242 | | - return ret; |
1243 | | - *sentp += ret; |
1244 | | - if (ret != head->iov_len) |
1245 | | - goto out; |
1246 | | - |
1247 | | - if (xdr_buf_pagecount(xdr)) { |
1248 | | - xdr->bvec[0].bv_offset = offset_in_page(xdr->page_base); |
1249 | | - xdr->bvec[0].bv_len -= offset_in_page(xdr->page_base); |
1250 | | - } |
| 1235 | + count = xdr_buf_to_bvec(rqstp->rq_bvec, ARRAY_SIZE(rqstp->rq_bvec), |
| 1236 | + &rqstp->rq_res); |
1251 | 1237 |
|
1252 | 1238 | msg.msg_flags = MSG_SPLICE_PAGES; |
1253 | | - iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, xdr->bvec, |
1254 | | - xdr_buf_pagecount(xdr), xdr->page_len); |
1255 | | - ret = sock_sendmsg(sock, &msg); |
| 1239 | + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, rqstp->rq_bvec, |
| 1240 | + count, rqstp->rq_res.len); |
| 1241 | + ret = sock_sendmsg(svsk->sk_sock, &msg); |
1256 | 1242 | if (ret < 0) |
1257 | 1243 | return ret; |
1258 | 1244 | *sentp += ret; |
1259 | | - |
1260 | | - if (tail->iov_len) { |
1261 | | - ret = svc_tcp_send_kvec(sock, tail, 0); |
1262 | | - if (ret < 0) |
1263 | | - return ret; |
1264 | | - *sentp += ret; |
1265 | | - } |
1266 | | - |
1267 | | -out: |
1268 | 1245 | return 0; |
1269 | 1246 | } |
1270 | 1247 |
|
@@ -1295,8 +1272,7 @@ static int svc_tcp_sendto(struct svc_rqst *rqstp) |
1295 | 1272 | if (svc_xprt_is_dead(xprt)) |
1296 | 1273 | goto out_notconn; |
1297 | 1274 | tcp_sock_set_cork(svsk->sk_sk, true); |
1298 | | - err = svc_tcp_sendmsg(svsk->sk_sock, xdr, marker, &sent); |
1299 | | - xdr_free_bvec(xdr); |
| 1275 | + err = svc_tcp_sendmsg(svsk, rqstp, marker, &sent); |
1300 | 1276 | trace_svcsock_tcp_send(xprt, err < 0 ? (long)err : sent); |
1301 | 1277 | if (err < 0 || sent != (xdr->len + sizeof(marker))) |
1302 | 1278 | goto out_close; |
|
0 commit comments