• Dan Williams's avatar
    md: raid5_run_ops - run stripe operations outside sh->lock · 91c00924
    Dan Williams authored
    When the raid acceleration work was proposed, Neil laid out the following
    attack plan:
    
    1/ move the xor and copy operations outside spin_lock(&sh->lock)
    2/ find/implement an asynchronous offload api
    
    The raid5_run_ops routine uses the asynchronous offload api (async_tx) and
    the stripe_operations member of a stripe_head to carry out xor+copy
    operations asynchronously, outside the lock.
    
    To perform operations outside the lock a new set of state flags is needed
    to track new requests, in-flight requests, and completed requests.  In this
    new model handle_stripe is tasked with scanning the stripe_head for work,
    updating the stripe_operations structure, and finally dropping the lock and
    calling raid5_run_ops for processing.  The following flags outline the
    requests that handle_stripe can make of raid5_run_ops:
    
    STRIPE_OP_BIOFILL
     - copy data into request buffers to satisfy a read request
    STRIPE_OP_COMPUTE_BLK
     - generate a missing block in the cache from the other blocks
    STRIPE_OP_PREXOR
     - subtract existing data as part of the read-modify-write process
    STRIPE_OP_BIODRAIN
     - copy data out of request buffers to satisfy a write request
    STRIPE_OP_POSTXOR
     - recalculate parity for new data that has entered the cache
    STRIPE_OP_CHECK
     - verify that the parity is correct
    STRIPE_OP_IO
     - submit i/o to the member disks (note this was already performed outside
       the stripe lock, but it made sense to add it as an operation type
    
    The flow is:
    1/ handle_stripe sets STRIPE_OP_* in sh->ops.pending
    2/ raid5_run_ops reads sh->ops.pending, sets sh->ops.ack, and submits the
       operation to the async_tx api
    3/ async_tx triggers the completion callback routine to set
       sh->ops.complete and release the stripe
    4/ handle_stripe runs again to finish the operation and optionally submit
       new operations that were previously blocked
    
    Note this patch just defines raid5_run_ops, subsequent commits (one per
    major operation type) modify handle_stripe to take advantage of this
    routine.
    
    Changelog:
    * removed ops_complete_biodrain in favor of ops_complete_postxor and
      ops_complete_write.
    * removed the raid5_run_ops workqueue
    * call bi_end_io for reads in ops_complete_biofill, saves a call to
      handle_stripe
    * explicitly handle the 2-disk raid5 case (xor becomes memcpy), Neil Brown
    * fix race between async engines and bi_end_io call for reads, Neil Brown
    * remove unnecessary spin_lock from ops_complete_biofill
    * remove test_and_set/test_and_clear BUG_ONs, Neil Brown
    * remove explicit interrupt handling for channel switching, this feature
      was absorbed (i.e. it is now implicit) by the async_tx api
    * use return_io in ops_complete_biofill
    Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
    Acked-By: default avatarNeilBrown <neilb@suse.de>
    91c00924
raid5.c 128 KB