Let's move the state change from the IRQ routine to the
workqueue callback.

Signed-off-by: Pierre Morel <pmo...@linux.vnet.ibm.com>
---
 drivers/s390/cio/vfio_ccw_drv.c | 20 +++++++-------------
 drivers/s390/cio/vfio_ccw_fsm.c | 14 ++++++++------
 2 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index ea6a2d0..57ae1ab 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -70,20 +70,9 @@ int vfio_ccw_sch_quiesce(struct subchannel *sch)
 static void vfio_ccw_sch_io_todo(struct work_struct *work)
 {
        struct vfio_ccw_private *private;
-       struct irb *irb;
 
        private = container_of(work, struct vfio_ccw_private, io_work);
-       irb = &private->irb;
-
-       if (scsw_is_solicited(&irb->scsw)) {
-               cp_update_scsw(&private->cp, &irb->scsw);
-               cp_free(&private->cp);
-       }
-       memcpy(private->io_region.irb_area, irb, sizeof(*irb));
-
-       if (private->io_trigger)
-               eventfd_signal(private->io_trigger, 1);
-
+       vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
        if (private->mdev)
                private->state = VFIO_CCW_STATE_IDLE;
 }
@@ -94,9 +83,14 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work)
 static void vfio_ccw_sch_irq(struct subchannel *sch)
 {
        struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
+       struct irb *irb = this_cpu_ptr(&cio_irb);
 
        inc_irq_stat(IRQIO_CIO);
-       vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
+       memcpy(&private->irb, irb, sizeof(*irb));
+
+       queue_work(vfio_ccw_work_q, &private->io_work);
+       if (private->completion)
+               complete(private->completion);
 }
 
 static int vfio_ccw_sch_probe(struct subchannel *sch)
diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c
index 3c80064..24e1e04 100644
--- a/drivers/s390/cio/vfio_ccw_fsm.c
+++ b/drivers/s390/cio/vfio_ccw_fsm.c
@@ -172,14 +172,16 @@ static void fsm_io_request(struct vfio_ccw_private 
*private,
 static void fsm_irq(struct vfio_ccw_private *private,
                    enum vfio_ccw_event event)
 {
-       struct irb *irb = this_cpu_ptr(&cio_irb);
+       struct irb *irb = &private->irb;
 
-       memcpy(&private->irb, irb, sizeof(*irb));
-
-       queue_work(vfio_ccw_work_q, &private->io_work);
+       if (scsw_is_solicited(&irb->scsw)) {
+               cp_update_scsw(&private->cp, &irb->scsw);
+               cp_free(&private->cp);
+       }
+       memcpy(private->io_region.irb_area, irb, sizeof(*irb));
 
-       if (private->completion)
-               complete(private->completion);
+       if (private->io_trigger)
+               eventfd_signal(private->io_trigger, 1);
 }
 
 /*
-- 
2.7.4

Reply via email to