Skip to content

Commit

Permalink
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/dledford/rdma

Pull rdma fixes from Doug Ledford:
 "This is the second batch of queued up rdma patches for this rc cycle.

  There isn't anything really major in here.  It's passed 0day,
  linux-next, and local testing across a wide variety of hardware.
  There are still a few known issues to be tracked down, but this should
  amount to the vast majority of the rdma RC fixes.

  Round two of 4.7 rc fixes:

   - A couple minor fixes to the rdma core
   - Multiple minor fixes to hfi1
   - Multiple minor fixes to mlx4/mlx4
   - A few minor fixes to i40iw"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma: (31 commits)
  IB/srpt: Reduce QP buffer size
  i40iw: Enable level-1 PBL for fast memory registration
  i40iw: Return correct max_fast_reg_page_list_len
  i40iw: Correct status check on i40iw_get_pble
  i40iw: Correct CQ arming
  IB/rdmavt: Correct qp_priv_alloc() return value test
  IB/hfi1: Don't zero out qp->s_ack_queue in rvt_reset_qp
  IB/hfi1: Fix deadlock with txreq allocation slow path
  IB/mlx4: Prevent cross page boundary allocation
  IB/mlx4: Fix memory leak if QP creation failed
  IB/mlx4: Verify port number in flow steering create flow
  IB/mlx4: Fix error flow when sending mads under SRIOV
  IB/mlx4: Fix the SQ size of an RC QP
  IB/mlx5: Fix wrong naming of port_rcv_data counter
  IB/mlx5: Fix post send fence logic
  IB/uverbs: Initialize ib_qp_init_attr with zeros
  IB/core: Fix false search of the IB_SA_WELL_KNOWN_GUID
  IB/core: Fix RoCE v1 multicast join logic issue
  IB/core: Fix no default GIDs when netdevice reregisters
  IB/hfi1: Send a pkey change event on driver pkey update
  ...
  • Loading branch information
Linus Torvalds committed Jun 25, 2016
2 parents 3fb5e59 + 9903fd1 commit aebe9bb
Show file tree
Hide file tree
Showing 30 changed files with 190 additions and 113 deletions.
4 changes: 3 additions & 1 deletion drivers/infiniband/core/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,9 @@ int ib_cache_gid_del_all_netdev_gids(struct ib_device *ib_dev, u8 port,

for (ix = 0; ix < table->sz; ix++)
if (table->data_vec[ix].attr.ndev == ndev)
if (!del_gid(ib_dev, port, table, ix, false))
if (!del_gid(ib_dev, port, table, ix,
!!(table->data_vec[ix].props &
GID_TABLE_ENTRY_DEFAULT)))
deleted = true;

write_unlock_irq(&table->rwlock);
Expand Down
62 changes: 30 additions & 32 deletions drivers/infiniband/core/cma.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,17 +708,6 @@ static void cma_deref_id(struct rdma_id_private *id_priv)
complete(&id_priv->comp);
}

static int cma_disable_callback(struct rdma_id_private *id_priv,
enum rdma_cm_state state)
{
mutex_lock(&id_priv->handler_mutex);
if (id_priv->state != state) {
mutex_unlock(&id_priv->handler_mutex);
return -EINVAL;
}
return 0;
}

struct rdma_cm_id *rdma_create_id(struct net *net,
rdma_cm_event_handler event_handler,
void *context, enum rdma_port_space ps,
Expand Down Expand Up @@ -1671,11 +1660,12 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
struct rdma_cm_event event;
int ret = 0;

mutex_lock(&id_priv->handler_mutex);
if ((ib_event->event != IB_CM_TIMEWAIT_EXIT &&
cma_disable_callback(id_priv, RDMA_CM_CONNECT)) ||
id_priv->state != RDMA_CM_CONNECT) ||
(ib_event->event == IB_CM_TIMEWAIT_EXIT &&
cma_disable_callback(id_priv, RDMA_CM_DISCONNECT)))
return 0;
id_priv->state != RDMA_CM_DISCONNECT))
goto out;

memset(&event, 0, sizeof event);
switch (ib_event->event) {
Expand Down Expand Up @@ -1870,7 +1860,7 @@ static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_e

static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
{
struct rdma_id_private *listen_id, *conn_id;
struct rdma_id_private *listen_id, *conn_id = NULL;
struct rdma_cm_event event;
struct net_device *net_dev;
int offset, ret;
Expand All @@ -1884,9 +1874,10 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
goto net_dev_put;
}

if (cma_disable_callback(listen_id, RDMA_CM_LISTEN)) {
mutex_lock(&listen_id->handler_mutex);
if (listen_id->state != RDMA_CM_LISTEN) {
ret = -ECONNABORTED;
goto net_dev_put;
goto err1;
}

memset(&event, 0, sizeof event);
Expand Down Expand Up @@ -1976,8 +1967,9 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event)
struct sockaddr *laddr = (struct sockaddr *)&iw_event->local_addr;
struct sockaddr *raddr = (struct sockaddr *)&iw_event->remote_addr;

if (cma_disable_callback(id_priv, RDMA_CM_CONNECT))
return 0;
mutex_lock(&id_priv->handler_mutex);
if (id_priv->state != RDMA_CM_CONNECT)
goto out;

memset(&event, 0, sizeof event);
switch (iw_event->event) {
Expand Down Expand Up @@ -2029,6 +2021,7 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event)
return ret;
}

out:
mutex_unlock(&id_priv->handler_mutex);
return ret;
}
Expand All @@ -2039,13 +2032,15 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
struct rdma_cm_id *new_cm_id;
struct rdma_id_private *listen_id, *conn_id;
struct rdma_cm_event event;
int ret;
int ret = -ECONNABORTED;
struct sockaddr *laddr = (struct sockaddr *)&iw_event->local_addr;
struct sockaddr *raddr = (struct sockaddr *)&iw_event->remote_addr;

listen_id = cm_id->context;
if (cma_disable_callback(listen_id, RDMA_CM_LISTEN))
return -ECONNABORTED;

mutex_lock(&listen_id->handler_mutex);
if (listen_id->state != RDMA_CM_LISTEN)
goto out;

/* Create a new RDMA id for the new IW CM ID */
new_cm_id = rdma_create_id(listen_id->id.route.addr.dev_addr.net,
Expand Down Expand Up @@ -3216,8 +3211,9 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id,
struct ib_cm_sidr_rep_event_param *rep = &ib_event->param.sidr_rep_rcvd;
int ret = 0;

if (cma_disable_callback(id_priv, RDMA_CM_CONNECT))
return 0;
mutex_lock(&id_priv->handler_mutex);
if (id_priv->state != RDMA_CM_CONNECT)
goto out;

memset(&event, 0, sizeof event);
switch (ib_event->event) {
Expand Down Expand Up @@ -3673,12 +3669,13 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)
struct rdma_id_private *id_priv;
struct cma_multicast *mc = multicast->context;
struct rdma_cm_event event;
int ret;
int ret = 0;

id_priv = mc->id_priv;
if (cma_disable_callback(id_priv, RDMA_CM_ADDR_BOUND) &&
cma_disable_callback(id_priv, RDMA_CM_ADDR_RESOLVED))
return 0;
mutex_lock(&id_priv->handler_mutex);
if (id_priv->state != RDMA_CM_ADDR_BOUND &&
id_priv->state != RDMA_CM_ADDR_RESOLVED)
goto out;

if (!status)
status = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey));
Expand Down Expand Up @@ -3720,6 +3717,7 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)
return 0;
}

out:
mutex_unlock(&id_priv->handler_mutex);
return 0;
}
Expand Down Expand Up @@ -3878,12 +3876,12 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
gid_type = id_priv->cma_dev->default_gid_type[id_priv->id.port_num -
rdma_start_port(id_priv->cma_dev->device)];
if (addr->sa_family == AF_INET) {
if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) {
mc->multicast.ib->rec.hop_limit = IPV6_DEFAULT_HOPLIMIT;
err = cma_igmp_send(ndev, &mc->multicast.ib->rec.mgid,
true);
if (!err) {
mc->igmp_joined = true;
mc->multicast.ib->rec.hop_limit = IPV6_DEFAULT_HOPLIMIT;
if (!err)
mc->igmp_joined = true;
}
} else {
if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/core/uverbs_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1747,7 +1747,7 @@ static int create_qp(struct ib_uverbs_file *file,
struct ib_srq *srq = NULL;
struct ib_qp *qp;
char *buf;
struct ib_qp_init_attr attr;
struct ib_qp_init_attr attr = {};
struct ib_uverbs_ex_create_qp_resp resp;
int ret;

Expand Down
16 changes: 10 additions & 6 deletions drivers/infiniband/core/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,12 +511,16 @@ int ib_init_ah_from_wc(struct ib_device *device, u8 port_num,
ah_attr->grh.dgid = sgid;

if (!rdma_cap_eth_ah(device, port_num)) {
ret = ib_find_cached_gid_by_port(device, &dgid,
IB_GID_TYPE_IB,
port_num, NULL,
&gid_index);
if (ret)
return ret;
if (dgid.global.interface_id != cpu_to_be64(IB_SA_WELL_KNOWN_GUID)) {
ret = ib_find_cached_gid_by_port(device, &dgid,
IB_GID_TYPE_IB,
port_num, NULL,
&gid_index);
if (ret)
return ret;
} else {
gid_index = 0;
}
}

ah_attr->grh.sgid_index = (u8) gid_index;
Expand Down
28 changes: 20 additions & 8 deletions drivers/infiniband/hw/hfi1/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ static void dc_shutdown(struct hfi1_devdata *);
static void dc_start(struct hfi1_devdata *);
static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp,
unsigned int *np);
static void remove_full_mgmt_pkey(struct hfi1_pportdata *ppd);
static void clear_full_mgmt_pkey(struct hfi1_pportdata *ppd);

/*
* Error interrupt table entry. This is used as input to the interrupt
Expand Down Expand Up @@ -6962,8 +6962,6 @@ void handle_link_down(struct work_struct *work)
}

reset_neighbor_info(ppd);
if (ppd->mgmt_allowed)
remove_full_mgmt_pkey(ppd);

/* disable the port */
clear_rcvctrl(ppd->dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK);
Expand Down Expand Up @@ -7070,12 +7068,16 @@ static void add_full_mgmt_pkey(struct hfi1_pportdata *ppd)
__func__, ppd->pkeys[2], FULL_MGMT_P_KEY);
ppd->pkeys[2] = FULL_MGMT_P_KEY;
(void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0);
hfi1_event_pkey_change(ppd->dd, ppd->port);
}

static void remove_full_mgmt_pkey(struct hfi1_pportdata *ppd)
static void clear_full_mgmt_pkey(struct hfi1_pportdata *ppd)
{
ppd->pkeys[2] = 0;
(void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0);
if (ppd->pkeys[2] != 0) {
ppd->pkeys[2] = 0;
(void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0);
hfi1_event_pkey_change(ppd->dd, ppd->port);
}
}

/*
Expand Down Expand Up @@ -9168,6 +9170,13 @@ int start_link(struct hfi1_pportdata *ppd)
return 0;
}

/*
* FULL_MGMT_P_KEY is cleared from the pkey table, so that the
* pkey table can be configured properly if the HFI unit is connected
* to switch port with MgmtAllowed=NO
*/
clear_full_mgmt_pkey(ppd);

return set_link_state(ppd, HLS_DN_POLL);
}

Expand Down Expand Up @@ -9777,7 +9786,7 @@ static void set_send_length(struct hfi1_pportdata *ppd)
u64 len1 = 0, len2 = (((dd->vld[15].mtu + max_hb) >> 2)
& SEND_LEN_CHECK1_LEN_VL15_MASK) <<
SEND_LEN_CHECK1_LEN_VL15_SHIFT;
int i;
int i, j;
u32 thres;

for (i = 0; i < ppd->vls_supported; i++) {
Expand All @@ -9801,7 +9810,10 @@ static void set_send_length(struct hfi1_pportdata *ppd)
sc_mtu_to_threshold(dd->vld[i].sc,
dd->vld[i].mtu,
dd->rcd[0]->rcvhdrqentsize));
sc_set_cr_threshold(dd->vld[i].sc, thres);
for (j = 0; j < INIT_SC_PER_VL; j++)
sc_set_cr_threshold(
pio_select_send_context_vl(dd, j, i),
thres);
}
thres = min(sc_percent_to_threshold(dd->vld[15].sc, 50),
sc_mtu_to_threshold(dd->vld[15].sc,
Expand Down
3 changes: 3 additions & 0 deletions drivers/infiniband/hw/hfi1/file_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,

switch (cmd) {
case HFI1_IOCTL_ASSIGN_CTXT:
if (uctxt)
return -EINVAL;

if (copy_from_user(&uinfo,
(struct hfi1_user_info __user *)arg,
sizeof(uinfo)))
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/hfi1/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1383,7 +1383,7 @@ static void postinit_cleanup(struct hfi1_devdata *dd)
static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int ret = 0, j, pidx, initfail;
struct hfi1_devdata *dd = NULL;
struct hfi1_devdata *dd = ERR_PTR(-EINVAL);
struct hfi1_pportdata *ppd;

/* First, lock the non-writable module parameters */
Expand Down
19 changes: 12 additions & 7 deletions drivers/infiniband/hw/hfi1/mad.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ static inline void clear_opa_smp_data(struct opa_smp *smp)
memset(data, 0, size);
}

void hfi1_event_pkey_change(struct hfi1_devdata *dd, u8 port)
{
struct ib_event event;

event.event = IB_EVENT_PKEY_CHANGE;
event.device = &dd->verbs_dev.rdi.ibdev;
event.element.port_num = port;
ib_dispatch_event(&event);
}

static void send_trap(struct hfi1_ibport *ibp, void *data, unsigned len)
{
struct ib_mad_send_buf *send_buf;
Expand Down Expand Up @@ -1418,15 +1428,10 @@ static int set_pkeys(struct hfi1_devdata *dd, u8 port, u16 *pkeys)
}

if (changed) {
struct ib_event event;

(void)hfi1_set_ib_cfg(ppd, HFI1_IB_CFG_PKEYS, 0);

event.event = IB_EVENT_PKEY_CHANGE;
event.device = &dd->verbs_dev.rdi.ibdev;
event.element.port_num = port;
ib_dispatch_event(&event);
hfi1_event_pkey_change(dd, port);
}

return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/infiniband/hw/hfi1/mad.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,4 +434,6 @@ struct sc2vlnt {
COUNTER_MASK(1, 3) | \
COUNTER_MASK(1, 4))

void hfi1_event_pkey_change(struct hfi1_devdata *dd, u8 port);

#endif /* _HFI1_MAD_H */
26 changes: 23 additions & 3 deletions drivers/infiniband/hw/hfi1/pio.c
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,7 @@ static void sc_wait_for_packet_egress(struct send_context *sc, int pause)
/* counter is reset if occupancy count changes */
if (reg != reg_prev)
loop = 0;
if (loop > 500) {
if (loop > 50000) {
/* timed out - bounce the link */
dd_dev_err(dd,
"%s: context %u(%u) timeout waiting for packets to egress, remaining count %u, bouncing link\n",
Expand Down Expand Up @@ -1797,6 +1797,21 @@ static void pio_map_rcu_callback(struct rcu_head *list)
pio_map_free(m);
}

/*
* Set credit return threshold for the kernel send context
*/
static void set_threshold(struct hfi1_devdata *dd, int scontext, int i)
{
u32 thres;

thres = min(sc_percent_to_threshold(dd->kernel_send_context[scontext],
50),
sc_mtu_to_threshold(dd->kernel_send_context[scontext],
dd->vld[i].mtu,
dd->rcd[0]->rcvhdrqentsize));
sc_set_cr_threshold(dd->kernel_send_context[scontext], thres);
}

/*
* pio_map_init - called when #vls change
* @dd: hfi1_devdata
Expand Down Expand Up @@ -1872,11 +1887,16 @@ int pio_map_init(struct hfi1_devdata *dd, u8 port, u8 num_vls, u8 *vl_scontexts)
if (!newmap->map[i])
goto bail;
newmap->map[i]->mask = (1 << ilog2(sz)) - 1;
/* assign send contexts */
/*
* assign send contexts and
* adjust credit return threshold
*/
for (j = 0; j < sz; j++) {
if (dd->kernel_send_context[scontext])
if (dd->kernel_send_context[scontext]) {
newmap->map[i]->ksc[j] =
dd->kernel_send_context[scontext];
set_threshold(dd, scontext, i);
}
if (++scontext >= first_scontext +
vl_scontexts[i])
/* wrap back to first send context */
Expand Down
3 changes: 2 additions & 1 deletion drivers/infiniband/hw/hfi1/qsfp.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,8 @@ int qsfp_dump(struct hfi1_pportdata *ppd, char *buf, int len)

if (ppd->qsfp_info.cache_valid) {
if (QSFP_IS_CU(cache[QSFP_MOD_TECH_OFFS]))
sprintf(lenstr, "%dM ", cache[QSFP_MOD_LEN_OFFS]);
snprintf(lenstr, sizeof(lenstr), "%dM ",
cache[QSFP_MOD_LEN_OFFS]);

power_byte = cache[QSFP_MOD_PWR_OFFS];
sofar += scnprintf(buf + sofar, len - sofar, "PWR:%.3sW\n",
Expand Down
Loading

0 comments on commit aebe9bb

Please sign in to comment.