Skip to content
  • Alessandro Rubini's avatar
    zio_trigger_abort_disable() may sleep, waiting for CSET_HW_BUSY · bd476cb4
    Alessandro Rubini authored
    Previously, the enable/disable sysfs store had to complete atomically,
    as zio takes a spinlock to serialize the various concurrent enable and
    disable that may happen.
    
    Unfortunately, this is a problem when the hardware is keeping data
    structures busy, and commit b77ca7f0 is not enough to solve the
    problem: That commit uses udelay(10) in a loop, but in one
    installation of ours the hardware operation runs in a work queue,
    whereas the driving application has real-time priority.  So we really
    need to schedule (or change the priorities, which is denied to us).
    But we cannot schedule while holding a spinlock.
    
    This patch, thus, make the following changes:
    
    * zio_trigger_abort_disable() is renamed to __zio_trigger_abort_disable()
    and does not sleep, but it returns -EAGAIN if HW_BUSY.
    
    * a new zio_trigger_abort_disable() is offered, that retries while
    scheduling.  This covers all sysfs users, but one, so this keeps the
    patch smaller than I initially wrote it.
    
    * __zobj_enable() return int, not void: 0 or -EAGAIN (without
    sleeping, as it calls the new __zio_trigger_abort_disable()). It's an
    internal function in ./sysfs.c, so this is not a problem.
    
    * zobj_store_enable() accepts -AGAIN, and loops over if so.
    
    This is more difficult than expected (I loved b77ca7f0
    
    ), but I see no
    easier solution to the weird RT priorities our users deploy.
    
    Signed-off-by: default avatarAlessandro Rubini <rubini@gnudd.com>
    Acked-by: default avatarFederico Vaga <federico.vaga@gmail.com>
    bd476cb4