Re: mISDN_send: error -12 strikes again

Ralf Schlatterbeck <[email protected]>
Newsgroups gmane.linux.isdn.i4l.user
Message-ID <[email protected]>
On Sun, Mar 18, 2012 at 05:53:30PM +0100, Ralf Schlatterbeck wrote:
> On Sun, Mar 18, 2012 at 07:29:08AM +0100, jolly wrote:
> > Ralf Schlatterbeck wrote:
> > > Yesterday we had the message "mISDN_send: error -12" filling
> > > /var/log/kern.log. Restarting asterisk "fixed" it.

> > hi ralf,
> > 
> > i guess it is because chan_lcr runs into deadlock inside asterisk. since
> > the process of chan_lcr holds a lock and never returns after calling
> > some asterisk function, bchannel read will not be processed, so the
> > kernel drops messages to prevent overfill. this is why you receive the
> > message above.
> 
> Yes, I've debugged this once and am following that bug for some time
> now... the kernel message simply indicates that we have a buffer
> overflow in kernel space, nobody is fetching the data.
> 
> > i suggest do debug which process calls the chan_lcr global lock and
> > unlock function. then, if asterisk hangs, use gdb to do backtrace all
> > threads of asterisk. you can see against which lock each thread runs.
> > since locking mechanism of asterisk is quite complex and unknown to me,
> > you might be on your own with that.

Problem with this approach is that we will do an automatic restart of
asterisk now once this happens again. So I've coded my own lock
debugging. When I ran this I observed that asterisk locks are
implemented using pthread locks with the PTHREAD_MUTEX_RECURSIVE
feature. This means the same thread can lock the same mutex multiple
times as long as lock/unlocks are properly nested. When the lock-count
reaches 0, other threads are free to obtain a lock.

> I've looked through the locking code and have some questions:
> - I don't understand why in lcr_hangup the lock is only obtained if the
>   thread is different from the lcr thread.

The more I think about this, the more I think it is wrong: This is
not used in other channel drivers I've examined. Even if this function
would be called when the thread already *has* a lock, this would not be
a problem (see above). On the other hand I think this can lead to an
inconsistent state if we modify data structures without a lock: the
asterisk thread and the lcr thread can concurrently modify data
structures here.

Maybe the error is not due to a deadlock but due to modification of data
structures without a lock? Is it possible that chan_lcr stops fetching
data from a socket when it no longer thinks there is an active call
because it has lost a reference for an active call?

A fact that supports this suspicion is that we observed different
channel counts in 'lcradmin state' and asterisk: asterisk hat only sip
channels while lcradmin showed three open connections. This was shortly
before asterisk was restarted after an hour in the error-state.

Ralf
-- 
Ralf Schlatterbeck             email: [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.