Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
Pull base rdma updates from Doug Ledford: "Round one of 4.8 code: while this is mostly normal, there is a new driver in here (the driver was hosted outside the kernel for several years and is actually a fairly mature and well coded driver). It amounts to 13,000 of the 16,000 lines of added code in here. Summary: - Updates/fixes for iw_cxgb4 driver - Updates/fixes for mlx5 driver - Add flow steering and RSS API - Add hardware stats to mlx4 and mlx5 drivers - Add firmware version API for RDMA driver use - Add the rxe driver (this is a software RoCE driver that makes any Ethernet device a RoCE device) - Fixes for i40iw driver - Support for send only multicast joins in the cma layer - Other minor fixes" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma: (72 commits) Soft RoCE driver IB/core: Support for CMA multicast join flags IB/sa: Add cached attribute containing SM information to SA port IB/uverbs: Fix race between uverbs_close and remove_one IB/mthca: Clean up error unwind flow in mthca_reset() IB/mthca: NULL arg to pci_dev_put is OK IB/hfi1: NULL arg to sc_return_credits is OK IB/mlx4: Add diagnostic hardware counters net/mlx4: Query performance and diagnostics counters net/mlx4: Add diagnostic counters capability bit Use smaller 512 byte messages for portmapper messages IB/ipoib: Report SG feature regardless of HW UD CSUM capability IB/mlx4: Don't use GFP_ATOMIC for CQ resize struct IB/hfi1: Disable by default IB/rdmavt: Disable by default IB/mlx5: Fix port counter ID association to QP offset IB/mlx5: Fix iteration overrun in GSI qps i40iw: Add NULL check for puda buffer i40iw: Change dup_ack_thresh to u8 i40iw: Remove unnecessary check for moving CQ head ...
Dieser Commit ist enthalten in:
@@ -1567,12 +1567,12 @@ static enum i40iw_status_code i40iw_del_multiple_qhash(
|
||||
ret = i40iw_manage_qhash(iwdev, cm_info,
|
||||
I40IW_QHASH_TYPE_TCP_SYN,
|
||||
I40IW_QHASH_MANAGE_TYPE_DELETE, NULL, false);
|
||||
kfree(child_listen_node);
|
||||
cm_parent_listen_node->cm_core->stats_listen_nodes_destroyed++;
|
||||
i40iw_debug(&iwdev->sc_dev,
|
||||
I40IW_DEBUG_CM,
|
||||
"freed pointer = %p\n",
|
||||
child_listen_node);
|
||||
kfree(child_listen_node);
|
||||
cm_parent_listen_node->cm_core->stats_listen_nodes_destroyed++;
|
||||
}
|
||||
spin_unlock_irqrestore(&iwdev->cm_core.listen_list_lock, flags);
|
||||
|
||||
|
@@ -1557,6 +1557,9 @@ enum i40iw_alignment {
|
||||
#define I40IW_RING_MOVE_TAIL(_ring) \
|
||||
(_ring).tail = ((_ring).tail + 1) % (_ring).size
|
||||
|
||||
#define I40IW_RING_MOVE_HEAD_NOCHECK(_ring) \
|
||||
(_ring).head = ((_ring).head + 1) % (_ring).size
|
||||
|
||||
#define I40IW_RING_MOVE_TAIL_BY_COUNT(_ring, _count) \
|
||||
(_ring).tail = ((_ring).tail + (_count)) % (_ring).size
|
||||
|
||||
|
@@ -1025,6 +1025,8 @@ static void i40iw_ieq_compl_pfpdu(struct i40iw_puda_rsrc *ieq,
|
||||
u16 txoffset, bufoffset;
|
||||
|
||||
buf = i40iw_puda_get_listbuf(pbufl);
|
||||
if (!buf)
|
||||
return;
|
||||
nextseqnum = buf->seqnum + fpdu_len;
|
||||
txbuf->totallen = buf->hdrlen + fpdu_len;
|
||||
txbuf->data = (u8 *)txbuf->mem.va + buf->hdrlen;
|
||||
@@ -1048,6 +1050,8 @@ static void i40iw_ieq_compl_pfpdu(struct i40iw_puda_rsrc *ieq,
|
||||
fpdu_len -= buf->datalen;
|
||||
i40iw_puda_ret_bufpool(ieq, buf);
|
||||
buf = i40iw_puda_get_listbuf(pbufl);
|
||||
if (!buf)
|
||||
return;
|
||||
bufoffset = (u16)(buf->data - (u8 *)buf->mem.va);
|
||||
} while (1);
|
||||
|
||||
|
@@ -667,7 +667,7 @@ struct i40iw_tcp_offload_info {
|
||||
bool time_stamp;
|
||||
u8 cwnd_inc_limit;
|
||||
bool drop_ooo_seg;
|
||||
bool dup_ack_thresh;
|
||||
u8 dup_ack_thresh;
|
||||
u8 ttl;
|
||||
u8 src_mac_addr_idx;
|
||||
bool avoid_stretch_ack;
|
||||
|
@@ -291,9 +291,9 @@ static enum i40iw_status_code i40iw_rdma_write(struct i40iw_qp_uk *qp,
|
||||
|
||||
i40iw_set_fragment(wqe, 0, op_info->lo_sg_list);
|
||||
|
||||
for (i = 1; i < op_info->num_lo_sges; i++) {
|
||||
byte_off = 32 + (i - 1) * 16;
|
||||
for (i = 1, byte_off = 32; i < op_info->num_lo_sges; i++) {
|
||||
i40iw_set_fragment(wqe, byte_off, &op_info->lo_sg_list[i]);
|
||||
byte_off += 16;
|
||||
}
|
||||
|
||||
wmb(); /* make sure WQE is populated before valid bit is set */
|
||||
@@ -401,9 +401,9 @@ static enum i40iw_status_code i40iw_send(struct i40iw_qp_uk *qp,
|
||||
|
||||
i40iw_set_fragment(wqe, 0, op_info->sg_list);
|
||||
|
||||
for (i = 1; i < op_info->num_sges; i++) {
|
||||
byte_off = 32 + (i - 1) * 16;
|
||||
for (i = 1, byte_off = 32; i < op_info->num_sges; i++) {
|
||||
i40iw_set_fragment(wqe, byte_off, &op_info->sg_list[i]);
|
||||
byte_off += 16;
|
||||
}
|
||||
|
||||
wmb(); /* make sure WQE is populated before valid bit is set */
|
||||
@@ -685,9 +685,9 @@ static enum i40iw_status_code i40iw_post_receive(struct i40iw_qp_uk *qp,
|
||||
|
||||
i40iw_set_fragment(wqe, 0, info->sg_list);
|
||||
|
||||
for (i = 1; i < info->num_sges; i++) {
|
||||
byte_off = 32 + (i - 1) * 16;
|
||||
for (i = 1, byte_off = 32; i < info->num_sges; i++) {
|
||||
i40iw_set_fragment(wqe, byte_off, &info->sg_list[i]);
|
||||
byte_off += 16;
|
||||
}
|
||||
|
||||
wmb(); /* make sure WQE is populated before valid bit is set */
|
||||
@@ -753,8 +753,7 @@ static enum i40iw_status_code i40iw_cq_post_entries(struct i40iw_cq_uk *cq,
|
||||
* @post_cq: update cq tail
|
||||
*/
|
||||
static enum i40iw_status_code i40iw_cq_poll_completion(struct i40iw_cq_uk *cq,
|
||||
struct i40iw_cq_poll_info *info,
|
||||
bool post_cq)
|
||||
struct i40iw_cq_poll_info *info)
|
||||
{
|
||||
u64 comp_ctx, qword0, qword2, qword3, wqe_qword;
|
||||
u64 *cqe, *sw_wqe;
|
||||
@@ -762,7 +761,6 @@ static enum i40iw_status_code i40iw_cq_poll_completion(struct i40iw_cq_uk *cq,
|
||||
struct i40iw_ring *pring = NULL;
|
||||
u32 wqe_idx, q_type, array_idx = 0;
|
||||
enum i40iw_status_code ret_code = 0;
|
||||
enum i40iw_status_code ret_code2 = 0;
|
||||
bool move_cq_head = true;
|
||||
u8 polarity;
|
||||
u8 addl_wqes = 0;
|
||||
@@ -870,19 +868,14 @@ exit:
|
||||
move_cq_head = false;
|
||||
|
||||
if (move_cq_head) {
|
||||
I40IW_RING_MOVE_HEAD(cq->cq_ring, ret_code2);
|
||||
|
||||
if (ret_code2 && !ret_code)
|
||||
ret_code = ret_code2;
|
||||
I40IW_RING_MOVE_HEAD_NOCHECK(cq->cq_ring);
|
||||
|
||||
if (I40IW_RING_GETCURRENT_HEAD(cq->cq_ring) == 0)
|
||||
cq->polarity ^= 1;
|
||||
|
||||
if (post_cq) {
|
||||
I40IW_RING_MOVE_TAIL(cq->cq_ring);
|
||||
set_64bit_val(cq->shadow_area, 0,
|
||||
I40IW_RING_GETCURRENT_HEAD(cq->cq_ring));
|
||||
}
|
||||
I40IW_RING_MOVE_TAIL(cq->cq_ring);
|
||||
set_64bit_val(cq->shadow_area, 0,
|
||||
I40IW_RING_GETCURRENT_HEAD(cq->cq_ring));
|
||||
} else {
|
||||
if (info->is_srq)
|
||||
return ret_code;
|
||||
|
@@ -327,7 +327,7 @@ struct i40iw_cq_ops {
|
||||
void (*iw_cq_request_notification)(struct i40iw_cq_uk *,
|
||||
enum i40iw_completion_notify);
|
||||
enum i40iw_status_code (*iw_cq_poll_completion)(struct i40iw_cq_uk *,
|
||||
struct i40iw_cq_poll_info *, bool);
|
||||
struct i40iw_cq_poll_info *);
|
||||
enum i40iw_status_code (*iw_cq_post_entries)(struct i40iw_cq_uk *, u8 count);
|
||||
void (*iw_cq_clean)(void *, struct i40iw_cq_uk *);
|
||||
};
|
||||
|
@@ -529,7 +529,7 @@ static int i40iw_setup_kmode_qp(struct i40iw_device *iwdev,
|
||||
status = i40iw_get_wqe_shift(rq_size, ukinfo->max_rq_frag_cnt, 0, &rqshift);
|
||||
|
||||
if (status)
|
||||
return -ENOSYS;
|
||||
return -ENOMEM;
|
||||
|
||||
sqdepth = sq_size << sqshift;
|
||||
rqdepth = rq_size << rqshift;
|
||||
@@ -671,7 +671,7 @@ static struct ib_qp *i40iw_create_qp(struct ib_pd *ibpd,
|
||||
iwqp->ctx_info.qp_compl_ctx = (uintptr_t)qp;
|
||||
|
||||
if (init_attr->qp_type != IB_QPT_RC) {
|
||||
err_code = -ENOSYS;
|
||||
err_code = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
if (iwdev->push_mode)
|
||||
@@ -1840,6 +1840,7 @@ struct ib_mr *i40iw_reg_phys_mr(struct ib_pd *pd,
|
||||
iwmr->ibmr.lkey = stag;
|
||||
iwmr->page_cnt = 1;
|
||||
iwmr->pgaddrmem[0] = addr;
|
||||
iwmr->length = size;
|
||||
status = i40iw_hwreg_mr(iwdev, iwmr, access);
|
||||
if (status) {
|
||||
i40iw_free_stag(iwdev, stag);
|
||||
@@ -1863,7 +1864,7 @@ static struct ib_mr *i40iw_get_dma_mr(struct ib_pd *pd, int acc)
|
||||
{
|
||||
u64 kva = 0;
|
||||
|
||||
return i40iw_reg_phys_mr(pd, 0, 0xffffffffffULL, acc, &kva);
|
||||
return i40iw_reg_phys_mr(pd, 0, 0, acc, &kva);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1974,18 +1975,6 @@ static ssize_t i40iw_show_rev(struct device *dev,
|
||||
return sprintf(buf, "%x\n", hw_rev);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40iw_show_fw_ver
|
||||
*/
|
||||
static ssize_t i40iw_show_fw_ver(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
u32 firmware_version = I40IW_FW_VERSION;
|
||||
|
||||
return sprintf(buf, "%u.%u\n", firmware_version,
|
||||
(firmware_version & 0x000000ff));
|
||||
}
|
||||
|
||||
/**
|
||||
* i40iw_show_hca
|
||||
*/
|
||||
@@ -2006,13 +1995,11 @@ static ssize_t i40iw_show_board(struct device *dev,
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(hw_rev, S_IRUGO, i40iw_show_rev, NULL);
|
||||
static DEVICE_ATTR(fw_ver, S_IRUGO, i40iw_show_fw_ver, NULL);
|
||||
static DEVICE_ATTR(hca_type, S_IRUGO, i40iw_show_hca, NULL);
|
||||
static DEVICE_ATTR(board_id, S_IRUGO, i40iw_show_board, NULL);
|
||||
|
||||
static struct device_attribute *i40iw_dev_attributes[] = {
|
||||
&dev_attr_hw_rev,
|
||||
&dev_attr_fw_ver,
|
||||
&dev_attr_hca_type,
|
||||
&dev_attr_board_id
|
||||
};
|
||||
@@ -2091,8 +2078,12 @@ static int i40iw_post_send(struct ib_qp *ibqp,
|
||||
ret = ukqp->ops.iw_send(ukqp, &info, ib_wr->ex.invalidate_rkey, false);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
err = -EIO;
|
||||
if (ret) {
|
||||
if (ret == I40IW_ERR_QP_TOOMANY_WRS_POSTED)
|
||||
err = -ENOMEM;
|
||||
else
|
||||
err = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case IB_WR_RDMA_WRITE:
|
||||
info.op_type = I40IW_OP_TYPE_RDMA_WRITE;
|
||||
@@ -2113,8 +2104,12 @@ static int i40iw_post_send(struct ib_qp *ibqp,
|
||||
ret = ukqp->ops.iw_rdma_write(ukqp, &info, false);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
err = -EIO;
|
||||
if (ret) {
|
||||
if (ret == I40IW_ERR_QP_TOOMANY_WRS_POSTED)
|
||||
err = -ENOMEM;
|
||||
else
|
||||
err = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case IB_WR_RDMA_READ_WITH_INV:
|
||||
inv_stag = true;
|
||||
@@ -2132,15 +2127,19 @@ static int i40iw_post_send(struct ib_qp *ibqp,
|
||||
info.op.rdma_read.lo_addr.stag = ib_wr->sg_list->lkey;
|
||||
info.op.rdma_read.lo_addr.len = ib_wr->sg_list->length;
|
||||
ret = ukqp->ops.iw_rdma_read(ukqp, &info, inv_stag, false);
|
||||
if (ret)
|
||||
err = -EIO;
|
||||
if (ret) {
|
||||
if (ret == I40IW_ERR_QP_TOOMANY_WRS_POSTED)
|
||||
err = -ENOMEM;
|
||||
else
|
||||
err = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case IB_WR_LOCAL_INV:
|
||||
info.op_type = I40IW_OP_TYPE_INV_STAG;
|
||||
info.op.inv_local_stag.target_stag = ib_wr->ex.invalidate_rkey;
|
||||
ret = ukqp->ops.iw_stag_local_invalidate(ukqp, &info, true);
|
||||
if (ret)
|
||||
err = -EIO;
|
||||
err = -ENOMEM;
|
||||
break;
|
||||
case IB_WR_REG_MR:
|
||||
{
|
||||
@@ -2174,7 +2173,7 @@ static int i40iw_post_send(struct ib_qp *ibqp,
|
||||
|
||||
ret = dev->iw_priv_qp_ops->iw_mr_fast_register(&iwqp->sc_qp, &info, true);
|
||||
if (ret)
|
||||
err = -EIO;
|
||||
err = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -2214,6 +2213,7 @@ static int i40iw_post_recv(struct ib_qp *ibqp,
|
||||
struct i40iw_sge sg_list[I40IW_MAX_WQ_FRAGMENT_COUNT];
|
||||
enum i40iw_status_code ret = 0;
|
||||
unsigned long flags;
|
||||
int err = 0;
|
||||
|
||||
iwqp = (struct i40iw_qp *)ibqp;
|
||||
ukqp = &iwqp->sc_qp.qp_uk;
|
||||
@@ -2228,6 +2228,10 @@ static int i40iw_post_recv(struct ib_qp *ibqp,
|
||||
ret = ukqp->ops.iw_post_receive(ukqp, &post_recv);
|
||||
if (ret) {
|
||||
i40iw_pr_err(" post_recv err %d\n", ret);
|
||||
if (ret == I40IW_ERR_QP_TOOMANY_WRS_POSTED)
|
||||
err = -ENOMEM;
|
||||
else
|
||||
err = -EINVAL;
|
||||
*bad_wr = ib_wr;
|
||||
goto out;
|
||||
}
|
||||
@@ -2235,9 +2239,7 @@ static int i40iw_post_recv(struct ib_qp *ibqp,
|
||||
}
|
||||
out:
|
||||
spin_unlock_irqrestore(&iwqp->lock, flags);
|
||||
if (ret)
|
||||
return -ENOSYS;
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2264,7 +2266,7 @@ static int i40iw_poll_cq(struct ib_cq *ibcq,
|
||||
|
||||
spin_lock_irqsave(&iwcq->lock, flags);
|
||||
while (cqe_count < num_entries) {
|
||||
ret = ukcq->ops.iw_cq_poll_completion(ukcq, &cq_poll_info, true);
|
||||
ret = ukcq->ops.iw_cq_poll_completion(ukcq, &cq_poll_info);
|
||||
if (ret == I40IW_ERR_QUEUE_EMPTY) {
|
||||
break;
|
||||
} else if (ret == I40IW_ERR_QUEUE_DESTROYED) {
|
||||
@@ -2437,6 +2439,15 @@ static const char * const i40iw_hw_stat_names[] = {
|
||||
"iwRdmaInv"
|
||||
};
|
||||
|
||||
static void i40iw_get_dev_fw_str(struct ib_device *dev, char *str,
|
||||
size_t str_len)
|
||||
{
|
||||
u32 firmware_version = I40IW_FW_VERSION;
|
||||
|
||||
snprintf(str, str_len, "%u.%u", firmware_version,
|
||||
(firmware_version & 0x000000ff));
|
||||
}
|
||||
|
||||
/**
|
||||
* i40iw_alloc_hw_stats - Allocate a hw stats structure
|
||||
* @ibdev: device pointer from stack
|
||||
@@ -2528,7 +2539,7 @@ static int i40iw_modify_port(struct ib_device *ibdev,
|
||||
int port_modify_mask,
|
||||
struct ib_port_modify *props)
|
||||
{
|
||||
return 0;
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2660,6 +2671,7 @@ static struct i40iw_ib_device *i40iw_init_rdma_device(struct i40iw_device *iwdev
|
||||
memcpy(iwibdev->ibdev.iwcm->ifname, netdev->name,
|
||||
sizeof(iwibdev->ibdev.iwcm->ifname));
|
||||
iwibdev->ibdev.get_port_immutable = i40iw_port_immutable;
|
||||
iwibdev->ibdev.get_dev_fw_str = i40iw_get_dev_fw_str;
|
||||
iwibdev->ibdev.poll_cq = i40iw_poll_cq;
|
||||
iwibdev->ibdev.req_notify_cq = i40iw_req_notify_cq;
|
||||
iwibdev->ibdev.post_send = i40iw_post_send;
|
||||
@@ -2723,7 +2735,7 @@ int i40iw_register_rdma_device(struct i40iw_device *iwdev)
|
||||
|
||||
iwdev->iwibdev = i40iw_init_rdma_device(iwdev);
|
||||
if (!iwdev->iwibdev)
|
||||
return -ENOSYS;
|
||||
return -ENOMEM;
|
||||
iwibdev = iwdev->iwibdev;
|
||||
|
||||
ret = ib_register_device(&iwibdev->ibdev, NULL);
|
||||
@@ -2748,5 +2760,5 @@ error:
|
||||
kfree(iwdev->iwibdev->ibdev.iwcm);
|
||||
iwdev->iwibdev->ibdev.iwcm = NULL;
|
||||
ib_dealloc_device(&iwdev->iwibdev->ibdev);
|
||||
return -ENOSYS;
|
||||
return ret;
|
||||
}
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren