Subject: Re: allocmem in interrupt context
To: Bill Studenmund <wrstuden@netbsd.org>
From: Iain Hibbert <plunky@rya-online.net>
List: tech-kern
Date: 10/28/2005 21:36:15
On Fri, 28 Oct 2005, Bill Studenmund wrote:

> Yes, you're doing something wrong. I'm not 100% sure of the fix.
>
> The main issue is that we use interrupt masks to protect memory allocation
> lists. Some interrupt handlers can still run while these other interrupts
> are blocked. They must NOT allocate memory (which is why they get to run
> :-).

take note of splvm() in other words?

> So one of two things is happening. Either you are allocating memory at a
> time when you shouldn't and the message is correct, or you are ok and the
> message is not differentiating between interrupt context and interrupt
> context where we can't allocate memory.

I think maybe the latter, in this case - it is produced by

#ifdef DIAGNOSTIC
 	if (!curproc) {
 		printf("usb_block_allocmem: in interrupt context, size=%lu\n",
 		    (unsigned long) size);
 	}
#endif

and though the interrupt level is IPL_SOFTNET, there is a splusb() before 
it gets to usbd_transfer(). This is defined, variously in dev/usb/usbdi.h, 
as:

#ifdef USB_USE_SOFTINTR
#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
#define splusb splsoftnet
#else
#define	splusb splsoftclock
#endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
#else
#define splusb splbio
#endif /* USB_USE_SOFTINTR */
#define splhardusb splbio
#define IPL_USB IPL_BIO

and none of those approaches splvm() so memory allocations should be ok, hm?

confusingly, splusb() != splraise(IPL_USB)

It may be (certainly is, in fact) that I am unclear on the way the USB 
code works, documentation is minimal it seems..  not sure why the memory 
is being allocated in there in any case, as I am providing a buffer though 
it is not an usbd_alloc_buffer() buffer, was getting the transfer into an 
MBUF (cluster) data area so I can just pass it off directly.

I will ask for specific comments on this code later, when I have updated 
to -current, sigh.

iain