···183183184184/*185185 * Release a reference on cm_id. If the last reference is being186186- * released, enable the waiting thread (in iw_destroy_cm_id) to187187- * get woken up, and return 1 if a thread is already waiting.186186+ * released, free the cm_id and return 1.188187 */189188static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv)190189{191190 BUG_ON(atomic_read(&cm_id_priv->refcount)==0);192191 if (atomic_dec_and_test(&cm_id_priv->refcount)) {193192 BUG_ON(!list_empty(&cm_id_priv->work_list));194194- complete(&cm_id_priv->destroy_comp);193193+ free_cm_id(cm_id_priv);195194 return 1;196195 }197196···207208static void rem_ref(struct iw_cm_id *cm_id)208209{209210 struct iwcm_id_private *cm_id_priv;210210- int cb_destroy;211211212212 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);213213214214- /*215215- * Test bit before deref in case the cm_id gets freed on another216216- * thread.217217- */218218- cb_destroy = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);219219- if (iwcm_deref_id(cm_id_priv) && cb_destroy) {220220- BUG_ON(!list_empty(&cm_id_priv->work_list));221221- free_cm_id(cm_id_priv);222222- }214214+ (void)iwcm_deref_id(cm_id_priv);223215}224216225217static int cm_event_handler(struct iw_cm_id *cm_id, struct iw_cm_event *event);···360370 wait_event(cm_id_priv->connect_wait,361371 !test_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags));362372373373+ /*374374+ * Since we're deleting the cm_id, drop any events that375375+ * might arrive before the last dereference.376376+ */377377+ set_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags);378378+363379 spin_lock_irqsave(&cm_id_priv->lock, flags);364380 switch (cm_id_priv->state) {365381 case IW_CM_STATE_LISTEN:···429433 struct iwcm_id_private *cm_id_priv;430434431435 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);432432- BUG_ON(test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags));433433-434436 destroy_cm_id(cm_id);435435-436436- wait_for_completion(&cm_id_priv->destroy_comp);437437-438438- free_cm_id(cm_id_priv);439437}440438EXPORT_SYMBOL(iw_destroy_cm_id);441439···799809 ret = cm_id->cm_handler(cm_id, iw_event);800810 if (ret) {801811 iw_cm_reject(cm_id, NULL, 0);802802- set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);803803- destroy_cm_id(cm_id);804804- if (atomic_read(&cm_id_priv->refcount)==0)805805- free_cm_id(cm_id_priv);812812+ iw_destroy_cm_id(cm_id);806813 }807814808815out:···9871000 unsigned long flags;9881001 int empty;9891002 int ret = 0;990990- int destroy_id;99110039921004 spin_lock_irqsave(&cm_id_priv->lock, flags);9931005 empty = list_empty(&cm_id_priv->work_list);···9991013 put_work(work);10001014 spin_unlock_irqrestore(&cm_id_priv->lock, flags);1001101510021002- ret = process_event(cm_id_priv, &levent);10031003- if (ret) {10041004- set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);10051005- destroy_cm_id(&cm_id_priv->id);10061006- }10071007- BUG_ON(atomic_read(&cm_id_priv->refcount)==0);10081008- destroy_id = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);10091009- if (iwcm_deref_id(cm_id_priv)) {10101010- if (destroy_id) {10111011- BUG_ON(!list_empty(&cm_id_priv->work_list));10121012- free_cm_id(cm_id_priv);10131013- }10161016+ if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) {10171017+ ret = process_event(cm_id_priv, &levent);10181018+ if (ret)10191019+ destroy_cm_id(&cm_id_priv->id);10201020+ } else10211021+ pr_debug("dropping event %d\n", levent.event);10221022+ if (iwcm_deref_id(cm_id_priv))10141023 return;10151015- }10161024 if (empty)10171025 return;10181026 spin_lock_irqsave(&cm_id_priv->lock, flags);
···30683068 PDBG("%s last streaming msg ack ep %p tid %u state %u "30693069 "initiator %u freeing skb\n", __func__, ep, ep->hwtid,30703070 state_read(&ep->com), ep->mpa_attr.initiator ? 1 : 0);30713071+ mutex_lock(&ep->com.mutex);30713072 kfree_skb(ep->mpa_skb);30723073 ep->mpa_skb = NULL;30733073- mutex_lock(&ep->com.mutex);30743074 if (test_bit(STOP_MPA_TIMER, &ep->com.flags))30753075 stop_ep_timer(ep);30763076 mutex_unlock(&ep->com.mutex);···36473647 ep->com.state = ABORTING;36483648 else {36493649 ep->com.state = CLOSING;36503650+36513651+ /*36523652+ * if we close before we see the fw4_ack() then we fix36533653+ * up the timer state since we're reusing it.36543654+ */36553655+ if (ep->mpa_skb &&36563656+ test_bit(STOP_MPA_TIMER, &ep->com.flags)) {36573657+ clear_bit(STOP_MPA_TIMER, &ep->com.flags);36583658+ stop_ep_timer(ep);36593659+ }36503660 start_ep_timer(ep);36513661 }36523662 set_bit(CLOSE_SENT, &ep->com.flags);