EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: EPICS/asyn problem
From: "Mark Rivers" <[email protected]>
To: "Andrew Johnson" <[email protected]>, "Marty Kraimer" <[email protected]>
Cc: Eric Norum <[email protected]>, [email protected]
Date: Tue, 16 Feb 2010 10:26:14 -0600
Thanks Marty and Andrew,
 
I had just figured out that it was indeed callbackSetQueueSize and not scanOncrSetQueueSize that I needed.  It does indeed fix the problem.
 
Thanks,
Mark
 

________________________________

From: Andrew Johnson [mailto:[email protected]]
Sent: Tue 2/16/2010 10:21 AM
To: Marty Kraimer
Cc: Mark Rivers; Eric Norum; [email protected]
Subject: Re: EPICS/asyn problem



Hi Marty,

Thanks for reminding me...

On Tuesday 16 February 2010 04:28:38 Marty Kraimer wrote:
> In the st.cmd file call
>
> scanOnceSetQueueSize(size)

That sets the buffer for the scanOnce task; Mark's problem is with the queue
for the callback tasks, which have their own ring buffer.  The routine and
iocsh command for setting the callback buffer sizes is:

int callbackSetQueueSize(int size);

This must be run before iocInit, and I believe can be used to solve Mark's
problem at the expense of some RAM which is only really needed at start-up.

Should we consider making those two void routines return an error status?  We
can't really do that in scanIoRequest() because if necessary it can push an
io_scan_list from each IOSCANPVT onto all three priority queues, and there's
have no easy way to report a failure for a specific callback queue, or to re-
do a request for a subset of its queues.  Therefore I don't think there's much
point in flagging this kind of failure to the caller, the user has to be
involved in fixing it.

- Andrew

> Mark Rivers wrote:
> > Folks,
> >
> > I have run into a fairly serious problem with asyn and EPICS base.
> >
> > Standard asyn device support allows for I/O Intr scanned records.  The
> > driver does a callback to device support with a new value, and device
> > support in turn calls scanIoRequest to process the record.  When the
> > record processes it reads the "cached" data that was passed to the
> > callback, rather than actually reading from the device.
> >
> > This generally works fine.  However, I  have just run into a serious
> > problem when the number of callback requests is very large.  This is
> > happening at iocInit in a system with lots of records that are I/O Intr
> > scanned.  The problem is a ring buffer overflow in the cbLow task.
> >
> > The sequence of calls is
> >
> > driver->asyn device support->scanIoRequest->callbackRequest.
> >
> > This is the code from EPICS base for callback request.
> >
> > void callbackRequest(CALLBACK *pcallback)
> > {
> >     int priority;
> >     int pushOK;
> >     int lockKey;
> >     if (!pcallback) {
> >         epicsPrintf("callbackRequest called with NULL pcallback\n");
> >         return;
> >     }
> >     priority = pcallback->priority;
> >     if (priority < 0 || priority >= NUM_CALLBACK_PRIORITIES) {
> >         epicsPrintf("callbackRequest called with invalid priority\n");
> >         return;
> >     }
> >     if (ringOverflow[priority]) return;
> >     lockKey = epicsInterruptLock();
> >     pushOK = epicsRingPointerPush(callbackQ[priority], pcallback);
> >     epicsInterruptUnlock(lockKey);
> >     if (!pushOK) {
> >         errlogPrintf("callbackRequest: %s ring buffer full\n",
> >             threadName[priority]);
> >         ringOverflow[priority] = TRUE;
> >     }
> >     epicsEventSignal(callbackSem[priority]);
> > }
> >
> > Note that it is a void function, and thus does not return an error status
> > when the ring buffer is full.  Why not?
> >
> > This is the code for scanIoRequest:
> >
> > void scanIoRequest(IOSCANPVT pioscanpvt)
> > {
> >     int prio;
> >     if (scanCtl != ctlRun) return;
> >     for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
> >         io_scan_list *piosl = &pioscanpvt[prio];
> >         if (ellCount(&piosl->scan_list.list) > 0)
> >             callbackRequest(&piosl->callback);
> >     }
> > }
> >
> > It is also a void function, and so cannot return an error from
> > callbackRequest even if it could return one.
> >
> > The ring pointer buffer is created with this line in callbackInitOnce:
> >         callbackQ[i] = epicsRingPointerCreate(callbackQueueSize);
> >
> > callbackQueueSize is defined with this line:
> > static int callbackQueueSize = 2000;
> >
> > Thus, if there are more than 2000 unprocessed scanIoRequest calls there
> > will be an error which cannot be caught.
> >
> > This is a serious problem for me.  My XIA detector driver is doing
> > callbacks to device support for >4000 records shortly after iocInit.
> > This will soon grow to 20,000 when a 100 element detector at the
> > Australian Synchrotron starts to use this driver.  I am now getting these
> > errors when I start a system with 16 detectors:
> >
> > callbackRequest: cbLow ring buffer full
> >
> > This very large number of callbacks will typically only happen right
> > after iocInit.  In this case I would be willing to change the asyn device
> > support as follows:
> >
> > - Test if scanIoRequest succeeded
> > - If it failed because of ring buffer full then do a short sleep and try
> > again, up to some maximum number of retries
> >
> > But I cannot implement this logic because scanIoRequest does not return a
> > failure status, so I don't know if it worked or not.
> >
> > What should be done?
> >
> > Thanks,
> > Mark


--
The best FOSS code is written to be read by other humans -- Harald Welte





References:
EPICS/asyn problem Mark Rivers
Re: EPICS/asyn problem Marty Kraimer
Re: EPICS/asyn problem Andrew Johnson

Navigate by Date:
Prev: Re: EPICS/asyn problem Andrew Johnson
Next: PCaPAC 2010 Opens for Submission of Abstracts Elder Matias
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: EPICS/asyn problem Andrew Johnson
Next: ITER CODAC Core System Version 1 has been released. Di Maio Franck
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Sep 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·