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

IB/mthca: max_inline_data handling tweaks

Fix a case where copying max_inline_data from a successful create_qp
capabilities output to create_qp input could cause EINVAL error:

mthca_set_qp_size must check max_inline_data directly against
max_desc_sz; checking qp->sq.max_gs is wrong since max_inline_data
depends on the qp type and does not involve max_sg.

Signed-off-by: Jack Morgenstein <jackm@mellanox.co.il>
Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>

authored by

Jack Morgenstein and committed by
Roland Dreier
5b3bc7a6 46620056

+36 -26
+36 -26
drivers/infiniband/hw/mthca/mthca_qp.c
··· 890 890 return err; 891 891 } 892 892 893 - static void mthca_adjust_qp_caps(struct mthca_dev *dev, 894 - struct mthca_pd *pd, 895 - struct mthca_qp *qp) 893 + static int mthca_max_data_size(struct mthca_dev *dev, struct mthca_qp *qp, int desc_sz) 896 894 { 897 - int max_data_size; 898 - 899 895 /* 900 896 * Calculate the maximum size of WQE s/g segments, excluding 901 897 * the next segment and other non-data segments. 902 898 */ 903 - max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) - 904 - sizeof (struct mthca_next_seg); 899 + int max_data_size = desc_sz - sizeof (struct mthca_next_seg); 905 900 906 901 switch (qp->transport) { 907 902 case MLX: ··· 915 920 break; 916 921 } 917 922 923 + return max_data_size; 924 + } 925 + 926 + static inline int mthca_max_inline_data(struct mthca_pd *pd, int max_data_size) 927 + { 918 928 /* We don't support inline data for kernel QPs (yet). */ 919 - if (!pd->ibpd.uobject) 920 - qp->max_inline_data = 0; 921 - else 922 - qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE; 929 + return pd->ibpd.uobject ? max_data_size - MTHCA_INLINE_HEADER_SIZE : 0; 930 + } 931 + 932 + static void mthca_adjust_qp_caps(struct mthca_dev *dev, 933 + struct mthca_pd *pd, 934 + struct mthca_qp *qp) 935 + { 936 + int max_data_size = mthca_max_data_size(dev, qp, 937 + min(dev->limits.max_desc_sz, 938 + 1 << qp->sq.wqe_shift)); 939 + 940 + qp->max_inline_data = mthca_max_inline_data(pd, max_data_size); 923 941 924 942 qp->sq.max_gs = min_t(int, dev->limits.max_sg, 925 943 max_data_size / sizeof (struct mthca_data_seg)); ··· 1199 1191 } 1200 1192 1201 1193 static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap, 1202 - struct mthca_qp *qp) 1194 + struct mthca_pd *pd, struct mthca_qp *qp) 1203 1195 { 1196 + int max_data_size = mthca_max_data_size(dev, qp, dev->limits.max_desc_sz); 1197 + 1204 1198 /* Sanity check QP size before proceeding */ 1205 - if (cap->max_send_wr > dev->limits.max_wqes || 1206 - cap->max_recv_wr > dev->limits.max_wqes || 1207 - cap->max_send_sge > dev->limits.max_sg || 1208 - cap->max_recv_sge > dev->limits.max_sg) 1199 + if (cap->max_send_wr > dev->limits.max_wqes || 1200 + cap->max_recv_wr > dev->limits.max_wqes || 1201 + cap->max_send_sge > dev->limits.max_sg || 1202 + cap->max_recv_sge > dev->limits.max_sg || 1203 + cap->max_inline_data > mthca_max_inline_data(pd, max_data_size)) 1204 + return -EINVAL; 1205 + 1206 + /* 1207 + * For MLX transport we need 2 extra S/G entries: 1208 + * one for the header and one for the checksum at the end 1209 + */ 1210 + if (qp->transport == MLX && cap->max_recv_sge + 2 > dev->limits.max_sg) 1209 1211 return -EINVAL; 1210 1212 1211 1213 if (mthca_is_memfree(dev)) { ··· 1234 1216 MTHCA_INLINE_CHUNK_SIZE) / 1235 1217 sizeof (struct mthca_data_seg)); 1236 1218 1237 - /* 1238 - * For MLX transport we need 2 extra S/G entries: 1239 - * one for the header and one for the checksum at the end 1240 - */ 1241 - if ((qp->transport == MLX && qp->sq.max_gs + 2 > dev->limits.max_sg) || 1242 - qp->sq.max_gs > dev->limits.max_sg || qp->rq.max_gs > dev->limits.max_sg) 1243 - return -EINVAL; 1244 - 1245 1219 return 0; 1246 1220 } 1247 1221 ··· 1248 1238 { 1249 1239 int err; 1250 1240 1251 - err = mthca_set_qp_size(dev, cap, qp); 1241 + err = mthca_set_qp_size(dev, cap, pd, qp); 1252 1242 if (err) 1253 1243 return err; 1254 1244 ··· 1291 1281 u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1; 1292 1282 int err; 1293 1283 1294 - err = mthca_set_qp_size(dev, cap, &sqp->qp); 1284 + err = mthca_set_qp_size(dev, cap, pd, &sqp->qp); 1295 1285 if (err) 1296 1286 return err; 1297 1287