Messages in this thread Patch in this message | | | Date | Sat, 02 Aug 1997 14:09:42 -0400 | From | Bill Hawes <> | Subject | Re: Hanging problems in 2.0.30 -- discoveries |
| |
Philip Gladstone wrote:
> I guess that copy_mm should probably claim the semaphore > and then null out the copy of it.
After a little more study, it looks like there may be a couple of related problems here -- either the semaphore in use when copied, or the mmap changing while dum_mmap is trying to copy it.
I've attached a preliminary patch that may help -- it cleanly initializes the semaphore, and then acquires the current mmap_sem before calling dup_mmap(). This isn't the best way to do things, but if it help we're probably on the right track.
Another thing I noticed that looks possibly dangerous -- if the memory map includes a mmapped file, the new mm gets added to the inode's shared list. The mm is not yet fully constructed, but is it possible that the new task could be prematurely awakened via the inode shared list? Maybe somebody else here has looked into that ...
Regards, Bill--- kernel/fork.c.old Sun Apr 27 15:54:44 1997 +++ kernel/fork.c Sat Aug 2 13:38:20 1997 @@ -115,6 +115,8 @@ static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk) { + int retval; + if (!(clone_flags & CLONE_VM)) { struct mm_struct * mm = kmalloc(sizeof(*tsk->mm), GFP_KERNEL); if (!mm) @@ -122,13 +124,25 @@ *mm = *current->mm; mm->count = 1; mm->def_flags = 0; + /* + * If current is a cloned process, the semaphore may be + * in use, so we don't want a copy. + */ + mm->mmap_sem = MUTEX; tsk->mm = mm; tsk->min_flt = tsk->maj_flt = 0; tsk->cmin_flt = tsk->cmaj_flt = 0; tsk->nswap = tsk->cnswap = 0; if (new_page_tables(tsk)) return -1; - if (dup_mmap(mm)) { + /* + * If current is a cloned process, its shared mmap may change + * if we block in dup_mmap(). Get the semaphore for safety. + */ + down(¤t->mm->mmap_sem); + retval = dup_mmap(mm); + up(¤t->mm->mmap_sem); + if (retval) { free_page_tables(mm); return -1; } | |