Well, I changed my code to use a mutex instead of a spinlock, and now I get: BUG: scheduling while atomic: swapper/0/0x10010000 All I changed was the spinlock_t to a struct mutex, and call mutex_init, mutex_lock, and mutex_unlock where I was previously calling the spin_lock variations. I'm confused. What does mutex_lock do besides set values in an atomic_t? -Kai Meyer On 11/10/2011 10:02 AM, Kai Meyer wrote: > > On 11/09/2011 08:38 PM, Dave Hylands wrote: >> Hi Kai, >> >> On Wed, Nov 9, 2011 at 3:12 PM, Kai Meyer<kai@xxxxxxxxxx> wrote: >>> Ok, I need mutual exclusion on a data structure regardless of interrupts >>> and core. It sounds like it can be done by using a spinlock and >>> disabling interrupts, but you mention that "spinlocks are intended to >>> provide mutual exclsion between interrupt context and non-interrupt >>> context." Should I be using a semaphore (mutex) instead? >> It depends. If the function is only called from thread context, then >> you probably want to use a mutex. If there is a possibility that it >> might be called from interrupt context, then you can't use a mutex. >> >> Also, remember that spin-locks are no-ops on a single processor >> machine, so as coded, you have no protection on a single-processor >> machine if you're calling from thread context. >> > To make sure I understand you, it sounds like there's two contexts I > need to be concerned about, thread context and interrupt context. As far > as I can be sure, this code will only run in thread context. If you > could verify for me that a block device's make request function is only > reached in thread context, then that would make me doubly sure. >>> Perhaps I could explain my problem with some code: >>> struct my_struct *get_data(spinlock_t *mylock, int ALLOC_DATA) >>> { >>> struct my_struct *mydata = NULL; >>> spin_lock(mylock); >>> if (test_bit(index, mybitmap)) >>> mydata = retrieve_data(); >>> if (!mydata&& ALLOC_DATA) { >>> mydata = alloc_data(); >>> set_bit(index, mybitmap); >>> } >>> spin_unlock(mylock); >>> return mydata; >>> } >>> >>> I need to prevent retrieve_data from being called if the index bit is >>> set in mybitmap and alloc_data has not completed, so I use a bitmap to >>> indicate that alloc_data has completed. I also need to protect >>> alloc_data from being run multiple times, so I use the spin_lock to >>> ensure that test_bit (and possibly retrieve_data) is not run while >>> alloc_data is being run (because it runs while the bit is cleared). >> If alloc_data might block, then you can't disable interrupts and you >> definitely shouldn't be using spinlocks. >> > alloc_data will call kmalloc(size, GFP_KERNEL), which I think may block, > so disabling irqs is out. > > Between thread context and kmalloc with GFP_KERNEL, it sounds like your > suggestion would be to use a mutex. Is that correct? > > -Kai Meyer > > _______________________________________________ > Kernelnewbies mailing list > Kernelnewbies@xxxxxxxxxxxxxxxxx > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies