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:
 "Round one of 4.8 rc fixes.

  This should be the bulk of the -rc fixes for 4.8.  I only have a few
  things that are still outstanding (two ipoib bugs for which the
  solution is not yet fully known, and a few queued items that came in
  after my last push and I didn't want to delay this pull request for
  late comers again).

  Even though the patch count is kind of high, everything is minor fixes
  so the overall churn is pretty low.

  Summary:

   - minor fixes to cxgb4
   - minor fixes to mlx4
   - one minor fix each to core, rxe, isert, srpt, mlx5, ocrdma, and usnic
   - six or so fixes to i40iw fixes
   - the rest are hfi1 fixes"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma: (34 commits)
  i40iw: Send last streaming mode message for loopback connections
  IB/srpt: Update sport->port_guid with each port refresh
  RDMA/ocrdma: Fix the max_sge reported from FW
  i40iw: Avoid writing to freed memory
  i40iw: Fix double free of allocated_buffer
  IB/mlx5: Remove superfluous include of io-mapping.h
  i40iw: Do not set self-referencing pointer to NULL after kfree
  i40iw: Add missing NULL check for MPA private data
  iw_cxgb4: Fix cxgb4 arm CQ logic w/IB_CQ_REPORT_MISSED_EVENTS
  i40iw: Add missing check for interface already open
  i40iw: Protect req_resource_num update
  i40iw: Change mem_resources pointer to a u8
  IB/core: Use memdup_user() rather than duplicating its implementation
  IB/qib: Use memdup_user() rather than duplicating its implementation
  iw_cxgb4: use the MPA initiator's IRD if < our ORD
  iw_cxgb4: limit IRD/ORD advertised to ULP by device max.
  IB/hfi1: Fix mm_struct use after free
  IB/rdmvat: Fix double vfree() in rvt_create_qp() error path
  IB/hfi1: Improve J_KEY generation
  IB/hfi1: Return invalid field for non-QSFP CableInfo queries
  ...
  • Loading branch information
torvalds committed Aug 27, 2016
2 parents 03cef71 + 049b1e7 commit a3d3469
Show file tree
Hide file tree
Showing 33 changed files with 185 additions and 145 deletions.
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -7661,7 +7661,7 @@ L: [email protected]
S: Supported
W: https://github.com/SoftRoCE/rxe-dev/wiki/rxe-dev:-Home
Q: http://patchwork.kernel.org/project/linux-rdma/list/
F: drivers/infiniband/hw/rxe/
F: drivers/infiniband/sw/rxe/
F: include/uapi/rdma/rdma_user_rxe.h

MEMBARRIER SUPPORT
Expand Down
18 changes: 12 additions & 6 deletions drivers/infiniband/core/cma.c
Original file line number Diff line number Diff line change
Expand Up @@ -2462,18 +2462,24 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)

if (addr->dev_addr.bound_dev_if) {
ndev = dev_get_by_index(&init_net, addr->dev_addr.bound_dev_if);
if (!ndev)
return -ENODEV;
if (!ndev) {
ret = -ENODEV;
goto err2;
}

if (ndev->flags & IFF_LOOPBACK) {
dev_put(ndev);
if (!id_priv->id.device->get_netdev)
return -EOPNOTSUPP;
if (!id_priv->id.device->get_netdev) {
ret = -EOPNOTSUPP;
goto err2;
}

ndev = id_priv->id.device->get_netdev(id_priv->id.device,
id_priv->id.port_num);
if (!ndev)
return -ENODEV;
if (!ndev) {
ret = -ENODEV;
goto err2;
}
}

route->path_rec->net = &init_net;
Expand Down
6 changes: 5 additions & 1 deletion drivers/infiniband/hw/cxgb4/cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1827,8 +1827,12 @@ static int process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
(ep->mpa_pkt + sizeof(*mpa));
ep->ird = ntohs(mpa_v2_params->ird) &
MPA_V2_IRD_ORD_MASK;
ep->ird = min_t(u32, ep->ird,
cur_max_read_depth(ep->com.dev));
ep->ord = ntohs(mpa_v2_params->ord) &
MPA_V2_IRD_ORD_MASK;
ep->ord = min_t(u32, ep->ord,
cur_max_read_depth(ep->com.dev));
PDBG("%s initiator ird %u ord %u\n", __func__, ep->ird,
ep->ord);
if (ntohs(mpa_v2_params->ird) & MPA_V2_PEER2PEER_MODEL)
Expand Down Expand Up @@ -3136,7 +3140,7 @@ int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) {
if (conn_param->ord > ep->ird) {
if (RELAXED_IRD_NEGOTIATION) {
ep->ord = ep->ird;
conn_param->ord = ep->ird;
} else {
ep->ird = conn_param->ird;
ep->ord = conn_param->ord;
Expand Down
10 changes: 5 additions & 5 deletions drivers/infiniband/hw/cxgb4/cq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1016,15 +1016,15 @@ int c4iw_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata)
int c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
{
struct c4iw_cq *chp;
int ret;
int ret = 0;
unsigned long flag;

chp = to_c4iw_cq(ibcq);
spin_lock_irqsave(&chp->lock, flag);
ret = t4_arm_cq(&chp->cq,
(flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED);
t4_arm_cq(&chp->cq,
(flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED);
if (flags & IB_CQ_REPORT_MISSED_EVENTS)
ret = t4_cq_notempty(&chp->cq);
spin_unlock_irqrestore(&chp->lock, flag);
if (ret && !(flags & IB_CQ_REPORT_MISSED_EVENTS))
ret = 0;
return ret;
}
5 changes: 5 additions & 0 deletions drivers/infiniband/hw/cxgb4/t4.h
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,11 @@ static inline int t4_valid_cqe(struct t4_cq *cq, struct t4_cqe *cqe)
return (CQE_GENBIT(cqe) == cq->gen);
}

static inline int t4_cq_notempty(struct t4_cq *cq)
{
return cq->sw_in_use || t4_valid_cqe(cq, &cq->queue[cq->cidx]);
}

static inline int t4_next_hw_cqe(struct t4_cq *cq, struct t4_cqe **cqe)
{
int ret;
Expand Down
21 changes: 13 additions & 8 deletions drivers/infiniband/hw/hfi1/affinity.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
#include <linux/topology.h>
#include <linux/cpumask.h>
#include <linux/module.h>
#include <linux/cpumask.h>

#include "hfi.h"
#include "affinity.h"
Expand Down Expand Up @@ -682,7 +681,7 @@ int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf,
size_t count)
{
struct hfi1_affinity_node *entry;
struct cpumask mask;
cpumask_var_t mask;
int ret, i;

spin_lock(&node_affinity.lock);
Expand All @@ -692,19 +691,24 @@ int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf,
if (!entry)
return -EINVAL;

ret = cpulist_parse(buf, &mask);
ret = zalloc_cpumask_var(&mask, GFP_KERNEL);
if (!ret)
return -ENOMEM;

ret = cpulist_parse(buf, mask);
if (ret)
return ret;
goto out;

if (!cpumask_subset(&mask, cpu_online_mask) || cpumask_empty(&mask)) {
if (!cpumask_subset(mask, cpu_online_mask) || cpumask_empty(mask)) {
dd_dev_warn(dd, "Invalid CPU mask\n");
return -EINVAL;
ret = -EINVAL;
goto out;
}

mutex_lock(&sdma_affinity_mutex);
/* reset the SDMA interrupt affinity details */
init_cpu_mask_set(&entry->def_intr);
cpumask_copy(&entry->def_intr.mask, &mask);
cpumask_copy(&entry->def_intr.mask, mask);
/*
* Reassign the affinity for each SDMA interrupt.
*/
Expand All @@ -720,8 +724,9 @@ int hfi1_set_sdma_affinity(struct hfi1_devdata *dd, const char *buf,
if (ret)
break;
}

mutex_unlock(&sdma_affinity_mutex);
out:
free_cpumask_var(mask);
return ret ? ret : strnlen(buf, PAGE_SIZE);
}

Expand Down
14 changes: 9 additions & 5 deletions drivers/infiniband/hw/hfi1/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,28 +223,32 @@ DEBUGFS_SEQ_FILE_OPEN(ctx_stats)
DEBUGFS_FILE_OPS(ctx_stats);

static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
__acquires(RCU)
__acquires(RCU)
{
struct qp_iter *iter;
loff_t n = *pos;

rcu_read_lock();
iter = qp_iter_init(s->private);

/* stop calls rcu_read_unlock */
rcu_read_lock();

if (!iter)
return NULL;

while (n--) {
do {
if (qp_iter_next(iter)) {
kfree(iter);
return NULL;
}
}
} while (n--);

return iter;
}

static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr,
loff_t *pos)
__must_hold(RCU)
{
struct qp_iter *iter = iter_ptr;

Expand All @@ -259,7 +263,7 @@ static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr,
}

static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr)
__releases(RCU)
__releases(RCU)
{
rcu_read_unlock();
}
Expand Down
11 changes: 6 additions & 5 deletions drivers/infiniband/hw/hfi1/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,14 +888,15 @@ void set_all_slowpath(struct hfi1_devdata *dd)
}

static inline int set_armed_to_active(struct hfi1_ctxtdata *rcd,
struct hfi1_packet packet,
struct hfi1_packet *packet,
struct hfi1_devdata *dd)
{
struct work_struct *lsaw = &rcd->ppd->linkstate_active_work;
struct hfi1_message_header *hdr = hfi1_get_msgheader(packet.rcd->dd,
packet.rhf_addr);
struct hfi1_message_header *hdr = hfi1_get_msgheader(packet->rcd->dd,
packet->rhf_addr);
u8 etype = rhf_rcv_type(packet->rhf);

if (hdr2sc(hdr, packet.rhf) != 0xf) {
if (etype == RHF_RCV_TYPE_IB && hdr2sc(hdr, packet->rhf) != 0xf) {
int hwstate = read_logical_state(dd);

if (hwstate != LSTATE_ACTIVE) {
Expand Down Expand Up @@ -979,7 +980,7 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread)
/* Auto activate link on non-SC15 packet receive */
if (unlikely(rcd->ppd->host_link_state ==
HLS_UP_ARMED) &&
set_armed_to_active(rcd, packet, dd))
set_armed_to_active(rcd, &packet, dd))
goto bail;
last = process_rcv_packet(&packet, thread);
}
Expand Down
4 changes: 3 additions & 1 deletion drivers/infiniband/hw/hfi1/file_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp)
if (fd) {
fd->rec_cpu_num = -1; /* no cpu affinity by default */
fd->mm = current->mm;
atomic_inc(&fd->mm->mm_count);
}

fp->private_data = fd;
Expand Down Expand Up @@ -222,7 +223,7 @@ static long hfi1_file_ioctl(struct file *fp, unsigned int cmd,
ret = assign_ctxt(fp, &uinfo);
if (ret < 0)
return ret;
setup_ctxt(fp);
ret = setup_ctxt(fp);
if (ret)
return ret;
ret = user_init(fp);
Expand Down Expand Up @@ -779,6 +780,7 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)
mutex_unlock(&hfi1_mutex);
hfi1_free_ctxtdata(dd, uctxt);
done:
mmdrop(fdata->mm);
kobject_put(&dd->kobj);
kfree(fdata);
return 0;
Expand Down
20 changes: 18 additions & 2 deletions drivers/infiniband/hw/hfi1/hfi.h
Original file line number Diff line number Diff line change
Expand Up @@ -1272,9 +1272,26 @@ static inline int hdr2sc(struct hfi1_message_header *hdr, u64 rhf)
((!!(rhf_dc_info(rhf))) << 4);
}

#define HFI1_JKEY_WIDTH 16
#define HFI1_JKEY_MASK (BIT(16) - 1)
#define HFI1_ADMIN_JKEY_RANGE 32

/*
* J_KEYs are split and allocated in the following groups:
* 0 - 31 - users with administrator privileges
* 32 - 63 - kernel protocols using KDETH packets
* 64 - 65535 - all other users using KDETH packets
*/
static inline u16 generate_jkey(kuid_t uid)
{
return from_kuid(current_user_ns(), uid) & 0xffff;
u16 jkey = from_kuid(current_user_ns(), uid) & HFI1_JKEY_MASK;

if (capable(CAP_SYS_ADMIN))
jkey &= HFI1_ADMIN_JKEY_RANGE - 1;
else if (jkey < 64)
jkey |= BIT(HFI1_JKEY_WIDTH - 1);

return jkey;
}

/*
Expand Down Expand Up @@ -1656,7 +1673,6 @@ struct cc_state *get_cc_state_protected(struct hfi1_pportdata *ppd)
struct hfi1_devdata *hfi1_init_dd(struct pci_dev *,
const struct pci_device_id *);
void hfi1_free_devdata(struct hfi1_devdata *);
void cc_state_reclaim(struct rcu_head *rcu);
struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra);

/* LED beaconing functions */
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 @@ -1333,7 +1333,7 @@ static void cleanup_device_data(struct hfi1_devdata *dd)
spin_unlock(&ppd->cc_state_lock);

if (cc_state)
call_rcu(&cc_state->rcu, cc_state_reclaim);
kfree_rcu(cc_state, rcu);
}

free_credit_return(dd);
Expand Down
14 changes: 6 additions & 8 deletions drivers/infiniband/hw/hfi1/mad.c
Original file line number Diff line number Diff line change
Expand Up @@ -1819,6 +1819,11 @@ static int __subn_get_opa_cable_info(struct opa_smp *smp, u32 am, u8 *data,
u32 len = OPA_AM_CI_LEN(am) + 1;
int ret;

if (dd->pport->port_type != PORT_TYPE_QSFP) {
smp->status |= IB_SMP_INVALID_FIELD;
return reply((struct ib_mad_hdr *)smp);
}

#define __CI_PAGE_SIZE BIT(7) /* 128 bytes */
#define __CI_PAGE_MASK ~(__CI_PAGE_SIZE - 1)
#define __CI_PAGE_NUM(a) ((a) & __CI_PAGE_MASK)
Expand Down Expand Up @@ -3398,7 +3403,7 @@ static void apply_cc_state(struct hfi1_pportdata *ppd)

spin_unlock(&ppd->cc_state_lock);

call_rcu(&old_cc_state->rcu, cc_state_reclaim);
kfree_rcu(old_cc_state, rcu);
}

static int __subn_set_opa_cong_setting(struct opa_smp *smp, u32 am, u8 *data,
Expand Down Expand Up @@ -3553,13 +3558,6 @@ static int __subn_get_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,
return reply((struct ib_mad_hdr *)smp);
}

void cc_state_reclaim(struct rcu_head *rcu)
{
struct cc_state *cc_state = container_of(rcu, struct cc_state, rcu);

kfree(cc_state);
}

static int __subn_set_opa_cc_table(struct opa_smp *smp, u32 am, u8 *data,
struct ib_device *ibdev, u8 port,
u32 *resp_len)
Expand Down
4 changes: 0 additions & 4 deletions drivers/infiniband/hw/hfi1/qp.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,10 +656,6 @@ struct qp_iter *qp_iter_init(struct hfi1_ibdev *dev)

iter->dev = dev;
iter->specials = dev->rdi.ibdev.phys_port_cnt * 2;
if (qp_iter_next(iter)) {
kfree(iter);
return NULL;
}

return iter;
}
Expand Down
32 changes: 30 additions & 2 deletions drivers/infiniband/hw/hfi1/qsfp.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,8 +706,8 @@ int get_cable_info(struct hfi1_devdata *dd, u32 port_num, u32 addr, u32 len,
u8 *data)
{
struct hfi1_pportdata *ppd;
u32 excess_len = 0;
int ret = 0;
u32 excess_len = len;
int ret = 0, offset = 0;

if (port_num > dd->num_pports || port_num < 1) {
dd_dev_info(dd, "%s: Invalid port number %d\n",
Expand Down Expand Up @@ -740,6 +740,34 @@ int get_cable_info(struct hfi1_devdata *dd, u32 port_num, u32 addr, u32 len,
}

memcpy(data, &ppd->qsfp_info.cache[addr], len);

if (addr <= QSFP_MONITOR_VAL_END &&
(addr + len) >= QSFP_MONITOR_VAL_START) {
/* Overlap with the dynamic channel monitor range */
if (addr < QSFP_MONITOR_VAL_START) {
if (addr + len <= QSFP_MONITOR_VAL_END)
len = addr + len - QSFP_MONITOR_VAL_START;
else
len = QSFP_MONITOR_RANGE;
offset = QSFP_MONITOR_VAL_START - addr;
addr = QSFP_MONITOR_VAL_START;
} else if (addr == QSFP_MONITOR_VAL_START) {
offset = 0;
if (addr + len > QSFP_MONITOR_VAL_END)
len = QSFP_MONITOR_RANGE;
} else {
offset = 0;
if (addr + len > QSFP_MONITOR_VAL_END)
len = QSFP_MONITOR_VAL_END - addr + 1;
}
/* Refresh the values of the dynamic monitors from the cable */
ret = one_qsfp_read(ppd, dd->hfi1_id, addr, data + offset, len);
if (ret != len) {
ret = -EAGAIN;
goto set_zeroes;
}
}

return 0;

set_zeroes:
Expand Down
3 changes: 3 additions & 0 deletions drivers/infiniband/hw/hfi1/qsfp.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@
/* Defined fields that Intel requires of qualified cables */
/* Byte 0 is Identifier, not checked */
/* Byte 1 is reserved "status MSB" */
#define QSFP_MONITOR_VAL_START 22
#define QSFP_MONITOR_VAL_END 81
#define QSFP_MONITOR_RANGE (QSFP_MONITOR_VAL_END - QSFP_MONITOR_VAL_START + 1)
#define QSFP_TX_CTRL_BYTE_OFFS 86
#define QSFP_PWR_CTRL_BYTE_OFFS 93
#define QSFP_CDR_CTRL_BYTE_OFFS 98
Expand Down
Loading

0 comments on commit a3d3469

Please sign in to comment.