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:
 "For the most part this is just a minor -rc cycle for the rdma
  subsystem. Even given that this is all of the -rc patches since the
  merge window closed, it's still only about 25 patches:

   - Multiple i40iw, nes, iw_cxgb4, hfi1, qib, mlx4, mlx5 fixes

   - A few upper layer protocol fixes (IPoIB, iSER, SRP)

   - A modest number of core fixes"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma: (26 commits)
  RDMA/SA: Fix kernel panic in CMA request handler flow
  RDMA/umem: Fix missing mmap_sem in get umem ODP call
  RDMA/core: not to set page dirty bit if it's already set.
  RDMA/uverbs: Declare local function static and add brackets to sizeof
  RDMA/netlink: Reduce exposure of RDMA netlink functions
  RDMA/srp: Fix NULL deref at srp_destroy_qp()
  RDMA/IPoIB: Limit the ipoib_dev_uninit_default scope
  RDMA/IPoIB: Replace netdev_priv with ipoib_priv for ipoib_get_link_ksettings
  RDMA/qedr: add null check before pointer dereference
  RDMA/mlx5: set UMR wqe fence according to HCA cap
  net/mlx5: Define interface bits for fencing UMR wqe
  RDMA/mlx4: Fix MAD tunneling when SRIOV is enabled
  RDMA/qib,hfi1: Fix MR reference count leak on write with immediate
  RDMA/hfi1: Defer setting VL15 credits to link-up interrupt
  RDMA/hfi1: change PCI bar addr assignments to Linux API functions
  RDMA/hfi1: fix array termination by appending NULL to attr array
  RDMA/iw_cxgb4: fix the calculation of ipv6 header size
  RDMA/iw_cxgb4: calculate t4_eq_status_entries properly
  RDMA/iw_cxgb4: Avoid touch after free error in ARP failure handlers
  RDMA/nes: ACK MPA Reply frame
  ...
  • Loading branch information
Linus Torvalds committed Jun 4, 2017
2 parents ea094f3 + d3957b8 commit 55cbdaf
Showing 37 changed files with 194 additions and 170 deletions.
4 changes: 2 additions & 2 deletions drivers/infiniband/core/cm.c
Original file line number Diff line number Diff line change
@@ -1429,7 +1429,7 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
primary_path->packet_life_time =
cm_req_get_primary_local_ack_timeout(req_msg);
primary_path->packet_life_time -= (primary_path->packet_life_time > 0);
sa_path_set_service_id(primary_path, req_msg->service_id);
primary_path->service_id = req_msg->service_id;

if (req_msg->alt_local_lid) {
alt_path->dgid = req_msg->alt_local_gid;
@@ -1452,7 +1452,7 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
alt_path->packet_life_time =
cm_req_get_alt_local_ack_timeout(req_msg);
alt_path->packet_life_time -= (alt_path->packet_life_time > 0);
sa_path_set_service_id(alt_path, req_msg->service_id);
alt_path->service_id = req_msg->service_id;
}
}

13 changes: 6 additions & 7 deletions drivers/infiniband/core/cma.c
Original file line number Diff line number Diff line change
@@ -1140,7 +1140,7 @@ static void cma_save_ib_info(struct sockaddr *src_addr,
ib->sib_pkey = path->pkey;
ib->sib_flowinfo = path->flow_label;
memcpy(&ib->sib_addr, &path->sgid, 16);
ib->sib_sid = sa_path_get_service_id(path);
ib->sib_sid = path->service_id;
ib->sib_scope_id = 0;
} else {
ib->sib_pkey = listen_ib->sib_pkey;
@@ -1274,8 +1274,7 @@ static int cma_save_req_info(const struct ib_cm_event *ib_event,
memcpy(&req->local_gid, &req_param->primary_path->sgid,
sizeof(req->local_gid));
req->has_gid = true;
req->service_id =
sa_path_get_service_id(req_param->primary_path);
req->service_id = req_param->primary_path->service_id;
req->pkey = be16_to_cpu(req_param->primary_path->pkey);
if (req->pkey != req_param->bth_pkey)
pr_warn_ratelimited("RDMA CMA: got different BTH P_Key (0x%x) and primary path P_Key (0x%x)\n"
@@ -1827,7 +1826,8 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
struct rdma_route *rt;
const sa_family_t ss_family = listen_id->route.addr.src_addr.ss_family;
struct sa_path_rec *path = ib_event->param.req_rcvd.primary_path;
const __be64 service_id = sa_path_get_service_id(path);
const __be64 service_id =
ib_event->param.req_rcvd.primary_path->service_id;
int ret;

id = rdma_create_id(listen_id->route.addr.dev_addr.net,
@@ -2345,9 +2345,8 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms,
path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
path_rec.numb_path = 1;
path_rec.reversible = 1;
sa_path_set_service_id(&path_rec,
rdma_get_service_id(&id_priv->id,
cma_dst_addr(id_priv)));
path_rec.service_id = rdma_get_service_id(&id_priv->id,
cma_dst_addr(id_priv));

comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID |
IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH |
10 changes: 10 additions & 0 deletions drivers/infiniband/core/core_priv.h
Original file line number Diff line number Diff line change
@@ -169,6 +169,16 @@ void ib_mad_cleanup(void);
int ib_sa_init(void);
void ib_sa_cleanup(void);

int ibnl_init(void);
void ibnl_cleanup(void);

/**
* Check if there are any listeners to the netlink group
* @group: the netlink group ID
* Returns 0 on success or a negative for no listeners.
*/
int ibnl_chk_listeners(unsigned int group);

int ib_nl_handle_resolve_resp(struct sk_buff *skb,
struct netlink_callback *cb);
int ib_nl_handle_set_timeout(struct sk_buff *skb,
2 changes: 1 addition & 1 deletion drivers/infiniband/core/netlink.c
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@
#include <net/net_namespace.h>
#include <net/sock.h>
#include <rdma/rdma_netlink.h>
#include "core_priv.h"

struct ibnl_client {
struct list_head list;
@@ -55,7 +56,6 @@ int ibnl_chk_listeners(unsigned int group)
return -1;
return 0;
}
EXPORT_SYMBOL(ibnl_chk_listeners);

int ibnl_add_client(int index, int nops,
const struct ibnl_client_cbs cb_table[])
6 changes: 3 additions & 3 deletions drivers/infiniband/core/sa_query.c
Original file line number Diff line number Diff line change
@@ -194,7 +194,7 @@ static u32 tid;
.field_name = "sa_path_rec:" #field

static const struct ib_field path_rec_table[] = {
{ PATH_REC_FIELD(ib.service_id),
{ PATH_REC_FIELD(service_id),
.offset_words = 0,
.offset_bits = 0,
.size_bits = 64 },
@@ -296,7 +296,7 @@ static const struct ib_field path_rec_table[] = {
.field_name = "sa_path_rec:" #field

static const struct ib_field opa_path_rec_table[] = {
{ OPA_PATH_REC_FIELD(opa.service_id),
{ OPA_PATH_REC_FIELD(service_id),
.offset_words = 0,
.offset_bits = 0,
.size_bits = 64 },
@@ -774,7 +774,7 @@ static void ib_nl_set_path_rec_attrs(struct sk_buff *skb,

/* Now build the attributes */
if (comp_mask & IB_SA_PATH_REC_SERVICE_ID) {
val64 = be64_to_cpu(sa_path_get_service_id(sa_rec));
val64 = be64_to_cpu(sa_rec->service_id);
nla_put(skb, RDMA_NLA_F_MANDATORY | LS_NLA_TYPE_SERVICE_ID,
sizeof(val64), &val64);
}
2 changes: 1 addition & 1 deletion drivers/infiniband/core/umem.c
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
for_each_sg(umem->sg_head.sgl, sg, umem->npages, i) {

page = sg_page(sg);
if (umem->writable && dirty)
if (!PageDirty(page) && umem->writable && dirty)
set_page_dirty_lock(page);
put_page(page);
}
6 changes: 5 additions & 1 deletion drivers/infiniband/core/umem_odp.c
Original file line number Diff line number Diff line change
@@ -321,11 +321,15 @@ int ib_umem_odp_get(struct ib_ucontext *context, struct ib_umem *umem,
struct vm_area_struct *vma;
struct hstate *h;

down_read(&mm->mmap_sem);
vma = find_vma(mm, ib_umem_start(umem));
if (!vma || !is_vm_hugetlb_page(vma))
if (!vma || !is_vm_hugetlb_page(vma)) {
up_read(&mm->mmap_sem);
return -EINVAL;
}
h = hstate_vma(vma);
umem->page_shift = huge_page_shift(h);
up_read(&mm->mmap_sem);
umem->hugetlb = 1;
} else {
umem->hugetlb = 0;
8 changes: 4 additions & 4 deletions drivers/infiniband/core/uverbs_marshall.c
Original file line number Diff line number Diff line change
@@ -96,11 +96,11 @@ void ib_copy_qp_attr_to_user(struct ib_uverbs_qp_attr *dst,
}
EXPORT_SYMBOL(ib_copy_qp_attr_to_user);

void __ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,
struct sa_path_rec *src)
static void __ib_copy_path_rec_to_user(struct ib_user_path_rec *dst,
struct sa_path_rec *src)
{
memcpy(dst->dgid, src->dgid.raw, sizeof src->dgid);
memcpy(dst->sgid, src->sgid.raw, sizeof src->sgid);
memcpy(dst->dgid, src->dgid.raw, sizeof(src->dgid));
memcpy(dst->sgid, src->sgid.raw, sizeof(src->sgid));

dst->dlid = htons(ntohl(sa_path_get_dlid(src)));
dst->slid = htons(ntohl(sa_path_get_slid(src)));
9 changes: 7 additions & 2 deletions drivers/infiniband/hw/cxgb4/cm.c
Original file line number Diff line number Diff line change
@@ -488,6 +488,7 @@ static int _put_ep_safe(struct c4iw_dev *dev, struct sk_buff *skb)

ep = *((struct c4iw_ep **)(skb->cb + 2 * sizeof(void *)));
release_ep_resources(ep);
kfree_skb(skb);
return 0;
}

@@ -498,6 +499,7 @@ static int _put_pass_ep_safe(struct c4iw_dev *dev, struct sk_buff *skb)
ep = *((struct c4iw_ep **)(skb->cb + 2 * sizeof(void *)));
c4iw_put_ep(&ep->parent_ep->com);
release_ep_resources(ep);
kfree_skb(skb);
return 0;
}

@@ -569,11 +571,13 @@ static void abort_arp_failure(void *handle, struct sk_buff *skb)

pr_debug("%s rdev %p\n", __func__, rdev);
req->cmd = CPL_ABORT_NO_RST;
skb_get(skb);
ret = c4iw_ofld_send(rdev, skb);
if (ret) {
__state_set(&ep->com, DEAD);
queue_arp_failure_cpl(ep, skb, FAKE_CPL_PUT_EP_SAFE);
}
} else
kfree_skb(skb);
}

static int send_flowc(struct c4iw_ep *ep)
@@ -2517,7 +2521,8 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
goto reject;
}

hdrs = sizeof(struct iphdr) + sizeof(struct tcphdr) +
hdrs = ((iptype == 4) ? sizeof(struct iphdr) : sizeof(struct ipv6hdr)) +
sizeof(struct tcphdr) +
((enable_tcp_timestamps && req->tcpopt.tstamp) ? 12 : 0);
if (peer_mss && child_ep->mtu > (peer_mss + hdrs))
child_ep->mtu = peer_mss + hdrs;
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/cxgb4/device.c
Original file line number Diff line number Diff line change
@@ -971,7 +971,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
devp->rdev.lldi.sge_egrstatuspagesize);

devp->rdev.hw_queue.t4_eq_status_entries =
devp->rdev.lldi.sge_ingpadboundary > 64 ? 2 : 1;
devp->rdev.lldi.sge_egrstatuspagesize / 64;
devp->rdev.hw_queue.t4_max_eq_size = 65520;
devp->rdev.hw_queue.t4_max_iq_size = 65520;
devp->rdev.hw_queue.t4_max_rq_size = 8192 -
67 changes: 50 additions & 17 deletions drivers/infiniband/hw/hfi1/chip.c
Original file line number Diff line number Diff line change
@@ -6312,25 +6312,38 @@ static void handle_8051_request(struct hfi1_pportdata *ppd)
}
}

static void write_global_credit(struct hfi1_devdata *dd,
u8 vau, u16 total, u16 shared)
/*
* Set up allocation unit vaulue.
*/
void set_up_vau(struct hfi1_devdata *dd, u8 vau)
{
write_csr(dd, SEND_CM_GLOBAL_CREDIT,
((u64)total <<
SEND_CM_GLOBAL_CREDIT_TOTAL_CREDIT_LIMIT_SHIFT) |
((u64)shared <<
SEND_CM_GLOBAL_CREDIT_SHARED_LIMIT_SHIFT) |
((u64)vau << SEND_CM_GLOBAL_CREDIT_AU_SHIFT));
u64 reg = read_csr(dd, SEND_CM_GLOBAL_CREDIT);

/* do not modify other values in the register */
reg &= ~SEND_CM_GLOBAL_CREDIT_AU_SMASK;
reg |= (u64)vau << SEND_CM_GLOBAL_CREDIT_AU_SHIFT;
write_csr(dd, SEND_CM_GLOBAL_CREDIT, reg);
}

/*
* Set up initial VL15 credits of the remote. Assumes the rest of
* the CM credit registers are zero from a previous global or credit reset .
* the CM credit registers are zero from a previous global or credit reset.
* Shared limit for VL15 will always be 0.
*/
void set_up_vl15(struct hfi1_devdata *dd, u8 vau, u16 vl15buf)
void set_up_vl15(struct hfi1_devdata *dd, u16 vl15buf)
{
/* leave shared count at zero for both global and VL15 */
write_global_credit(dd, vau, vl15buf, 0);
u64 reg = read_csr(dd, SEND_CM_GLOBAL_CREDIT);

/* set initial values for total and shared credit limit */
reg &= ~(SEND_CM_GLOBAL_CREDIT_TOTAL_CREDIT_LIMIT_SMASK |
SEND_CM_GLOBAL_CREDIT_SHARED_LIMIT_SMASK);

/*
* Set total limit to be equal to VL15 credits.
* Leave shared limit at 0.
*/
reg |= (u64)vl15buf << SEND_CM_GLOBAL_CREDIT_TOTAL_CREDIT_LIMIT_SHIFT;
write_csr(dd, SEND_CM_GLOBAL_CREDIT, reg);

write_csr(dd, SEND_CM_CREDIT_VL15, (u64)vl15buf
<< SEND_CM_CREDIT_VL15_DEDICATED_LIMIT_VL_SHIFT);
@@ -6348,9 +6361,11 @@ void reset_link_credits(struct hfi1_devdata *dd)
for (i = 0; i < TXE_NUM_DATA_VL; i++)
write_csr(dd, SEND_CM_CREDIT_VL + (8 * i), 0);
write_csr(dd, SEND_CM_CREDIT_VL15, 0);
write_global_credit(dd, 0, 0, 0);
write_csr(dd, SEND_CM_GLOBAL_CREDIT, 0);
/* reset the CM block */
pio_send_control(dd, PSC_CM_RESET);
/* reset cached value */
dd->vl15buf_cached = 0;
}

/* convert a vCU to a CU */
@@ -6839,24 +6854,35 @@ void handle_link_up(struct work_struct *work)
{
struct hfi1_pportdata *ppd = container_of(work, struct hfi1_pportdata,
link_up_work);
struct hfi1_devdata *dd = ppd->dd;

set_link_state(ppd, HLS_UP_INIT);

/* cache the read of DC_LCB_STS_ROUND_TRIP_LTP_CNT */
read_ltp_rtt(ppd->dd);
read_ltp_rtt(dd);
/*
* OPA specifies that certain counters are cleared on a transition
* to link up, so do that.
*/
clear_linkup_counters(ppd->dd);
clear_linkup_counters(dd);
/*
* And (re)set link up default values.
*/
set_linkup_defaults(ppd);

/*
* Set VL15 credits. Use cached value from verify cap interrupt.
* In case of quick linkup or simulator, vl15 value will be set by
* handle_linkup_change. VerifyCap interrupt handler will not be
* called in those scenarios.
*/
if (!(quick_linkup || dd->icode == ICODE_FUNCTIONAL_SIMULATOR))
set_up_vl15(dd, dd->vl15buf_cached);

/* enforce link speed enabled */
if ((ppd->link_speed_active & ppd->link_speed_enabled) == 0) {
/* oops - current speed is not enabled, bounce */
dd_dev_err(ppd->dd,
dd_dev_err(dd,
"Link speed active 0x%x is outside enabled 0x%x, downing link\n",
ppd->link_speed_active, ppd->link_speed_enabled);
set_link_down_reason(ppd, OPA_LINKDOWN_REASON_SPEED_POLICY, 0,
@@ -7357,7 +7383,14 @@ void handle_verify_cap(struct work_struct *work)
*/
if (vau == 0)
vau = 1;
set_up_vl15(dd, vau, vl15buf);
set_up_vau(dd, vau);

/*
* Set VL15 credits to 0 in global credit register. Cache remote VL15
* credits value and wait for link-up interrupt ot set it.
*/
set_up_vl15(dd, 0);
dd->vl15buf_cached = vl15buf;

/* set up the LCB CRC mode */
crc_mask = ppd->port_crc_mode_enabled & partner_supported_crc;
2 changes: 2 additions & 0 deletions drivers/infiniband/hw/hfi1/chip_registers.h
Original file line number Diff line number Diff line change
@@ -839,7 +839,9 @@
#define SEND_CM_CTRL_FORCE_CREDIT_MODE_SMASK 0x8ull
#define SEND_CM_CTRL_RESETCSR 0x0000000000000020ull
#define SEND_CM_GLOBAL_CREDIT (TXE + 0x000000000508)
#define SEND_CM_GLOBAL_CREDIT_AU_MASK 0x7ull
#define SEND_CM_GLOBAL_CREDIT_AU_SHIFT 16
#define SEND_CM_GLOBAL_CREDIT_AU_SMASK 0x70000ull
#define SEND_CM_GLOBAL_CREDIT_RESETCSR 0x0000094000030000ull
#define SEND_CM_GLOBAL_CREDIT_SHARED_LIMIT_MASK 0xFFFFull
#define SEND_CM_GLOBAL_CREDIT_SHARED_LIMIT_SHIFT 0
11 changes: 10 additions & 1 deletion drivers/infiniband/hw/hfi1/hfi.h
Original file line number Diff line number Diff line change
@@ -1045,6 +1045,14 @@ struct hfi1_devdata {
/* initial vl15 credits to use */
u16 vl15_init;

/*
* Cached value for vl15buf, read during verify cap interrupt. VL15
* credits are to be kept at 0 and set when handling the link-up
* interrupt. This removes the possibility of receiving VL15 MAD
* packets before this HFI is ready.
*/
u16 vl15buf_cached;

/* Misc small ints */
u8 n_krcv_queues;
u8 qos_shift;
@@ -1598,7 +1606,8 @@ int hfi1_rcvbuf_validate(u32 size, u8 type, u16 *encode);
int fm_get_table(struct hfi1_pportdata *ppd, int which, void *t);
int fm_set_table(struct hfi1_pportdata *ppd, int which, void *t);

void set_up_vl15(struct hfi1_devdata *dd, u8 vau, u16 vl15buf);
void set_up_vau(struct hfi1_devdata *dd, u8 vau);
void set_up_vl15(struct hfi1_devdata *dd, u16 vl15buf);
void reset_link_credits(struct hfi1_devdata *dd);
void assign_remote_cm_au_table(struct hfi1_devdata *dd, u8 vcu);

3 changes: 2 additions & 1 deletion drivers/infiniband/hw/hfi1/intr.c
Original file line number Diff line number Diff line change
@@ -130,7 +130,8 @@ void handle_linkup_change(struct hfi1_devdata *dd, u32 linkup)
* the remote values. Both sides must be using the values.
*/
if (quick_linkup || dd->icode == ICODE_FUNCTIONAL_SIMULATOR) {
set_up_vl15(dd, dd->vau, dd->vl15_init);
set_up_vau(dd, dd->vau);
set_up_vl15(dd, dd->vl15_init);
assign_remote_cm_au_table(dd, dd->vcu);
}

4 changes: 2 additions & 2 deletions drivers/infiniband/hw/hfi1/pcie.c
Original file line number Diff line number Diff line change
@@ -207,8 +207,8 @@ int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev)
/*
* Save BARs and command to rewrite after device reset.
*/
dd->pcibar0 = addr;
dd->pcibar1 = addr >> 32;
pci_read_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0, &dd->pcibar0);
pci_read_config_dword(dd->pcidev, PCI_BASE_ADDRESS_1, &dd->pcibar1);
pci_read_config_dword(dd->pcidev, PCI_ROM_ADDRESS, &dd->pci_rom);
pci_read_config_word(dd->pcidev, PCI_COMMAND, &dd->pci_command);
pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCTL, &dd->pcie_devctl);
5 changes: 4 additions & 1 deletion drivers/infiniband/hw/hfi1/rc.c
Original file line number Diff line number Diff line change
@@ -2159,8 +2159,11 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
ret = hfi1_rvt_get_rwqe(qp, 1);
if (ret < 0)
goto nack_op_err;
if (!ret)
if (!ret) {
/* peer will send again */
rvt_put_ss(&qp->r_sge);
goto rnr_nak;
}
wc.ex.imm_data = ohdr->u.rc.imm_data;
wc.wc_flags = IB_WC_WITH_IMM;
goto send_last;
Loading

0 comments on commit 55cbdaf

Please sign in to comment.