From: James S. <jsi...@su...> - 2001-01-17 00:05:29
|
Some time ago a intel i810 framebuffer driver was written. It only worked for 2.2.X. With 2.4.X a spinlock is used in the upper layers of the console system. Sooner or later we are going to run into the situtation where we will have graphics hardware which has no vga core and wih be purely DMA/irq based (i.e i810). In this case using the current console_lock will block the driver itself. I have thought about a possible solution. A semaphore can't be used since their is a spin_lock in the console_softirq. Since this is in a interrupt context a semaphore can't be used. Another idea was to do a void get_vc_lock(void) { while (test_and_set_bit(0, &vc_var)) ; } Any better ideas? |
From: Andrew M. <an...@uo...> - 2001-01-17 13:41:39
|
James Simmons wrote: > > Some time ago a intel i810 framebuffer driver was written. It only worked > for 2.2.X. With 2.4.X a spinlock is used in the upper layers of the > console system. Sooner or later we are going to run into the situtation > where we will have graphics hardware which has no vga core and wih be > purely DMA/irq based (i.e i810). In this case using the current > console_lock will block the driver itself. I have thought about a > possible solution. A semaphore can't be used since their is a spin_lock > in the console_softirq. Since this is in a interrupt context a > semaphore can't be used. Another idea was to do a > > void get_vc_lock(void) > { > while (test_and_set_bit(0, &vc_var)) > ; > } > > Any better ideas? > heh. I'm actually planning on grabbing console_lock and thoroughly strangling it next week. It can block interrupts for up to a second. That just isn't civil. - Use a semaphore for serialisation. - For printk in interrupt context, grab the semaphore (yes, you can do this). - If it couldn't be acquired from interrupt context, buffer the text in the log buffer and return. The text will be printed by whoever holds the semaphore before they drop it. - Special "system booting" mode which bypasses all this stuff. - Special "oops in progress" mode which just punches through everything. - Get rid of the special printk buffer - share the log buffer. (Implies writes to console devices will be broken into two writes when they wrap around). - Teach vsprintf to print into a circular buffer (snprintf thus comes for free). - Get rid of all the printk deadlock opportunities (fourth attempt). - Get rid of console_tasklet. Do it in process context callback or just do it synchronously. Assumption: - Once the system is up and running, it's always safe to call down() when in_interrupt() returns false - probably not the case in parts of the exit path - tough. Anyway, that's the thoughtware. Sound sane? - |
From: Roman Z. <zi...@fh...> - 2001-01-17 18:44:54
|
Hi, On Thu, 18 Jan 2001, Andrew Morton wrote: > - Get rid of the special printk buffer - share the > log buffer. (Implies writes to console > devices will be broken into two writes when they > wrap around). > - Teach vsprintf to print into a circular buffer > (snprintf thus comes for free). I have a different vsprintf variant - vpprintf(). It takes a function and a data pointer, this function is called with the print buffer and within that function you can take care of the locking. The only problem is that %n doesn't work anymore, but it's not used anyway in the kernel (as far as I can grep :) ). bye, Roman |
From: James S. <jsi...@su...> - 2001-01-17 23:40:17
|
> heh. > > I'm actually planning on grabbing console_lock and thoroughly strangling > it Ha Ha!! > - Use a semaphore for serialisation. I think this would be the best solution as well. > - For printk in interrupt context, grab the > semaphore (yes, you can do this). Don't forget about the idle task also. How is this done? By reintializing the semaphore. > - If it couldn't be acquired from interrupt context, > buffer the text in the log buffer and return. The text will be > printed by whoever holds the semaphore before they > drop it. By you saying couldn't be acquired from interrupt context do you mean from a process context or do you mean it failed to aquire it while in the interrupt context? > - Special "system booting" mode which bypasses all this > stuff. This wouldn't be to hard to do for VTs using the fact that keybaords are not initialized right away. As for serial consoles well that is another story. Of course we could have this flag set/cleared in start_kernel. > - Special "oops in progress" mode which just > punches through everything. You already developed the framework for this. > - Get rid of the special printk buffer - share the > log buffer. (Implies writes to console > devices will be broken into two writes when they > wrap around). > - Teach vsprintf to print into a circular buffer > (snprintf thus comes for free). > - Get rid of all the printk deadlock opportunities (fourth > attempt). Good luck. > - Get rid of console_tasklet. Do it in process context callback > or just do it synchronously. What about multidesktop systems? I have vgacon and mdacon working fine along each other. Each one has their own tasklet to allow them to work independent of each other. Meaning no race condition when both VC switch at the same time. > Assumption: > - Once the system is up and running, it's always safe to > call down() when in_interrupt() returns false - probably > not the case in parts of the exit path - tough. Don't forget the idle_task case as well. exit path? |
From: Andrew M. <an...@uo...> - 2001-01-18 12:34:16
|
James Simmons wrote: > ... > By you saying couldn't be acquired from interrupt context do you mean > from a process context or do you mean it failed to aquire it while in > the interrupt context? Actually, printk() must always use __down_trylock(). > > - Get rid of console_tasklet. Do it in process context callback > > or just do it synchronously. > > What about multidesktop systems? I have vgacon and mdacon working fine > along each other. Each one has their own tasklet to allow them to work > independent of each other. Meaning no race condition when both VC switch > at the same time. Ah. Thanks. That stuff was actually design-from-memory :) I'll take a closer look when I have something other than a clockwork computer. > > Assumption: > > - Once the system is up and running, it's always safe to > > call down() when in_interrupt() returns false - probably > > not the case in parts of the exit path - tough. > > Don't forget the idle_task case as well. exit path? This statement of mine was grade-A bollocks. printk cannot of course call down(). It needs to use __down_trylock and buffer it up if it fails. (faster, too!) The subtler problem will be interrupt-capable drivers which do a bare spin_lock() to serialise wrt their interrupt routines, relying upon interrupts being disabled. They'll be deadlocky and will need changing. That's trivial to find and fix though. Anyway, this was just a heads-up that I'll be looking at this stuff. Please allow me a week or so to provide some substance. I read that the fbdev developers have been seeking a fix for this for some time, so it seems worth some effort. |
From: Russell K. <rm...@ar...> - 2001-01-18 22:04:55
|
Andrew Morton writes: > The subtler problem will be interrupt-capable drivers which > do a bare spin_lock() to serialise wrt their interrupt routines, > relying upon interrupts being disabled. They'll be deadlocky > and will need changing. That's trivial to find and fix though. Uhh, what if you have this situation: interrupt (level triggered) enter interrupt handler printk (can re-enable interrupts?) enter interrupt handler printk (can re-enable interrupts?) enter interrupt handler printk (can re-enable interrupts?) .... So surely this isn't a new problem? _____ |_____| ------------------------------------------------- ---+---+- | | Russell King rm...@ar... --- --- | | | | http://www.arm.linux.org.uk/personal/aboutme.html / / | | +-+-+ --- -+- / | THE developer of ARM Linux |+| /|\ / | | | --- | +-+-+ ------------------------------------------------- /\\\ | |
From: James S. <jsi...@su...> - 2001-01-19 01:23:00
|
> This statement of mine was grade-A bollocks. printk cannot of > course call down(). It needs to use __down_trylock and buffer > it up if it fails. (faster, too!) Okay. I'm going to start working on this tomorrow. |