[Add jhb and move to -current]

On Fri, 15 Mar 2002 10:53:20 -0800,
  Alfred Perlstein <[EMAIL PROTECTED]> said:

Alfred> * Brian F. Feldman <[EMAIL PROTECTED]> [020315 03:22] wrote:
>> Alfred Perlstein <[EMAIL PROTECTED]> 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.

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

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

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

Alfred> This happens in vm_map_lookup() because of this:

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

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

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

Attached patch implements sx_upgrade() which should work as you said
above. This compiles fine, but is not tested yet.

sx_upgrader records the thread that wants to upgrade. If sx_upgrader
is non-NULL, sx_sunlock() wakes up the upgrader rather than other
exclusive lock waiters.

Attachment: sx_upgrade.diff
Description: Binary data


-- 
Seigo Tanimura <[EMAIL PROTECTED]> <[EMAIL PROTECTED]>

Reply via email to