Re: Which types of locking should I use?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux