--- Dave Grothe <[EMAIL PROTECTED]> wrote:
> The tradeoff between spin locks and semaphores for queue routine entries is
> that with spin locks you are severely restricted as to what you can do with
> the kernel, and even more so in 2.6. That's why the semaphore.
>
> The more recent "lettered" versions of LiS provide for a construct in the
> Config file in which you can declare the degree of locking (semaphore)
> protection upon entry to put/srv routines.
>
> qlock driver <driver-name> <value>
>
> The <value> is as follows:
>
> 0 = no locking
> 1 = lock each q half individually (defaul)
> 2 = lock both q halves together
> 3 = use a global lock
>
> Type 1 is the old LiS behavior. Drivers that are written defensively for
> SMP environments can probably run with option 0. With no locking at all it
> no longer matters whether you do putnext() from interrupt level.
So these options are global for all streams drivers/modules/multiplexors?
The option applies on a per-driver basis. If you driver is loadable and has no Config file you can call a registration routine in LiS from your driver's module init function to declare your locking style.
int lis_register_module_qlock_option(modID_t id, int qlock_option);
> Personally, I don't like calling putnext() from interrupt context.
When you are trying to deliver something in a timely fashion like a timer
indication, it helps to not have all of the overhead and additional delay of
having to run the service routine. I wouldn't do it for data although some
drivers, most noteably the hme driver on Solaris, do just that.
Solaris gets away with that kind of stuff because they run interrupts in dedicated threads. Since interrupt routines have thread context they can get mutexes that cause sleeps with no damage to the system.
I'll give the lettered versions a try and see if this at least fixes the
panic, but in the near term we have to go with the "released" version of LiS.
I'm trying to get to a released version out but keep getting diverted.
> So I would have coded this construct to fabricate the indication message
> and do a putq() into the read queue so as to let the service procedure send
> it upstream from guaranteed non-interrupt context.
So I take it that a timeout is indeed an "interrupt context". In fact
experimentation proves just that. The only way I could get this to work at
all was to do just this, put the message on a local private queue in my
connection structure and deliver it from the read service routine. I didn't
want to use putq() because I don't need all the additional putq() overhead
(byte counting and all the rest...) I just need the message delivered and
fast...j
That technique works nicely.
Do you have any additional insights into how to debug these locking problems?
I cannot for the life of me actually see deadly embraces with kgdb even when
I know I'm in one.
First you need to compile LiS for the development version so that the locks have information about who owns them and who is spinning/waiting.
Second, of course you need to compile LiS with -g, but you probably knew that. And if you are using kgdb then you kernel was compiled with -g as well.
Third, I have had problems with gdb and threads that are waiting on semaphores or spinning on locks. The stack frame chain is broken by the assembler code in the kernel so gdb cannot peel the stack back. I have written some gdb macros to follow the stack back using an "ebp" chain. I have attached that code as stack.gdb. The command is "stk $ebp". What I then sometimes do is force a value into ebp from one of the stack frames BELOW the spin lock or semaphore call. Then, sometimes, "bt" will work again and you can then use the "up" and "down" commands.
Also, just for fun, I am enclosing another set of gdb macros in cp.gdb. These are useful for printing out the LiS code path table in an easily readable manner. Example:
code_path_range 450 499
Print out a range of code path entries from 450 to 499 inclusively.
You can get the index of the next code path point with:
p lis_code_path_ptr - lis_code_path_tbl
Good luck
Dave
cp.gdb
Description: Binary data
stack.gdb
Description: Binary data
