On Tue, May 04, 2004 at 21:21:44 +0900, Tetsuo Handa wrote: > "Jan Hudec <bulb@ucw.cz>" wrote: > > GFP_NOFS in writeout path (->writepage and below) and GFP_KERNEL in all > > Oh, I didn't know GFP_NOFS flag. > I found the description at http://lwn.net/Articles/22909/ and > http://www.win.tue.nl/~aeb/linux/lk/lk-11.html . Yes. It does not seem to be too important for you, since you did not list any functions from the writeout path when saying what you modify. > > however). Of course, you must move your allocations out of the critical > > section, which you should do anyway. > > Does this mean I must not call kmalloc(GFP_KERNEL or GFP_NOFS) > inside critical section locked by a semaphore? Under a *semaphore* you may. Under a *spinlock* you must not. For a semaphore, it's still preferable to push the allocation before the semaphore is taken as you reduce the time spent in critical section and thus contention of that semaphore. > I introduced a new structure (arrays of 'const char *') in my functions. > The arrays are dynamically allocated and expanded as the system runs. > I need to use kmalloc() inside my critical section to append an element. 1) Use a linked list, from list.h. It will consume more memory, but avoid reallocations. You can use the "char foo[0]" GCC extension to have the head and string in one chunk of memory. 2) Be sure to remember how kmalloc works. It can only alocate power-of-2 sized buffers, 32 bytes minimum, PAGE_SIZE << 5 (or something like that) maximum. When you allocate same-sized chunks, use the kmem_cache. 3) You should preallocate the memory before you enter the critical section. > So I need to use spinlocks or semaphores. I would prefer to use spinlocks to lock a linked list. Allocate the element before and than just spin_lock around the list_add. And since you say they are const chars, I assume they don't change once added. You can combine linked list and arrays like this: struct chunk { list_head list; const char * array[CHUNK_SIZE]; } Allocate these from a kmem_cache and use the ctor for construction. When you are about to enter the critical section and there are no free slots (keep an atomic_t coutner), you can preallocate, keep the chunk private and add it to the list once the spinlock is down. Worst thing, that can happen is that you allocate more than necessary. You can also add some auxiliary data to simplify looking for free slots. Perhaps you can have them in a linked list (just the way slabs in a kmem_cache work). > > You should really study the existing locking scheme a bit. You should > > know, what can happen when and what states are considered consistent. > I've read "Unreliable Guide To Locking" for several times, > but I haven't fully understood yet. > I'm sorry I'm really a newbie to kernel programming. The locking is not really thoroughly explained anywhere :-(. There is the Documentation/filesystems/Locking file, that specifies locking for the filesystem driver methods. And the rest you must deduce from looking at the code. When you need to manipulate something, think of operations that might cross your path and look at what they lock. ------------------------------------------------------------------------------- Jan 'Bulb' Hudec <bulb@ucw.cz>
Attachment:
signature.asc
Description: Digital signature