• Don Brace's avatar
    scsi: hpsa: correct race condition in offload enabled · 3e16e83a
    Don Brace authored
    Correct race condition where ioaccel is re-enabled before the raid_map is
    updated. For RAID_1, RAID_1ADM, and RAID 5/6 there is a BUG_ON called which
    is bad.
    
     - Change event thread to disable ioaccel only. Send all requests down the
       RAID path instead.
    
     - Have rescan thread handle offload_enable.
    
     - Since there is only one rescan allowed at a time, turning
       offload_enabled on/off should not be racy. Each handler queues up a
       rescan if one is already in progress.
    
      - For timing diagram, offload_enabled is initially off due to a change
        (transformation: splitmirror/remirror), ...
    
      otbe = offload_to_be_enabled
      oe   = offload_enabled
    
      Time Event         Rescan              Completion     Request
           Worker        Worker              Thread         Thread
      ---- ------        ------              ----------     -------
       T0   |             |                       + UA      |
       T1   |             + rescan started        | 0x3f    |
       T2   + Event       |                       | 0x0e    |
       T3   + Ack msg     |                       |         |
       T4   |             + if (!dev[i]->oe &&    |         |
       T5   |             |     dev[i]->otbe)     |         |
       T6   |             |      get_raid_map     |         |
       T7   + otbe = 1    |                       |         |
       T8   |             |                       |         |
       T9   |             + oe = otbe             |         |
       T10  |             |                       |         + ioaccel request
       T11                                                  * BUG_ON
    
      T0 - I/O completion with UA 0x3f 0x0e sets rescan flag.
      T1 - rescan worker thread starts a rescan.
      T2 - event comes in
      T3 - event thread starts and issues "Acknowledge" message
      ...
      T6 - rescan thread has bypassed code to reload new raid map.
      ...
      T7 - event thread runs and sets offload_to_be_enabled
      ...
      T9 - rescan thread turns on offload_enabled.
      T10- request comes in and goes down ioaccel path.
      T11- BUG_ON.
    
     - After the patch is applied, ioaccel_enabled can only be re-enabled in
       the re-scan thread.
    
    Link: https://lore.kernel.org/r/158472877894.14200.7077843399036368335.stgit@brunhildaReviewed-by: default avatarScott Teel <scott.teel@microsemi.com>
    Reviewed-by: default avatarMatt Perricone <matt.perricone@microsemi.com>
    Reviewed-by: default avatarScott Benesh <scott.benesh@microsemi.com>
    Signed-off-by: default avatarDon Brace <don.brace@microsemi.com>
    Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
    3e16e83a
hpsa.c 273 KB