Skip to contentSkip to conversation

Deadlock on the mm->mmap_sem

PATCH New David Howells 1 participant 2 messages Sep 20, 2001 1 message not in the archive

lore
Share & tools
lore
#1 lore raw
In reply to a message not in the archive
Quoted 5 lines

David, coredump is the only difficult recursive user of mmap_sem. ptrace & /proc/pid/mem double buffer into kernel buffers, fork just doesn't lock the new mm_struct - it's new, noone can get a pointer to it before it's linked into the various lists.

Yes, you're right. So what you and Andrea are proposing is to have a field in the task struct that counts the number of active readlocks you hold on your own mm_struct. If this is >0, then you can add another readlock to it. If this is the case, then you can add an extra asm-rwsem operation that simply increments the semaphore counter. BUT you can only use this operation if you _know_ you already have a readlock. And as you know that some function higher up the stack holds the lock, you can guarantee that the lock isn't going to go away.

Give me a few minutes, and I can handle this:-)

David

#2 lore raw

PATCH 1/1 Make same-process recursive mm_struct access possible

Based on an idea by Andrea Arcangeli, this patch wraps the rw_semaphore on the mm_struct (to force you to use special locking operations to access it) and adds a counter to the task_struct (which counts the number of active read locks you hold on _your_ mm_struct). The four new ops are:

	mm_lock_shared(struct mm_struct *);
	mm_unlock_shared(struct mm_struct *);
	mm_lock_exclusive(struct mm_struct *);
	mm_unlock_exclusive(struct mm_struct *);

* The exclusive ops map directly to down_write() and up_write().

* The unlock-shared op decrements the current mm readlock counter if the mm unlocked is the current mm; finally it calls up_read().

* The lock-shared op does one of the following two things:

* If the mm being locked is the current mm, and if the current readlock counter is greater than zero, then it calls down_read_recursive() and then increments the current readlock counter.

* Otherwise, it just calls down_read() and then increments the current readlock counter.

down_read_recursive() is a new rw-semaphore operation. It simply adjusts the semaphore to record an extra active readlock. As specified in the comments associated with it, it MUST ONLY be called if you know that there is already an active read lock on the semaphore. Note that it never needs to wait; given the preconditions for calling it, it knows it can always succeed immediately.

This patch makes no changes to existing rw-semaphore operations. They are still fair. It simply makes mm_struct locks fair and capable of recursion.

David