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 has been a slow -rc cycle for the RDMA subsystem. We really
  haven't had a lot of rc fixes come in. This pull request is the first
  of this entire rc cycle and it has all of the suitable fixes so far
  and it's still only about 20 patches. The fix for the minor breakage
  cause by the dma mapping patchset is in here, as well as a couple
  other potential oops fixes, but the rest is more minor.

  Summary:

   - fix for dma_ops change in this kernel, resolving the s390, powerpc,
     and IOMMU operation

   - a few other oops fixes

   - the rest are all minor fixes"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma:
  IB/qib: fix false-postive maybe-uninitialized warning
  RDMA/iser: Fix possible mr leak on device removal event
  IB/device: Convert ib-comp-wq to be CPU-bound
  IB/cq: Don't process more than the given budget
  IB/rxe: increment msn only when completing a request
  uapi: fix rdma/mlx5-abi.h userspace compilation errors
  IB/core: Restore I/O MMU, s390 and powerpc support
  IB/rxe: Update documentation link
  RDMA/ocrdma: fix a type issue in ocrdma_put_pd_num()
  IB/rxe: double free on error
  RDMA/vmw_pvrdma: Activate device on ethernet link up
  RDMA/vmw_pvrdma: Dont hardcode QP header page
  RDMA/vmw_pvrdma: Cleanup unused variables
  infiniband: Fix alignment of mmap cookies to support VIPT caching
  IB/core: Protect against self-requeue of a cq work item
  i40iw: Receive netdev events post INET_NOTIFIER state
  • Loading branch information
torvalds committed Mar 25, 2017
2 parents 4c3de7e + f6aafac commit 4a01fa5
Show file tree
Hide file tree
Showing 18 changed files with 110 additions and 69 deletions.
10 changes: 8 additions & 2 deletions drivers/infiniband/core/cq.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ static int __ib_process_cq(struct ib_cq *cq, int budget)
{
int i, n, completed = 0;

while ((n = ib_poll_cq(cq, IB_POLL_BATCH, cq->wc)) > 0) {
/*
* budget might be (-1) if the caller does not
* want to bound this call, thus we need unsigned
* minimum here.
*/
while ((n = ib_poll_cq(cq, min_t(u32, IB_POLL_BATCH,
budget - completed), cq->wc)) > 0) {
for (i = 0; i < n; i++) {
struct ib_wc *wc = &cq->wc[i];

Expand Down Expand Up @@ -196,7 +202,7 @@ void ib_free_cq(struct ib_cq *cq)
irq_poll_disable(&cq->iop);
break;
case IB_POLL_WORKQUEUE:
flush_work(&cq->work);
cancel_work_sync(&cq->work);
break;
default:
WARN_ON_ONCE(1);
Expand Down
29 changes: 21 additions & 8 deletions drivers/infiniband/core/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,26 @@ int ib_register_device(struct ib_device *device,
struct device *parent = device->dev.parent;

WARN_ON_ONCE(!parent);
if (!device->dev.dma_ops)
device->dev.dma_ops = parent->dma_ops;
if (!device->dev.dma_mask)
device->dev.dma_mask = parent->dma_mask;
if (!device->dev.coherent_dma_mask)
device->dev.coherent_dma_mask = parent->coherent_dma_mask;
WARN_ON_ONCE(device->dma_device);
if (device->dev.dma_ops) {
/*
* The caller provided custom DMA operations. Copy the
* DMA-related fields that are used by e.g. dma_alloc_coherent()
* into device->dev.
*/
device->dma_device = &device->dev;
if (!device->dev.dma_mask)
device->dev.dma_mask = parent->dma_mask;
if (!device->dev.coherent_dma_mask)
device->dev.coherent_dma_mask =
parent->coherent_dma_mask;
} else {
/*
* The caller did not provide custom DMA operations. Use the
* DMA mapping operations of the parent device.
*/
device->dma_device = parent;
}

mutex_lock(&device_mutex);

Expand Down Expand Up @@ -1015,8 +1029,7 @@ static int __init ib_core_init(void)
return -ENOMEM;

ib_comp_wq = alloc_workqueue("ib-comp-wq",
WQ_UNBOUND | WQ_HIGHPRI | WQ_MEM_RECLAIM,
WQ_UNBOUND_MAX_ACTIVE);
WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_SYSFS, 0);
if (!ib_comp_wq) {
ret = -ENOMEM;
goto err;
Expand Down
8 changes: 8 additions & 0 deletions drivers/infiniband/hw/i40iw/i40iw_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ int i40iw_inetaddr_event(struct notifier_block *notifier,
return NOTIFY_DONE;

iwdev = &hdl->device;
if (iwdev->init_state < INET_NOTIFIER)
return NOTIFY_DONE;

netdev = iwdev->ldev->netdev;
upper_dev = netdev_master_upper_dev_get(netdev);
if (netdev != event_netdev)
Expand Down Expand Up @@ -214,6 +217,9 @@ int i40iw_inet6addr_event(struct notifier_block *notifier,
return NOTIFY_DONE;

iwdev = &hdl->device;
if (iwdev->init_state < INET_NOTIFIER)
return NOTIFY_DONE;

netdev = iwdev->ldev->netdev;
if (netdev != event_netdev)
return NOTIFY_DONE;
Expand Down Expand Up @@ -260,6 +266,8 @@ int i40iw_net_event(struct notifier_block *notifier, unsigned long event, void *
if (!iwhdl)
return NOTIFY_DONE;
iwdev = &iwhdl->device;
if (iwdev->init_state < INET_NOTIFIER)
return NOTIFY_DONE;
p = (__be32 *)neigh->primary_key;
i40iw_copy_ip_ntohl(local_ipaddr, p);
if (neigh->nud_state & NUD_VALID) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ static int _ocrdma_pd_mgr_put_bitmap(struct ocrdma_dev *dev, u16 pd_id,
return 0;
}

static u8 ocrdma_put_pd_num(struct ocrdma_dev *dev, u16 pd_id,
static int ocrdma_put_pd_num(struct ocrdma_dev *dev, u16 pd_id,
bool dpp_pool)
{
int status;
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/qib/qib_iba7322.c
Original file line number Diff line number Diff line change
Expand Up @@ -7068,7 +7068,7 @@ static void qib_7322_txchk_change(struct qib_devdata *dd, u32 start,
unsigned long flags;

while (wait) {
unsigned long shadow;
unsigned long shadow = 0;
int cstart, previ = -1;

/*
Expand Down
3 changes: 3 additions & 0 deletions drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@
*/
#define PCI_DEVICE_ID_VMWARE_PVRDMA 0x0820

#define PVRDMA_NUM_RING_PAGES 4
#define PVRDMA_QP_NUM_HEADER_PAGES 1

struct pvrdma_dev;

struct pvrdma_page_dir {
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/vmw_pvrdma/pvrdma_dev_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ enum pvrdma_pci_resource {

enum pvrdma_device_ctl {
PVRDMA_DEVICE_CTL_ACTIVATE, /* Activate device. */
PVRDMA_DEVICE_CTL_QUIESCE, /* Quiesce device. */
PVRDMA_DEVICE_CTL_UNQUIESCE, /* Unquiesce device. */
PVRDMA_DEVICE_CTL_RESET, /* Reset device. */
};

Expand Down
17 changes: 13 additions & 4 deletions drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
#include "pvrdma.h"

#define DRV_NAME "vmw_pvrdma"
#define DRV_VERSION "1.0.0.0-k"
#define DRV_VERSION "1.0.1.0-k"

static DEFINE_MUTEX(pvrdma_device_list_lock);
static LIST_HEAD(pvrdma_device_list);
Expand Down Expand Up @@ -660,7 +660,16 @@ static void pvrdma_netdevice_event_handle(struct pvrdma_dev *dev,
pvrdma_dispatch_event(dev, 1, IB_EVENT_PORT_ERR);
break;
case NETDEV_UP:
pvrdma_dispatch_event(dev, 1, IB_EVENT_PORT_ACTIVE);
pvrdma_write_reg(dev, PVRDMA_REG_CTL,
PVRDMA_DEVICE_CTL_UNQUIESCE);

mb();

if (pvrdma_read_reg(dev, PVRDMA_REG_ERR))
dev_err(&dev->pdev->dev,
"failed to activate device during link up\n");
else
pvrdma_dispatch_event(dev, 1, IB_EVENT_PORT_ACTIVE);
break;
default:
dev_dbg(&dev->pdev->dev, "ignore netdevice event %ld on %s\n",
Expand Down Expand Up @@ -858,7 +867,7 @@ static int pvrdma_pci_probe(struct pci_dev *pdev,
dev->dsr->resp_slot_dma = (u64)slot_dma;

/* Async event ring */
dev->dsr->async_ring_pages.num_pages = 4;
dev->dsr->async_ring_pages.num_pages = PVRDMA_NUM_RING_PAGES;
ret = pvrdma_page_dir_init(dev, &dev->async_pdir,
dev->dsr->async_ring_pages.num_pages, true);
if (ret)
Expand All @@ -867,7 +876,7 @@ static int pvrdma_pci_probe(struct pci_dev *pdev,
dev->dsr->async_ring_pages.pdir_dma = dev->async_pdir.dir_dma;

/* CQ notification ring */
dev->dsr->cq_ring_pages.num_pages = 4;
dev->dsr->cq_ring_pages.num_pages = PVRDMA_NUM_RING_PAGES;
ret = pvrdma_page_dir_init(dev, &dev->cq_pdir,
dev->dsr->cq_ring_pages.num_pages, true);
if (ret)
Expand Down
42 changes: 18 additions & 24 deletions drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,9 @@ static int pvrdma_set_sq_size(struct pvrdma_dev *dev, struct ib_qp_cap *req_cap,
sizeof(struct pvrdma_sge) *
qp->sq.max_sg);
/* Note: one extra page for the header. */
qp->npages_send = 1 + (qp->sq.wqe_cnt * qp->sq.wqe_size +
PAGE_SIZE - 1) / PAGE_SIZE;
qp->npages_send = PVRDMA_QP_NUM_HEADER_PAGES +
(qp->sq.wqe_cnt * qp->sq.wqe_size + PAGE_SIZE - 1) /
PAGE_SIZE;

return 0;
}
Expand Down Expand Up @@ -288,7 +289,7 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd,
qp->npages = qp->npages_send + qp->npages_recv;

/* Skip header page. */
qp->sq.offset = PAGE_SIZE;
qp->sq.offset = PVRDMA_QP_NUM_HEADER_PAGES * PAGE_SIZE;

/* Recv queue pages are after send pages. */
qp->rq.offset = qp->npages_send * PAGE_SIZE;
Expand Down Expand Up @@ -341,7 +342,7 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd,
cmd->qp_type = ib_qp_type_to_pvrdma(init_attr->qp_type);
cmd->access_flags = IB_ACCESS_LOCAL_WRITE;
cmd->total_chunks = qp->npages;
cmd->send_chunks = qp->npages_send - 1;
cmd->send_chunks = qp->npages_send - PVRDMA_QP_NUM_HEADER_PAGES;
cmd->pdir_dma = qp->pdir.dir_dma;

dev_dbg(&dev->pdev->dev, "create queuepair with %d, %d, %d, %d\n",
Expand Down Expand Up @@ -554,13 +555,13 @@ int pvrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
return ret;
}

static inline void *get_sq_wqe(struct pvrdma_qp *qp, int n)
static inline void *get_sq_wqe(struct pvrdma_qp *qp, unsigned int n)
{
return pvrdma_page_dir_get_ptr(&qp->pdir,
qp->sq.offset + n * qp->sq.wqe_size);
}

static inline void *get_rq_wqe(struct pvrdma_qp *qp, int n)
static inline void *get_rq_wqe(struct pvrdma_qp *qp, unsigned int n)
{
return pvrdma_page_dir_get_ptr(&qp->pdir,
qp->rq.offset + n * qp->rq.wqe_size);
Expand Down Expand Up @@ -598,9 +599,7 @@ int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
unsigned long flags;
struct pvrdma_sq_wqe_hdr *wqe_hdr;
struct pvrdma_sge *sge;
int i, index;
int nreq;
int ret;
int i, ret;

/*
* In states lower than RTS, we can fail immediately. In other states,
Expand All @@ -613,9 +612,8 @@ int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,

spin_lock_irqsave(&qp->sq.lock, flags);

index = pvrdma_idx(&qp->sq.ring->prod_tail, qp->sq.wqe_cnt);
for (nreq = 0; wr; nreq++, wr = wr->next) {
unsigned int tail;
while (wr) {
unsigned int tail = 0;

if (unlikely(!pvrdma_idx_ring_has_space(
qp->sq.ring, qp->sq.wqe_cnt, &tail))) {
Expand Down Expand Up @@ -680,7 +678,7 @@ int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
}
}

wqe_hdr = (struct pvrdma_sq_wqe_hdr *)get_sq_wqe(qp, index);
wqe_hdr = (struct pvrdma_sq_wqe_hdr *)get_sq_wqe(qp, tail);
memset(wqe_hdr, 0, sizeof(*wqe_hdr));
wqe_hdr->wr_id = wr->wr_id;
wqe_hdr->num_sge = wr->num_sge;
Expand Down Expand Up @@ -771,12 +769,11 @@ int pvrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
/* Make sure wqe is written before index update */
smp_wmb();

index++;
if (unlikely(index >= qp->sq.wqe_cnt))
index = 0;
/* Update shared sq ring */
pvrdma_idx_ring_inc(&qp->sq.ring->prod_tail,
qp->sq.wqe_cnt);

wr = wr->next;
}

ret = 0;
Expand Down Expand Up @@ -806,7 +803,6 @@ int pvrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
struct pvrdma_qp *qp = to_vqp(ibqp);
struct pvrdma_rq_wqe_hdr *wqe_hdr;
struct pvrdma_sge *sge;
int index, nreq;
int ret = 0;
int i;

Expand All @@ -821,9 +817,8 @@ int pvrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,

spin_lock_irqsave(&qp->rq.lock, flags);

index = pvrdma_idx(&qp->rq.ring->prod_tail, qp->rq.wqe_cnt);
for (nreq = 0; wr; nreq++, wr = wr->next) {
unsigned int tail;
while (wr) {
unsigned int tail = 0;

if (unlikely(wr->num_sge > qp->rq.max_sg ||
wr->num_sge < 0)) {
Expand All @@ -843,7 +838,7 @@ int pvrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
goto out;
}

wqe_hdr = (struct pvrdma_rq_wqe_hdr *)get_rq_wqe(qp, index);
wqe_hdr = (struct pvrdma_rq_wqe_hdr *)get_rq_wqe(qp, tail);
wqe_hdr->wr_id = wr->wr_id;
wqe_hdr->num_sge = wr->num_sge;
wqe_hdr->total_len = 0;
Expand All @@ -859,12 +854,11 @@ int pvrdma_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
/* Make sure wqe is written before index update */
smp_wmb();

index++;
if (unlikely(index >= qp->rq.wqe_cnt))
index = 0;
/* Update shared rq ring */
pvrdma_idx_ring_inc(&qp->rq.ring->prod_tail,
qp->rq.wqe_cnt);

wr = wr->next;
}

spin_unlock_irqrestore(&qp->rq.lock, flags);
Expand Down
4 changes: 2 additions & 2 deletions drivers/infiniband/sw/rdmavt/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi,

spin_lock_irq(&rdi->mmap_offset_lock);
if (rdi->mmap_offset == 0)
rdi->mmap_offset = PAGE_SIZE;
rdi->mmap_offset = ALIGN(PAGE_SIZE, SHMLBA);
ip->offset = rdi->mmap_offset;
rdi->mmap_offset += size;
rdi->mmap_offset += ALIGN(size, SHMLBA);
spin_unlock_irq(&rdi->mmap_offset_lock);

INIT_LIST_HEAD(&ip->pending_mmaps);
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/sw/rxe/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ config RDMA_RXE
To configure and work with soft-RoCE driver please use the
following wiki page under "configure Soft-RoCE (RXE)" section:

https://github.com/SoftRoCE/rxe-dev/wiki/rxe-dev:-Home
https://github.com/linux-rdma/rdma-core/blob/master/Documentation/rxe.md
4 changes: 2 additions & 2 deletions drivers/infiniband/sw/rxe/rxe_mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,10 @@ struct rxe_mmap_info *rxe_create_mmap_info(struct rxe_dev *rxe,
spin_lock_bh(&rxe->mmap_offset_lock);

if (rxe->mmap_offset == 0)
rxe->mmap_offset = PAGE_SIZE;
rxe->mmap_offset = ALIGN(PAGE_SIZE, SHMLBA);

ip->info.offset = rxe->mmap_offset;
rxe->mmap_offset += size;
rxe->mmap_offset += ALIGN(size, SHMLBA);

spin_unlock_bh(&rxe->mmap_offset_lock);

Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/sw/rxe/rxe_req.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,11 +729,11 @@ int rxe_requester(void *arg)
ret = rxe_xmit_packet(to_rdev(qp->ibqp.device), qp, &pkt, skb);
if (ret) {
qp->need_req_skb = 1;
kfree_skb(skb);

rollback_state(wqe, qp, &rollback_wqe, rollback_psn);

if (ret == -EAGAIN) {
kfree_skb(skb);
rxe_run_task(&qp->req.task, 1);
goto exit;
}
Expand Down
9 changes: 4 additions & 5 deletions drivers/infiniband/sw/rxe/rxe_resp.c
Original file line number Diff line number Diff line change
Expand Up @@ -813,18 +813,17 @@ static enum resp_states execute(struct rxe_qp *qp, struct rxe_pkt_info *pkt)
WARN_ON_ONCE(1);
}

/* We successfully processed this new request. */
qp->resp.msn++;

/* next expected psn, read handles this separately */
qp->resp.psn = (pkt->psn + 1) & BTH_PSN_MASK;

qp->resp.opcode = pkt->opcode;
qp->resp.status = IB_WC_SUCCESS;

if (pkt->mask & RXE_COMP_MASK)
if (pkt->mask & RXE_COMP_MASK) {
/* We successfully processed this new request. */
qp->resp.msn++;
return RESPST_COMPLETE;
else if (qp_type(qp) == IB_QPT_RC)
} else if (qp_type(qp) == IB_QPT_RC)
return RESPST_ACKNOWLEDGE;
else
return RESPST_CLEANUP;
Expand Down
2 changes: 2 additions & 0 deletions drivers/infiniband/ulp/iser/iscsi_iser.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ struct iser_fr_desc {
struct list_head list;
struct iser_reg_resources rsc;
struct iser_pi_context *pi_ctx;
struct list_head all_list;
};

/**
Expand All @@ -443,6 +444,7 @@ struct iser_fr_pool {
struct list_head list;
spinlock_t lock;
int size;
struct list_head all_list;
};

/**
Expand Down
Loading

0 comments on commit 4a01fa5

Please sign in to comment.