Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 48792
b: refs/heads/master
c: ebb9098
h: refs/heads/master
v: v3
  • Loading branch information
Steve Wise authored and Roland Dreier committed Feb 16, 2007
1 parent bac050b commit 9c9b70f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6bbcea0d42209ab5f0fae213050ad042c499ad8b
refs/heads/master: ebb90986e183296086b5d6678a838f125d743982
47 changes: 25 additions & 22 deletions trunk/drivers/infiniband/core/iwcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,28 +146,27 @@ static int copy_private_data(struct iw_cm_event *event)
return 0;
}

static void free_cm_id(struct iwcm_id_private *cm_id_priv)
{
dealloc_work_entries(cm_id_priv);
kfree(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.
*/
static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
{
int ret = 0;

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));
if (waitqueue_active(&cm_id_priv->destroy_comp.wait)) {
BUG_ON(cm_id_priv->state != IW_CM_STATE_DESTROYING);
BUG_ON(test_bit(IWCM_F_CALLBACK_DESTROY,
&cm_id_priv->flags));
ret = 1;
}
complete(&cm_id_priv->destroy_comp);
return 1;
}

return ret;
return 0;
}

static void add_ref(struct iw_cm_id *cm_id)
Expand All @@ -181,7 +180,11 @@ static void rem_ref(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);
iwcm_deref_id(cm_id_priv);
if (iwcm_deref_id(cm_id_priv) &&
test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
BUG_ON(!list_empty(&cm_id_priv->work_list));
free_cm_id(cm_id_priv);
}
}

static int cm_event_handler(struct iw_cm_id *cm_id, struct iw_cm_event *event);
Expand Down Expand Up @@ -355,7 +358,9 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
case IW_CM_STATE_CONN_RECV:
/*
* App called destroy before/without calling accept after
* receiving connection request event notification.
* receiving connection request event notification or
* returned non zero from the event callback function.
* In either case, must tell the provider to reject.
*/
cm_id_priv->state = IW_CM_STATE_DESTROYING;
break;
Expand Down Expand Up @@ -391,9 +396,7 @@ void iw_destroy_cm_id(struct iw_cm_id *cm_id)

wait_for_completion(&cm_id_priv->destroy_comp);

dealloc_work_entries(cm_id_priv);

kfree(cm_id_priv);
free_cm_id(cm_id_priv);
}
EXPORT_SYMBOL(iw_destroy_cm_id);

Expand Down Expand Up @@ -647,10 +650,11 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv,
/* Call the client CM handler */
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)
kfree(cm_id);
free_cm_id(cm_id_priv);
}

out:
Expand Down Expand Up @@ -854,13 +858,12 @@ static void cm_work_handler(struct work_struct *_work)
destroy_cm_id(&cm_id_priv->id);
}
BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
if (iwcm_deref_id(cm_id_priv))
return;

if (atomic_read(&cm_id_priv->refcount)==0 &&
test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
dealloc_work_entries(cm_id_priv);
kfree(cm_id_priv);
if (iwcm_deref_id(cm_id_priv)) {
if (test_bit(IWCM_F_CALLBACK_DESTROY,
&cm_id_priv->flags)) {
BUG_ON(!list_empty(&cm_id_priv->work_list));
free_cm_id(cm_id_priv);
}
return;
}
spin_lock_irqsave(&cm_id_priv->lock, flags);
Expand Down

0 comments on commit 9c9b70f

Please sign in to comment.