Re: Hanging problems in 2.0.30 -- discoveries

Bill Hawes (whawes@star.net)
Sat, 02 Aug 1997 14:09:42 -0400


This is a multi-part message in MIME format.
--------------3B3E3603C95CA88FF4A299BD
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

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
--------------3B3E3603C95CA88FF4A299BD
Content-Type: text/plain; charset=us-ascii; name="fork_30-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="fork_30-patch"

--- 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(&current->mm->mmap_sem);
+ retval = dup_mmap(mm);
+ up(&current->mm->mmap_sem);
+ if (retval) {
free_page_tables(mm);
return -1;
}

--------------3B3E3603C95CA88FF4A299BD--