problems with new the "contigmalloc" routine
Hans Petter Selasky
hselasky at c2i.net
Sun May 22 18:10:09 GMT 2005
On Sunday 22 May 2005 18:06, Scott Long wrote:
> > When I worked with USB I ran into some synchronization problems with
> > callbacks that leaded me to writing to the stack of another thread, which
> > I hope is OK.
> No, it's not ok. Kernel stacks can be swapped out while sleeping.
> Writing to a swapped out stack will cause a VM panic.
OK, maybe I have to create a bitmap in "struct thread" where I can store that
information, though that will limit the maximum number of context exits to a
And then change things a little bit. I assume that "curthread" points to the
currently active thread and is always set? But the principle will be exactly
the same. Please read through my previous e-mail and the function below
#define CONTEXT_MAX (8*8)
struct mtx *mtx;
#define max_callback 16
#if (max_callback >= CONTEXT_MAX)
#error "out of contexts"
struct callback * callbacks[max_callback];
struct mtx * mtxs[max_callback];
int x = 0;
int repeat = 0;
int retry = 0;
u_int8_t index = curthread->context_index;
if(index >= (CONTEXT_MAX - max_callback))
panic("out of contexts\n");
callbacks[x] = GET_NEXT_CALLBACK();
if(callbacks[x] == NULL)
/* another thread is calling callback
/* clear bit */
curthread->context_bitmap[index / 8] &= ~(1 << (index % 8));
callbacks[x]->ctx.done_p = &curthread->context_bitmap;
callbacks[x]->ctx.done_index = index;
mtxs[x] = callbacks[x]->ctx.mtx;
if(x == max_callback)
retry = 1;
curthread->context_index = index;
/* here one needs to switch lock to avoid
* locking order reversal
/* do you see the point in storing a pointer to the
* mutex on the stack ?
* The callback structure might have been freed when one
* gets here and needs a copy !
/* do you see the point in checking the bit below?
* It is supposed to get set if this callback has been
* stopped during the lock switch!
if(!(curthread->context_bitmap[index / 8] & (1<<(index % 8))))
callbacks[x]->ctx.done_p = NULL;
/* else callback stopped */
/* free up bits used */
retry = 0;
> > What do you think about the following:
> > I hope this wasn't too much for you to read :-)
> > Any comments ?
> I'm not too familiar with the exact problem you're trying to solve in
> USB. I guess you need to be able to allocate a contiguous chunk of
> memory in order to do a transaction, but are afraid that state will
> change while the allocation is in progress?
That's one problem.
> What is the maximum size
> of memory that the hardware can handle for this transaction?
It is limited to the amount of available memory.
> How many transactions can be handled concurrently by the hardware?
Typically there is more than one transaction i parallell, and there is
synchronous transfers waiting for completion and non-synchronous transfers
not waiting for completion, that call callbacks.
> What state are you trying to protect?
For example that the callback is not called after that I have stopped a
> Is it possible to do the allocation before
> the state needs to be protected?
Mostly, but not always, though that only solves one part of the problem.
More information about the freebsd-hackers