summaryrefslogtreecommitdiffstats
path: root/net/rds/send.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rds/send.c')
-rw-r--r--net/rds/send.c61
1 files changed, 50 insertions, 11 deletions
diff --git a/net/rds/send.c b/net/rds/send.c
index fe785ee819dd..3d822bad7de9 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -876,13 +876,18 @@ out:
876 * rds_message is getting to be quite complicated, and we'd like to allocate 876 * rds_message is getting to be quite complicated, and we'd like to allocate
877 * it all in one go. This figures out how big it needs to be up front. 877 * it all in one go. This figures out how big it needs to be up front.
878 */ 878 */
879static int rds_rm_size(struct msghdr *msg, int num_sgs) 879static int rds_rm_size(struct msghdr *msg, int num_sgs,
880 struct rds_iov_vector_arr *vct)
880{ 881{
881 struct cmsghdr *cmsg; 882 struct cmsghdr *cmsg;
882 int size = 0; 883 int size = 0;
883 int cmsg_groups = 0; 884 int cmsg_groups = 0;
884 int retval; 885 int retval;
885 bool zcopy_cookie = false; 886 bool zcopy_cookie = false;
887 struct rds_iov_vector *iov, *tmp_iov;
888
889 if (num_sgs < 0)
890 return -EINVAL;
886 891
887 for_each_cmsghdr(cmsg, msg) { 892 for_each_cmsghdr(cmsg, msg) {
888 if (!CMSG_OK(msg, cmsg)) 893 if (!CMSG_OK(msg, cmsg))
@@ -893,8 +898,24 @@ static int rds_rm_size(struct msghdr *msg, int num_sgs)
893 898
894 switch (cmsg->cmsg_type) { 899 switch (cmsg->cmsg_type) {
895 case RDS_CMSG_RDMA_ARGS: 900 case RDS_CMSG_RDMA_ARGS:
901 if (vct->indx >= vct->len) {
902 vct->len += vct->incr;
903 tmp_iov =
904 krealloc(vct->vec,
905 vct->len *
906 sizeof(struct rds_iov_vector),
907 GFP_KERNEL);
908 if (!tmp_iov) {
909 vct->len -= vct->incr;
910 return -ENOMEM;
911 }
912 vct->vec = tmp_iov;
913 }
914 iov = &vct->vec[vct->indx];
915 memset(iov, 0, sizeof(struct rds_iov_vector));
916 vct->indx++;
896 cmsg_groups |= 1; 917 cmsg_groups |= 1;
897 retval = rds_rdma_extra_size(CMSG_DATA(cmsg)); 918 retval = rds_rdma_extra_size(CMSG_DATA(cmsg), iov);
898 if (retval < 0) 919 if (retval < 0)
899 return retval; 920 return retval;
900 size += retval; 921 size += retval;
@@ -951,10 +972,11 @@ static int rds_cmsg_zcopy(struct rds_sock *rs, struct rds_message *rm,
951} 972}
952 973
953static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm, 974static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm,
954 struct msghdr *msg, int *allocated_mr) 975 struct msghdr *msg, int *allocated_mr,
976 struct rds_iov_vector_arr *vct)
955{ 977{
956 struct cmsghdr *cmsg; 978 struct cmsghdr *cmsg;
957 int ret = 0; 979 int ret = 0, ind = 0;
958 980
959 for_each_cmsghdr(cmsg, msg) { 981 for_each_cmsghdr(cmsg, msg) {
960 if (!CMSG_OK(msg, cmsg)) 982 if (!CMSG_OK(msg, cmsg))
@@ -968,7 +990,10 @@ static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm,
968 */ 990 */
969 switch (cmsg->cmsg_type) { 991 switch (cmsg->cmsg_type) {
970 case RDS_CMSG_RDMA_ARGS: 992 case RDS_CMSG_RDMA_ARGS:
971 ret = rds_cmsg_rdma_args(rs, rm, cmsg); 993 if (ind >= vct->indx)
994 return -ENOMEM;
995 ret = rds_cmsg_rdma_args(rs, rm, cmsg, &vct->vec[ind]);
996 ind++;
972 break; 997 break;
973 998
974 case RDS_CMSG_RDMA_DEST: 999 case RDS_CMSG_RDMA_DEST:
@@ -1084,6 +1109,13 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
1084 sock_flag(rds_rs_to_sk(rs), SOCK_ZEROCOPY)); 1109 sock_flag(rds_rs_to_sk(rs), SOCK_ZEROCOPY));
1085 int num_sgs = ceil(payload_len, PAGE_SIZE); 1110 int num_sgs = ceil(payload_len, PAGE_SIZE);
1086 int namelen; 1111 int namelen;
1112 struct rds_iov_vector_arr vct;
1113 int ind;
1114
1115 memset(&vct, 0, sizeof(vct));
1116
1117 /* expect 1 RDMA CMSG per rds_sendmsg. can still grow if more needed. */
1118 vct.incr = 1;
1087 1119
1088 /* Mirror Linux UDP mirror of BSD error message compatibility */ 1120 /* Mirror Linux UDP mirror of BSD error message compatibility */
1089 /* XXX: Perhaps MSG_MORE someday */ 1121 /* XXX: Perhaps MSG_MORE someday */
@@ -1220,7 +1252,7 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
1220 num_sgs = iov_iter_npages(&msg->msg_iter, INT_MAX); 1252 num_sgs = iov_iter_npages(&msg->msg_iter, INT_MAX);
1221 } 1253 }
1222 /* size of rm including all sgs */ 1254 /* size of rm including all sgs */
1223 ret = rds_rm_size(msg, num_sgs); 1255 ret = rds_rm_size(msg, num_sgs, &vct);
1224 if (ret < 0) 1256 if (ret < 0)
1225 goto out; 1257 goto out;
1226 1258
@@ -1232,11 +1264,9 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
1232 1264
1233 /* Attach data to the rm */ 1265 /* Attach data to the rm */
1234 if (payload_len) { 1266 if (payload_len) {
1235 rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs); 1267 rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs, &ret);
1236 if (!rm->data.op_sg) { 1268 if (!rm->data.op_sg)
1237 ret = -ENOMEM;
1238 goto out; 1269 goto out;
1239 }
1240 ret = rds_message_copy_from_user(rm, &msg->msg_iter, zcopy); 1270 ret = rds_message_copy_from_user(rm, &msg->msg_iter, zcopy);
1241 if (ret) 1271 if (ret)
1242 goto out; 1272 goto out;
@@ -1270,7 +1300,7 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
1270 rm->m_conn_path = cpath; 1300 rm->m_conn_path = cpath;
1271 1301
1272 /* Parse any control messages the user may have included. */ 1302 /* Parse any control messages the user may have included. */
1273 ret = rds_cmsg_send(rs, rm, msg, &allocated_mr); 1303 ret = rds_cmsg_send(rs, rm, msg, &allocated_mr, &vct);
1274 if (ret) { 1304 if (ret) {
1275 /* Trigger connection so that its ready for the next retry */ 1305 /* Trigger connection so that its ready for the next retry */
1276 if (ret == -EAGAIN) 1306 if (ret == -EAGAIN)
@@ -1348,9 +1378,18 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
1348 if (ret) 1378 if (ret)
1349 goto out; 1379 goto out;
1350 rds_message_put(rm); 1380 rds_message_put(rm);
1381
1382 for (ind = 0; ind < vct.indx; ind++)
1383 kfree(vct.vec[ind].iov);
1384 kfree(vct.vec);
1385
1351 return payload_len; 1386 return payload_len;
1352 1387
1353out: 1388out:
1389 for (ind = 0; ind < vct.indx; ind++)
1390 kfree(vct.vec[ind].iov);
1391 kfree(vct.vec);
1392
1354 /* If the user included a RDMA_MAP cmsg, we allocated a MR on the fly. 1393 /* If the user included a RDMA_MAP cmsg, we allocated a MR on the fly.
1355 * If the sendmsg goes through, we keep the MR. If it fails with EAGAIN 1394 * If the sendmsg goes through, we keep the MR. If it fails with EAGAIN
1356 * or in any other way, we need to destroy the MR again */ 1395 * or in any other way, we need to destroy the MR again */