[RFC PATCH v3 2/3] vfio-ccw: Remove the CP_PENDING FSM state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The FSM state is set to CP_PROCESSING when a START operation begins,
is set to CP_PENDING when a START operation is done (the SSCH
instruction gets a cc0), and is set back to IDLE when the final
interrupt is received (or if the START fails somehow). However, it is
categorically impossible to distinguish between interrupts when
other instructions can generate "final" interrupts via the async
region, so using this information for any decision-making at the
completion of an I/O is fraught with peril.

We could replace "CP_PENDING" with a generic "OPERATION_PENDING" state,
but it doesn't appear to buy us anything as far as knowing if we get
one interrupt for a START and another for a CLEAR, or if we just get
one interrupt for the CLEAR and the START never got off the ground.

So let's remove that entirely, and just move the FSM back to IDLE
once the START process completes.

Signed-off-by: Eric Farman <farman@xxxxxxxxxxxxx>
---
 drivers/s390/cio/vfio_ccw_drv.c     |  3 ---
 drivers/s390/cio/vfio_ccw_fsm.c     | 16 +++-------------
 drivers/s390/cio/vfio_ccw_ops.c     |  3 +--
 drivers/s390/cio/vfio_ccw_private.h |  1 -
 4 files changed, 4 insertions(+), 19 deletions(-)

diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c
index 7e2a790dc9a1..b76c9008871b 100644
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -101,9 +101,6 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work)
 	memcpy(private->io_region->irb_area, irb, sizeof(*irb));
 	mutex_unlock(&private->io_mutex);
 
-	if (private->mdev && is_final)
-		private->state = VFIO_CCW_STATE_IDLE;
-
 	if (private->io_trigger)
 		eventfd_signal(private->io_trigger, 1);
 }
diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c
index d806f88eba72..f0952192480e 100644
--- a/drivers/s390/cio/vfio_ccw_fsm.c
+++ b/drivers/s390/cio/vfio_ccw_fsm.c
@@ -49,7 +49,6 @@ static int fsm_io_helper(struct vfio_ccw_private *private)
 		 */
 		sch->schib.scsw.cmd.actl |= SCSW_ACTL_START_PEND;
 		ret = 0;
-		private->state = VFIO_CCW_STATE_CP_PENDING;
 		private->cp.started = true;
 		break;
 	case 1:		/* Status pending */
@@ -188,12 +187,6 @@ static void fsm_io_error(struct vfio_ccw_private *private,
 	private->io_region->ret_code = -EIO;
 }
 
-static void fsm_io_busy(struct vfio_ccw_private *private,
-			enum vfio_ccw_event event)
-{
-	private->io_region->ret_code = -EBUSY;
-}
-
 static void fsm_io_retry(struct vfio_ccw_private *private,
 			 enum vfio_ccw_event event)
 {
@@ -309,6 +302,7 @@ static void fsm_io_request(struct vfio_ccw_private *private,
 			cp_free(&private->cp);
 			goto err_out;
 		}
+		private->state = VFIO_CCW_STATE_IDLE;
 		return;
 	} else if (scsw->cmd.fctl & SCSW_FCTL_HALT_FUNC) {
 		VFIO_CCW_MSG_EVENT(2,
@@ -331,6 +325,8 @@ static void fsm_io_request(struct vfio_ccw_private *private,
 err_out:
 	trace_vfio_ccw_fsm_io_request(scsw->cmd.fctl, schid,
 				      io_region->ret_code, errstr);
+
+	private->state = VFIO_CCW_STATE_IDLE;
 }
 
 /*
@@ -405,10 +401,4 @@ fsm_func_t *vfio_ccw_jumptable[NR_VFIO_CCW_STATES][NR_VFIO_CCW_EVENTS] = {
 		[VFIO_CCW_EVENT_ASYNC_REQ]	= fsm_async_retry,
 		[VFIO_CCW_EVENT_INTERRUPT]	= fsm_irq,
 	},
-	[VFIO_CCW_STATE_CP_PENDING] = {
-		[VFIO_CCW_EVENT_NOT_OPER]	= fsm_notoper,
-		[VFIO_CCW_EVENT_IO_REQ]		= fsm_io_busy,
-		[VFIO_CCW_EVENT_ASYNC_REQ]	= fsm_async_request,
-		[VFIO_CCW_EVENT_INTERRUPT]	= fsm_irq,
-	},
 };
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index 8b3ed5b45277..0b67c04decee 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -276,8 +276,7 @@ static ssize_t vfio_ccw_mdev_write_io_region(struct vfio_ccw_private *private,
 	}
 
 	vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_IO_REQ);
-	if (region->ret_code != 0)
-		private->state = VFIO_CCW_STATE_IDLE;
+
 	ret = (region->ret_code != 0) ? region->ret_code : count;
 
 out_unlock:
diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h
index 8723156b29ea..f592897f1930 100644
--- a/drivers/s390/cio/vfio_ccw_private.h
+++ b/drivers/s390/cio/vfio_ccw_private.h
@@ -125,7 +125,6 @@ enum vfio_ccw_state {
 	VFIO_CCW_STATE_STANDBY,
 	VFIO_CCW_STATE_IDLE,
 	VFIO_CCW_STATE_CP_PROCESSING,
-	VFIO_CCW_STATE_CP_PENDING,
 	/* last element! */
 	NR_VFIO_CCW_STATES
 };
-- 
2.17.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux