[Openib-windows] A problem in ib_close_al

Leonid Keller leonid at mellanox.co.il
Wed Jul 19 09:32:57 PDT 2006


One more question.
Look at __cleanup_pool_key():

__cleanup_pool_key(
	IN				al_obj_t*
p_obj )
{
	...
	CL_ASSERT( !p_pool_key->mad_cnt );
	...
	if( p_pool_key->mad_cnt ) 
	{
		// release mad_list
	}
}

Questions:
	(minor) Why you expect mad_cnt=0 in ASSERT and then release the
MADs ?
	(major) Why do we need to release MADs *here* at all?
		( Because if there is at least one MAD, not released to
pool, 
		  __cleanup_pool_key() will be never called! )



> -----Original Message-----
> From: Leonid Keller 
> Sent: Tuesday, July 18, 2006 9:08 PM
> To: 'Fabian Tillier'
> Cc: openib-windows at openib.org
> Subject: RE: [Openib-windows] A problem in ib_close_al
> Importance: High
> 
> I'm still investigating the stuck on shutdown and see a lot 
> of "strange" things, look like bugs.
> Sure, I'm missing something, but ...
> 
> Here are the questions:
> 
> 1. mad_list in AL object: 
>    usually protected by mad_lock, but ...
> 	sometimes - by h_al->obj.lock:
> 		- __cleanup_pool_key();
> 		- __proxy_cleanup_map();	 
> 	sometimes - not protected at all:
> 		- __proxy_mad_recv_cb;
> 		- __free_mads()
> 
> 2. recv_queue in SPL_QP_SVC object: 
>    usually protected by p_spl_qp_svc->obj.lock, but is not 
> protected in:
> 	- create_spl_qp_svc() (call to spl_qp_svc_post_recvs());
> 	- spl_qp_svc_reset_cb()(call to spl_qp_svc_post_recvs());
> 	- free_spl_qp_svc();
> 
> 3. send_queue in SPL_QP_SVC object: 
>    usually protected by p_spl_qp_svc->obj.lock, but is not 
> protected in:
> 	- spl_qp_svc_reset_cb();
> 
> 4. may be the same problems exist with other link lists, like
> 	- recv_queue in AL_MAD_QP object;
> 	- send_queue in AL_MAD_QP object;
> 	- et al
> 
> See, please, also my comments below.
> 
> 
> > -----Original Message-----
> > From: ftillier.sst at gmail.com 
> [mailto:ftillier.sst at gmail.com] On Behalf 
> > Of Fabian Tillier
> > Sent: Wednesday, July 12, 2006 7:33 PM
> > To: Leonid Keller
> > Cc: openib-windows at openib.org
> > Subject: Re: [Openib-windows] A problem in ib_close_al
> > 
> > Hi Leonid,
> > 
> > On 7/12/06, Leonid Keller <leonid at mellanox.co.il> wrote:
> > >
> > > > -----Original Message-----
> > > > From: ftillier.sst at gmail.com [mailto:ftillier.sst at gmail.com] On 
> > > > Behalf Of Fabian Tillier
> > > > Sent: Tuesday, July 11, 2006 9:18 PM
> > > >
> > > > Hi Leo,
> > > >
> > > > On 7/10/06, Leonid Keller <leonid at mellanox.co.il> wrote:
> > > > > Hi Fab,
> > > > > Our regression uses to run opensm and then kill it at
> > some moment.
> > > > > Sometimes opensm enters "zombi" state and there is no
> > way to kill
> > > > > it.
> > > > > I've investigated that and found that it is stuck on
> > infinite loop
> > > > > in sync_destroy_obj while destroying opensm's instance of AL.
> > > > > I saw ref_cnt = 13 and mad_list of AL object contained
> > 13 records.
> > > >
> > > > The proxy code should free all outstanding MADs before calling 
> > > > ib_close_al - see the code path in al_dev_close
> > (al_dev.c at 371).  The
> > > > call to __proxy_cleanup_map will free all MADs queued
> > internally.  
> > > > Do you know what these MADs are from?  Are they received
> > MADs that
> > > > were not delivered to the client?  Or are they send 
> MADs that are 
> > > > waiting to be sent?
> > > >
> > > I don't know so far how to reproduce that so:
> > > Is there a way to tell received MADs from sent ones apart
> > from adding
> > > a mad_type field anywhere and setting it after every call to
> > > ib_get_mad() ?
> > 
> > You can look at the MAD header - the method should indicate 
> whether it 
> > is a send or a receive.  The ib_get_mad function cannot set whether 
> > the MAD will be used for a send or receive, as that is not an input 
> > parameter.  It cannot be an input parameter anyway as it is 
> valid for 
> > a received MAD to be used to send a response without 
> putting the MAD 
> > back into the pool.
> > 
> 
> Now, after SPL_QP_SVC has been destroyed, I see CI_CA object 
> stuck with several IB_MAD_METHOD_GETTABLE_RESP MADs, which 
> were taken yet in create_spl_qp_svc() (I mark on the MAD, in 
> what function it was taken).
>  
> 
> 
> > > > > I think, the problem is in that, that mad_list is freed in
> > > > > free_al()
> > > > > which can't be called before ref_cnt = 0, which can 
> become such 
> > > > > only after calling free_al().
> > > >
> > > > Yes, we have a chicken and egg issue here.  The free_mads
> > function
> > > > is there to do internal cleanup if we proceed with
> > destruction when
> > > > the reference count doesn't hit zero.  Note that this can only 
> > > > happen in a debug build (where destruction will
> > eventually timeout
> > > > and blow the object away).
> > > >
> > > > > I've prepared a patch which calls __free_mads() from AL
> > destroying
> > > > > function.
> > > >
> > > > We could call __free_mads from the destroying_al
> > function, but this
> > > > wouldn't necessarilly prevent MADs from being queued after that 
> > > > function is called, but before the AL object moves to 
> the cleanup 
> > > > phase of destruction (after all references are released).
> > 
> > I just realized that we cannot call __free_mads from the 
> destroying_al 
> > function - it is never safe to reclaim a MAD that a user is using.
> > 
> > > I'm working now on a stuck during shutdown after 
> regression, which 
> > > (the
> > > stuck) we experiences constantly. The function stuck is 
> > > ib_deregister_ca(), which stands in sync_destroy_obj(),
> > waiting for CA
> > > to release it, which is in turn hold by its PD object.
> > > Today I revealed that the PD object is hold by several 
> mads, taken 
> > > once from the pool_key of CI_CA. It reminds the problem, being 
> > > discussed here and I'll appreciate if you could suggest an
> > idea, why
> > > wouldn't these mads be released by __cleanup_pool_key().
> > 
> > You can't pull MADs back from a user if that user is using it.  The 
> > user *must* return the MADs.  The MAD tracking list in IBAL is for 
> > debugging purposes only.  If a MAD is in the tracking list it means 
> > that a client has pulled that MAD out of the pool.  It is not 
> > technically safe to just put the MAD back in the pool, as 
> the user may 
> > still be accessing it.  If the user later tries to return 
> the MAD, you 
> > will very likely get a system crash.
> > 
> > > For now I have an idea that probably could solve both problems:
> > > What if we forbid inserting of new MADs while the AL object
> > is being
> > > destroyed ?
> > 
> > The tracking list is there only to track MADs - it is there only to 
> > allow debugging so that we know what instance of AL has what MADs 
> > outstanding.  We can't reclaim these automatically - we 
> need to figure 
> > out why they aren't being returned to the pool.
> 
> It's not just for debugging, if you use it in 
> __cleanup_pool_key() to release the pool_key.
> 
> > 
> > > Say, by returning an error from ib_get_mad() when 
> > > (pool_key->h_al->obj.type == CL_DESTROYING) ?
> > > I can prepare a patch if you don't mind.
> > 
> > If AL is destroying so will the pool_key object, so there's 
> no need to 
> > check AL.  Destruction is initiated on all child objects as 
> soon as it 
> > is initiated on the parent.  The ib_get_mad function already checks 
> > the state of the pool, and fails if the pool is not in the 
> > CL_INITIALIZED state.
> > 
> 
> It's not quite so. 
> ib_deregister_ca() initiates destroy of CI_CA and 
> consequently CA, but not AL.
> I saw calls to ib_get_mad() during CI_CA destroying. Her is 
> an example of debug print:
> 
> ***** ib_get_mad: MAD taken during destroying. pool_key 
> FFFFFADFCCFBE010, al_mad FFFFFADFCD1C8010, ib_mad 
> FFFFFADFCD1C8038, pool_state 2, ci_ca_state 3
> 
> 
> > > > A MAD completion that happens just after the
> > destroying_al function
> > > > returns would be able to insert the MAD in the tracking
> > list if the
> > > > AL instance still had some other reference held.
> > > >
> > > > __free_mads must be called from free_al though we could
> > call it from
> > > > destroying_al too, but as I said that doesn't solve the problem.
> > >
> > > If we can prevent adding new MADs while AL object
> > destroying, it will
> > > be OK to call __free_mads from destroying_al.
> > 
> > Calling __free_mads is only possible in debug builds, after you've 
> > ignored the assertion hit because destruction timed out.  
> __free_mads 
> > is not a function that can be called to reclaim MADs while 
> users are 
> > using them.  What we need to do is find out who/why the MADs aren't 
> > being returned to their pool, and fix that.
> > 
> > - Fab
> > 




More information about the ofw mailing list