Skip to content

Commit

Permalink
Merge branches 'cxgb4' and 'mlx5' into k.o/for-4.8
Browse files Browse the repository at this point in the history
  • Loading branch information
dledford committed Aug 4, 2016
3 parents fb92d8f + 59c68ac + 321a9e3 commit 3e5e8e8
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 76 deletions.
54 changes: 17 additions & 37 deletions drivers/infiniband/core/iwcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,15 +183,14 @@ static void free_cm_id(struct iwcm_id_private *cm_id_priv)

/*
* Release a reference on cm_id. If the last reference is being
* released, enable the waiting thread (in iw_destroy_cm_id) to
* get woken up, and return 1 if a thread is already waiting.
* released, free the cm_id and return 1.
*/
static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
{
BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
if (atomic_dec_and_test(&cm_id_priv->refcount)) {
BUG_ON(!list_empty(&cm_id_priv->work_list));
complete(&cm_id_priv->destroy_comp);
free_cm_id(cm_id_priv);
return 1;
}

Expand All @@ -208,19 +207,10 @@ static void add_ref(struct iw_cm_id *cm_id)
static void rem_ref(struct iw_cm_id *cm_id)
{
struct iwcm_id_private *cm_id_priv;
int cb_destroy;

cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);

/*
* Test bit before deref in case the cm_id gets freed on another
* thread.
*/
cb_destroy = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
if (iwcm_deref_id(cm_id_priv) && cb_destroy) {
BUG_ON(!list_empty(&cm_id_priv->work_list));
free_cm_id(cm_id_priv);
}
(void)iwcm_deref_id(cm_id_priv);
}

static int cm_event_handler(struct iw_cm_id *cm_id, struct iw_cm_event *event);
Expand Down Expand Up @@ -370,6 +360,12 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
wait_event(cm_id_priv->connect_wait,
!test_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags));

/*
* Since we're deleting the cm_id, drop any events that
* might arrive before the last dereference.
*/
set_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags);

spin_lock_irqsave(&cm_id_priv->lock, flags);
switch (cm_id_priv->state) {
case IW_CM_STATE_LISTEN:
Expand Down Expand Up @@ -433,13 +429,7 @@ void iw_destroy_cm_id(struct iw_cm_id *cm_id)
struct iwcm_id_private *cm_id_priv;

cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
BUG_ON(test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags));

destroy_cm_id(cm_id);

wait_for_completion(&cm_id_priv->destroy_comp);

free_cm_id(cm_id_priv);
}
EXPORT_SYMBOL(iw_destroy_cm_id);

Expand Down Expand Up @@ -809,10 +799,7 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv,
ret = cm_id->cm_handler(cm_id, iw_event);
if (ret) {
iw_cm_reject(cm_id, NULL, 0);
set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
destroy_cm_id(cm_id);
if (atomic_read(&cm_id_priv->refcount)==0)
free_cm_id(cm_id_priv);
iw_destroy_cm_id(cm_id);
}

out:
Expand Down Expand Up @@ -1000,7 +987,6 @@ static void cm_work_handler(struct work_struct *_work)
unsigned long flags;
int empty;
int ret = 0;
int destroy_id;

spin_lock_irqsave(&cm_id_priv->lock, flags);
empty = list_empty(&cm_id_priv->work_list);
Expand All @@ -1013,20 +999,14 @@ static void cm_work_handler(struct work_struct *_work)
put_work(work);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);

ret = process_event(cm_id_priv, &levent);
if (ret) {
set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
destroy_cm_id(&cm_id_priv->id);
}
BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
destroy_id = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
if (iwcm_deref_id(cm_id_priv)) {
if (destroy_id) {
BUG_ON(!list_empty(&cm_id_priv->work_list));
free_cm_id(cm_id_priv);
}
if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) {
ret = process_event(cm_id_priv, &levent);
if (ret)
destroy_cm_id(&cm_id_priv->id);
} else
pr_debug("dropping event %d\n", levent.event);
if (iwcm_deref_id(cm_id_priv))
return;
}
if (empty)
return;
spin_lock_irqsave(&cm_id_priv->lock, flags);
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/core/iwcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct iwcm_id_private {
struct list_head work_free_list;
};

#define IWCM_F_CALLBACK_DESTROY 1
#define IWCM_F_DROP_EVENTS 1
#define IWCM_F_CONNECT_WAIT 2

#endif /* IWCM_H */
6 changes: 5 additions & 1 deletion drivers/infiniband/core/netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,10 @@ static void ibnl_rcv(struct sk_buff *skb)
int ibnl_unicast(struct sk_buff *skb, struct nlmsghdr *nlh,
__u32 pid)
{
return nlmsg_unicast(nls, skb, pid);
int err;

err = netlink_unicast(nls, skb, pid, 0);
return (err < 0) ? err : 0;
}
EXPORT_SYMBOL(ibnl_unicast);

Expand All @@ -252,6 +255,7 @@ int __init ibnl_init(void)
return -ENOMEM;
}

nls->sk_sndtimeo = 10 * HZ;
return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/infiniband/hw/cxgb3/iwch_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1396,10 +1396,10 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
state_set(&child_ep->com, CONNECTING);
child_ep->com.tdev = tdev;
child_ep->com.cm_id = NULL;
child_ep->com.local_addr.sin_family = PF_INET;
child_ep->com.local_addr.sin_family = AF_INET;
child_ep->com.local_addr.sin_port = req->local_port;
child_ep->com.local_addr.sin_addr.s_addr = req->local_ip;
child_ep->com.remote_addr.sin_family = PF_INET;
child_ep->com.remote_addr.sin_family = AF_INET;
child_ep->com.remote_addr.sin_port = req->peer_port;
child_ep->com.remote_addr.sin_addr.s_addr = req->peer_ip;
get_ep(&parent_ep->com);
Expand Down
12 changes: 11 additions & 1 deletion drivers/infiniband/hw/cxgb4/cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3068,9 +3068,9 @@ static int fw4_ack(struct c4iw_dev *dev, struct sk_buff *skb)
PDBG("%s last streaming msg ack ep %p tid %u state %u "
"initiator %u freeing skb\n", __func__, ep, ep->hwtid,
state_read(&ep->com), ep->mpa_attr.initiator ? 1 : 0);
mutex_lock(&ep->com.mutex);
kfree_skb(ep->mpa_skb);
ep->mpa_skb = NULL;
mutex_lock(&ep->com.mutex);
if (test_bit(STOP_MPA_TIMER, &ep->com.flags))
stop_ep_timer(ep);
mutex_unlock(&ep->com.mutex);
Expand Down Expand Up @@ -3647,6 +3647,16 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
ep->com.state = ABORTING;
else {
ep->com.state = CLOSING;

/*
* if we close before we see the fw4_ack() then we fix
* up the timer state since we're reusing it.
*/
if (ep->mpa_skb &&
test_bit(STOP_MPA_TIMER, &ep->com.flags)) {
clear_bit(STOP_MPA_TIMER, &ep->com.flags);
stop_ep_timer(ep);
}
start_ep_timer(ep);
}
set_bit(CLOSE_SENT, &ep->com.flags);
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/cxgb4/iw_cxgb4.h
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ struct c4iw_qp {
struct t4_wq wq;
spinlock_t lock;
struct mutex mutex;
atomic_t refcnt;
struct kref kref;
wait_queue_head_t wait;
struct timer_list timer;
int sq_sig_all;
Expand Down
26 changes: 15 additions & 11 deletions drivers/infiniband/hw/cxgb4/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,30 +603,33 @@ struct ib_mw *c4iw_alloc_mw(struct ib_pd *pd, enum ib_mw_type type,

mhp->dereg_skb = alloc_skb(SGE_MAX_WR_LEN, GFP_KERNEL);
if (!mhp->dereg_skb) {
kfree(mhp);
return ERR_PTR(-ENOMEM);
ret = -ENOMEM;
goto free_mhp;
}

ret = allocate_window(&rhp->rdev, &stag, php->pdid);
if (ret) {
kfree(mhp->dereg_skb);
kfree(mhp);
return ERR_PTR(ret);
}
if (ret)
goto free_skb;
mhp->rhp = rhp;
mhp->attr.pdid = php->pdid;
mhp->attr.type = FW_RI_STAG_MW;
mhp->attr.stag = stag;
mmid = (stag) >> 8;
mhp->ibmw.rkey = stag;
if (insert_handle(rhp, &rhp->mmidr, mhp, mmid)) {
deallocate_window(&rhp->rdev, mhp->attr.stag, mhp->dereg_skb);
kfree(mhp->dereg_skb);
kfree(mhp);
return ERR_PTR(-ENOMEM);
ret = -ENOMEM;
goto dealloc_win;
}
PDBG("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag);
return &(mhp->ibmw);

dealloc_win:
deallocate_window(&rhp->rdev, mhp->attr.stag, mhp->dereg_skb);
free_skb:
kfree_skb(mhp->dereg_skb);
free_mhp:
kfree(mhp);
return ERR_PTR(ret);
}

int c4iw_dealloc_mw(struct ib_mw *mw)
Expand All @@ -640,6 +643,7 @@ int c4iw_dealloc_mw(struct ib_mw *mw)
mmid = (mw->rkey) >> 8;
remove_handle(rhp, &rhp->mmidr, mmid);
deallocate_window(&rhp->rdev, mhp->attr.stag, mhp->dereg_skb);
kfree_skb(mhp->dereg_skb);
kfree(mhp);
PDBG("%s ib_mw %p mmid 0x%x ptr %p\n", __func__, mw, mmid, mhp);
return 0;
Expand Down
30 changes: 23 additions & 7 deletions drivers/infiniband/hw/cxgb4/qp.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,17 +683,25 @@ static int build_inv_stag(union t4_wr *wqe, struct ib_send_wr *wr,
return 0;
}

void _free_qp(struct kref *kref)
{
struct c4iw_qp *qhp;

qhp = container_of(kref, struct c4iw_qp, kref);
PDBG("%s qhp %p\n", __func__, qhp);
kfree(qhp);
}

void c4iw_qp_add_ref(struct ib_qp *qp)
{
PDBG("%s ib_qp %p\n", __func__, qp);
atomic_inc(&(to_c4iw_qp(qp)->refcnt));
kref_get(&to_c4iw_qp(qp)->kref);
}

void c4iw_qp_rem_ref(struct ib_qp *qp)
{
PDBG("%s ib_qp %p\n", __func__, qp);
if (atomic_dec_and_test(&(to_c4iw_qp(qp)->refcnt)))
wake_up(&(to_c4iw_qp(qp)->wait));
kref_put(&to_c4iw_qp(qp)->kref, _free_qp);
}

static void add_to_fc_list(struct list_head *head, struct list_head *entry)
Expand Down Expand Up @@ -1594,8 +1602,6 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
wait_event(qhp->wait, !qhp->ep);

remove_handle(rhp, &rhp->qpidr, qhp->wq.sq.qid);
atomic_dec(&qhp->refcnt);
wait_event(qhp->wait, !atomic_read(&qhp->refcnt));

spin_lock_irq(&rhp->lock);
if (!list_empty(&qhp->db_fc_entry))
Expand All @@ -1608,8 +1614,9 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
destroy_qp(&rhp->rdev, &qhp->wq,
ucontext ? &ucontext->uctx : &rhp->rdev.uctx);

c4iw_qp_rem_ref(ib_qp);

PDBG("%s ib_qp %p qpid 0x%0x\n", __func__, ib_qp, qhp->wq.sq.qid);
kfree(qhp);
return 0;
}

Expand Down Expand Up @@ -1706,7 +1713,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
init_completion(&qhp->rq_drained);
mutex_init(&qhp->mutex);
init_waitqueue_head(&qhp->wait);
atomic_set(&qhp->refcnt, 1);
kref_init(&qhp->kref);

ret = insert_handle(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
if (ret)
Expand Down Expand Up @@ -1898,12 +1905,20 @@ int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
return 0;
}

static void move_qp_to_err(struct c4iw_qp *qp)
{
struct c4iw_qp_attributes attrs = { .next_state = C4IW_QP_STATE_ERROR };

(void)c4iw_modify_qp(qp->rhp, qp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
}

void c4iw_drain_sq(struct ib_qp *ibqp)
{
struct c4iw_qp *qp = to_c4iw_qp(ibqp);
unsigned long flag;
bool need_to_wait;

move_qp_to_err(qp);
spin_lock_irqsave(&qp->lock, flag);
need_to_wait = !t4_sq_empty(&qp->wq);
spin_unlock_irqrestore(&qp->lock, flag);
Expand All @@ -1918,6 +1933,7 @@ void c4iw_drain_rq(struct ib_qp *ibqp)
unsigned long flag;
bool need_to_wait;

move_qp_to_err(qp);
spin_lock_irqsave(&qp->lock, flag);
need_to_wait = !t4_rq_empty(&qp->wq);
spin_unlock_irqrestore(&qp->lock, flag);
Expand Down
19 changes: 6 additions & 13 deletions drivers/infiniband/hw/mlx5/gsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,16 @@ static bool mlx5_ib_deth_sqpn_cap(struct mlx5_ib_dev *dev)
return MLX5_CAP_GEN(dev->mdev, set_deth_sqpn);
}

static u32 next_outstanding(struct mlx5_ib_gsi_qp *gsi, u32 index)
{
return ++index % gsi->cap.max_send_wr;
}

#define for_each_outstanding_wr(gsi, index) \
for (index = gsi->outstanding_ci; index != gsi->outstanding_pi; \
index = next_outstanding(gsi, index))

/* Call with gsi->lock locked */
static void generate_completions(struct mlx5_ib_gsi_qp *gsi)
{
struct ib_cq *gsi_cq = gsi->ibqp.send_cq;
struct mlx5_ib_gsi_wr *wr;
u32 index;

for_each_outstanding_wr(gsi, index) {
wr = &gsi->outstanding_wrs[index];
for (index = gsi->outstanding_ci; index != gsi->outstanding_pi;
index++) {
wr = &gsi->outstanding_wrs[index % gsi->cap.max_send_wr];

if (!wr->completed)
break;
Expand Down Expand Up @@ -430,8 +422,9 @@ static int mlx5_ib_add_outstanding_wr(struct mlx5_ib_gsi_qp *gsi,
return -ENOMEM;
}

gsi_wr = &gsi->outstanding_wrs[gsi->outstanding_pi];
gsi->outstanding_pi = next_outstanding(gsi, gsi->outstanding_pi);
gsi_wr = &gsi->outstanding_wrs[gsi->outstanding_pi %
gsi->cap.max_send_wr];
gsi->outstanding_pi++;

if (!wc) {
memset(&gsi_wr->wc, 0, sizeof(gsi_wr->wc));
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/mlx5/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2574,7 +2574,7 @@ static int mlx5_ib_alloc_q_counters(struct mlx5_ib_dev *dev)
return ret;
}

static const char const *names[] = {
static const char * const names[] = {
"rx_write_requests",
"rx_read_requests",
"rx_atomic_requests",
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/mlx5/qp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2657,7 +2657,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
struct mlx5_ib_port *mibport = &dev->port[port_num];

context->qp_counter_set_usr_page |=
cpu_to_be32(mibport->q_cnt_id << 16);
cpu_to_be32((u32)(mibport->q_cnt_id) << 24);
}

if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
Expand Down

0 comments on commit 3e5e8e8

Please sign in to comment.