Commit 85cbb7c7 authored by Mike Marciniszyn's avatar Mike Marciniszyn Committed by Roland Dreier

IB/qib: Correct reference counting in debugfs qp_stats

This particular reference count is not needed with the rcu protection,
and the current code leaks a reference count, causing a hang in
qib_qp_destroy().

Cc: <stable@vger.kernel.org>
Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent f5c4984e
...@@ -193,6 +193,7 @@ static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos) ...@@ -193,6 +193,7 @@ static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
struct qib_qp_iter *iter; struct qib_qp_iter *iter;
loff_t n = *pos; loff_t n = *pos;
rcu_read_lock();
iter = qib_qp_iter_init(s->private); iter = qib_qp_iter_init(s->private);
if (!iter) if (!iter)
return NULL; return NULL;
...@@ -224,7 +225,7 @@ static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr, ...@@ -224,7 +225,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) static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr)
{ {
/* nothing for now */ rcu_read_unlock();
} }
static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr) static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr)
......
...@@ -1325,7 +1325,6 @@ int qib_qp_iter_next(struct qib_qp_iter *iter) ...@@ -1325,7 +1325,6 @@ int qib_qp_iter_next(struct qib_qp_iter *iter)
struct qib_qp *pqp = iter->qp; struct qib_qp *pqp = iter->qp;
struct qib_qp *qp; struct qib_qp *qp;
rcu_read_lock();
for (; n < dev->qp_table_size; n++) { for (; n < dev->qp_table_size; n++) {
if (pqp) if (pqp)
qp = rcu_dereference(pqp->next); qp = rcu_dereference(pqp->next);
...@@ -1333,18 +1332,11 @@ int qib_qp_iter_next(struct qib_qp_iter *iter) ...@@ -1333,18 +1332,11 @@ int qib_qp_iter_next(struct qib_qp_iter *iter)
qp = rcu_dereference(dev->qp_table[n]); qp = rcu_dereference(dev->qp_table[n]);
pqp = qp; pqp = qp;
if (qp) { if (qp) {
if (iter->qp)
atomic_dec(&iter->qp->refcount);
atomic_inc(&qp->refcount);
rcu_read_unlock();
iter->qp = qp; iter->qp = qp;
iter->n = n; iter->n = n;
return 0; return 0;
} }
} }
rcu_read_unlock();
if (iter->qp)
atomic_dec(&iter->qp->refcount);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment