Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Mar 2002 10:53:20 -0800
From:      Alfred Perlstein <bright@mu.org>
To:        "Brian F. Feldman" <green@FreeBSD.org>
Cc:        cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org
Subject:   Re: cvs commit: src/sys/kern kern_mtxpool.c src/sys/sys kernel.h src/sys/vm vm_fault.c vm_glue.c vm_map.c vm_map.h vm_pageout.c vm_zone.c
Message-ID:  <20020315185320.GJ4857@elvis.mu.org>
In-Reply-To: <200203151121.g2FBLnj36094@green.bikeshed.org>
References:  <20020315054113.GC4857@elvis.mu.org> <200203151121.g2FBLnj36094@green.bikeshed.org>

next in thread | previous in thread | raw e-mail | index | archive | help
* Brian F. Feldman <green@FreeBSD.org> [020315 03:22] wrote:
> Alfred Perlstein <bright@mu.org> wrote:
> > 
> > What is the problem?
> 
> Damn good question.  Are the tracebacks related?  If not, what are you 
> supposed to be telling me it's deadlocking on?  I don't see the system being 
> deadlocked.  What is it actually supposed to be blocked on?
> 
> > Well basically you changed:
> > 
> > ! static __inline__ int
> > ! _vm_map_lock_upgrade(vm_map_t map, struct thread *td) {
> > !       int error;
> > ! 
> > !       vm_map_printf("locking map LK_EXCLUPGRADE: %p\n", map); 
> > !       error = lockmgr(&map->lock, LK_EXCLUPGRADE, NULL, td);
> > !       if (error == 0)
> > !               map->timestamp++;
> > !       return error;
> >   }
> > 
> > into:
> > 
> > ! _vm_map_lock_upgrade(vm_map_t map, const char *file, int line)
> >   {
> > !       vm_map_printf("locking map LK_EXCLUPGRADE: %p\n", map); 
> > !       if (_sx_try_upgrade(&map->lock, file, line)) {
> > !               map->timestamp++;
> > !               return (0);
> > !       }
> > !       return (EWOULDBLOCK);
> >   }
> 
> It doesn't need LK_EXCLUPGRADE semantics, only LK_UPGRADE, if it's not 
> blocking.  It backs out completely and unlocks the shared reference and 
> tries for an exclusive lock.

Sigh, you're making me do all the work here... :(

lockmgr(&map->lock, LK_EXCLUPGRADE, NULL, td);
means:
  Turn my shared lock into an exclusive lock,
  if it's shared then wait for all shared locks to drain,
  however if someone else is requesting an exclusive lock, then fail.
  
_sx_try_upgrade(&map->lock, file, line)
means:
  Give me an exclusive lock
  if anyone else has a shared lock then fail immediately.

What happens in your case is that you get into a busy loop
because you never yeild the processor.

This happens in vm_map_lookup() because of this:

                if (fault_type & VM_PROT_WRITE) {
                        /*
                         * Make a new object, and place it in the object
                         * chain.  Note that no new references have appeared
                         * -- one just moved from the map to the new
                         * object.
                         */
                        if (vm_map_lock_upgrade(map))
                                goto RetryLookup;

So, you fail your sx_lock upgrade and cause the cpu to spin.

You basically need to add logic to the sxlock subsystem to do what
lockmgr does, actually wait for the others to go away or fail if
someone else wants an upgrade.

-Alfred

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020315185320.GJ4857>