[openib-general] [PATCH] RDMA/iwcm: Bugs in cm_conn_req_handler()

Tom Tucker tom at opengridcomputing.com
Fri Feb 9 07:41:08 PST 2007


Roland:

This looks bad. Lemme noodle...

On Thu, 2007-02-08 at 20:23 -0800, Roland Dreier wrote:
> BTW, while looking at iwcm.c, I noticed the following highly dubious
> code for the first time:
> 
> 	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 ret;
> 	}
> 
> The test of waitqueue_active on destroy_comp.wait looks really bad for
> two reasons: first, it is relying on an internal implementation detail
> of struct completion that really shouldn't be used by generic code.
> And second, it seems to me that this doesn't even work right, since
> there is a race something like the following:
> 
> iw_destroy_cm_id():
> destroy_cm_id(cm_id); // still 1 ref left
> 
> 				cm_work_handler():
> 					if (iwcm_deref_id()) // drop last ref
> 						return;
> 					// no one waiting yet, doesn't
> 					// return, but destroy_comp is
> 					// signaled
> 
> wait_for_completion(&cm_id_priv->destroy_comp);
> // destroy_comp is signaled, proceed
> kfree(cm_id_priv);
> 
> 					// continue using cm_id_priv
> 					// OOPS
> 
> I don't understand this code well enough for the fix to be obvious.
> 
>  - R.





More information about the general mailing list