• Stefan Richter's avatar
    [PATCH] sbp2: fix spinlock recursion · 24c7cd06
    Stefan Richter authored
    sbp2util_mark_command_completed takes a lock which was already taken by
    sbp2scsi_complete_all_commands.  This is a regression in Linux 2.6.15.
    
     Reported by Kristian Harms at
    	https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=187394
    
    [ More complete commentary, as response to questions by Andrew: ]
    
    > This changes the call environment for all implementations of
    > ->Current_done().  Are they all safe to call under this lock?
    
    Short answer: Yes, trust me.  ;-) Long answer:
    
    The done() callbacks are passed on to sbp2 from the SCSI stack along
    with each SCSI command via the queuecommand hook.  The done() callback
    is safe to call in atomic context.  So does
    Documentation/scsi/scsi_mid_low_api.txt say, and many if not all SCSI
    low-level handlers rely on this fact.  So whatever this callback does,
    it is "self-contained" and it won't conflict with sbp2's internal ORB
    list handling.  In particular, it won't race with the
    sbp2_command_orb_lock.
    
    Moreover, sbp2 already calls the done() handler with
    sbp2_command_orb_lock taken in sbp2scsi_complete_all_commands().  I
    admit this is ultimately no proof of correctness, especially since this
    portion of code introduced the spinlock recursion in the first place and
    we didn't realize it since this code's submission before 2.6.15 until
    now.  (I have learned a lesson from this.)
    
    I stress-tested my patch on x86 uniprocessor with a preemptible SMP
    kernel (alas I have no SMP machine yet) and made sure that all code
    paths which involve the sbp2_command_orb_lock were gone through multiple
    times.
    Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    24c7cd06
sbp2.c 75.7 KB