| .. | .. |
|---|
| 145 | 145 | LIST_HEAD(to_be_dropped); |
|---|
| 146 | 146 | int batch_count; |
|---|
| 147 | 147 | unsigned long send_gen = 0; |
|---|
| 148 | + int same_rm = 0; |
|---|
| 148 | 149 | |
|---|
| 149 | 150 | restart: |
|---|
| 150 | 151 | batch_count = 0; |
|---|
| .. | .. |
|---|
| 199 | 200 | while (1) { |
|---|
| 200 | 201 | |
|---|
| 201 | 202 | rm = cp->cp_xmit_rm; |
|---|
| 203 | + |
|---|
| 204 | + if (!rm) { |
|---|
| 205 | + same_rm = 0; |
|---|
| 206 | + } else { |
|---|
| 207 | + same_rm++; |
|---|
| 208 | + if (same_rm >= 4096) { |
|---|
| 209 | + rds_stats_inc(s_send_stuck_rm); |
|---|
| 210 | + ret = -EAGAIN; |
|---|
| 211 | + break; |
|---|
| 212 | + } |
|---|
| 213 | + } |
|---|
| 202 | 214 | |
|---|
| 203 | 215 | /* |
|---|
| 204 | 216 | * If between sending messages, we can send a pending congestion |
|---|
| .. | .. |
|---|
| 491 | 503 | struct rm_rdma_op *ro; |
|---|
| 492 | 504 | struct rds_notifier *notifier; |
|---|
| 493 | 505 | unsigned long flags; |
|---|
| 494 | | - unsigned int notify = 0; |
|---|
| 495 | 506 | |
|---|
| 496 | 507 | spin_lock_irqsave(&rm->m_rs_lock, flags); |
|---|
| 497 | 508 | |
|---|
| 498 | | - notify = rm->rdma.op_notify | rm->data.op_notify; |
|---|
| 499 | 509 | ro = &rm->rdma; |
|---|
| 500 | 510 | if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) && |
|---|
| 501 | | - ro->op_active && notify && ro->op_notifier) { |
|---|
| 511 | + ro->op_active && ro->op_notify && ro->op_notifier) { |
|---|
| 502 | 512 | notifier = ro->op_notifier; |
|---|
| 503 | 513 | rs = rm->m_rs; |
|---|
| 504 | 514 | sock_hold(rds_rs_to_sk(rs)); |
|---|
| .. | .. |
|---|
| 886 | 896 | bool zcopy_cookie = false; |
|---|
| 887 | 897 | struct rds_iov_vector *iov, *tmp_iov; |
|---|
| 888 | 898 | |
|---|
| 899 | + if (num_sgs < 0) |
|---|
| 900 | + return -EINVAL; |
|---|
| 901 | + |
|---|
| 889 | 902 | for_each_cmsghdr(cmsg, msg) { |
|---|
| 890 | 903 | if (!CMSG_OK(msg, cmsg)) |
|---|
| 891 | 904 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 921 | 934 | |
|---|
| 922 | 935 | case RDS_CMSG_ZCOPY_COOKIE: |
|---|
| 923 | 936 | zcopy_cookie = true; |
|---|
| 924 | | - /* fall through */ |
|---|
| 937 | + fallthrough; |
|---|
| 925 | 938 | |
|---|
| 926 | 939 | case RDS_CMSG_RDMA_DEST: |
|---|
| 927 | 940 | case RDS_CMSG_RDMA_MAP: |
|---|
| .. | .. |
|---|
| 1104 | 1117 | size_t total_payload_len = payload_len, rdma_payload_len = 0; |
|---|
| 1105 | 1118 | bool zcopy = ((msg->msg_flags & MSG_ZEROCOPY) && |
|---|
| 1106 | 1119 | sock_flag(rds_rs_to_sk(rs), SOCK_ZEROCOPY)); |
|---|
| 1107 | | - int num_sgs = ceil(payload_len, PAGE_SIZE); |
|---|
| 1120 | + int num_sgs = DIV_ROUND_UP(payload_len, PAGE_SIZE); |
|---|
| 1108 | 1121 | int namelen; |
|---|
| 1109 | 1122 | struct rds_iov_vector_arr vct; |
|---|
| 1110 | 1123 | int ind; |
|---|
| .. | .. |
|---|
| 1131 | 1144 | case AF_INET: |
|---|
| 1132 | 1145 | if (usin->sin_addr.s_addr == htonl(INADDR_ANY) || |
|---|
| 1133 | 1146 | usin->sin_addr.s_addr == htonl(INADDR_BROADCAST) || |
|---|
| 1134 | | - IN_MULTICAST(ntohl(usin->sin_addr.s_addr))) { |
|---|
| 1147 | + ipv4_is_multicast(usin->sin_addr.s_addr)) { |
|---|
| 1135 | 1148 | ret = -EINVAL; |
|---|
| 1136 | 1149 | goto out; |
|---|
| 1137 | 1150 | } |
|---|
| .. | .. |
|---|
| 1162 | 1175 | addr4 = sin6->sin6_addr.s6_addr32[3]; |
|---|
| 1163 | 1176 | if (addr4 == htonl(INADDR_ANY) || |
|---|
| 1164 | 1177 | addr4 == htonl(INADDR_BROADCAST) || |
|---|
| 1165 | | - IN_MULTICAST(ntohl(addr4))) { |
|---|
| 1178 | + ipv4_is_multicast(addr4)) { |
|---|
| 1166 | 1179 | ret = -EINVAL; |
|---|
| 1167 | 1180 | goto out; |
|---|
| 1168 | 1181 | } |
|---|
| .. | .. |
|---|
| 1262 | 1275 | /* Attach data to the rm */ |
|---|
| 1263 | 1276 | if (payload_len) { |
|---|
| 1264 | 1277 | rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs); |
|---|
| 1265 | | - if (!rm->data.op_sg) { |
|---|
| 1266 | | - ret = -ENOMEM; |
|---|
| 1278 | + if (IS_ERR(rm->data.op_sg)) { |
|---|
| 1279 | + ret = PTR_ERR(rm->data.op_sg); |
|---|
| 1267 | 1280 | goto out; |
|---|
| 1268 | 1281 | } |
|---|
| 1269 | 1282 | ret = rds_message_copy_from_user(rm, &msg->msg_iter, zcopy); |
|---|
| .. | .. |
|---|
| 1276 | 1289 | |
|---|
| 1277 | 1290 | /* rds_conn_create has a spinlock that runs with IRQ off. |
|---|
| 1278 | 1291 | * Caching the conn in the socket helps a lot. */ |
|---|
| 1279 | | - if (rs->rs_conn && ipv6_addr_equal(&rs->rs_conn->c_faddr, &daddr)) |
|---|
| 1292 | + if (rs->rs_conn && ipv6_addr_equal(&rs->rs_conn->c_faddr, &daddr) && |
|---|
| 1293 | + rs->rs_tos == rs->rs_conn->c_tos) { |
|---|
| 1280 | 1294 | conn = rs->rs_conn; |
|---|
| 1281 | | - else { |
|---|
| 1295 | + } else { |
|---|
| 1282 | 1296 | conn = rds_conn_create_outgoing(sock_net(sock->sk), |
|---|
| 1283 | 1297 | &rs->rs_bound_addr, &daddr, |
|---|
| 1284 | | - rs->rs_transport, |
|---|
| 1298 | + rs->rs_transport, rs->rs_tos, |
|---|
| 1285 | 1299 | sock->sk->sk_allocation, |
|---|
| 1286 | 1300 | scope_id); |
|---|
| 1287 | 1301 | if (IS_ERR(conn)) { |
|---|
| .. | .. |
|---|
| 1326 | 1340 | goto out; |
|---|
| 1327 | 1341 | } |
|---|
| 1328 | 1342 | |
|---|
| 1329 | | - rds_conn_path_connect_if_down(cpath); |
|---|
| 1343 | + if (rds_conn_path_down(cpath)) |
|---|
| 1344 | + rds_check_all_paths(conn); |
|---|
| 1330 | 1345 | |
|---|
| 1331 | 1346 | ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs); |
|---|
| 1332 | 1347 | if (ret) { |
|---|