The .state is used by several threads of execution. Propagate the state to make changes visible. Also propagate context change in vss_on_msg. Signed-off-by: Olaf Hering <olaf@xxxxxxxxx> --- drivers/hv/hv_snapshot.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c index 815405f..f3cb822 100644 --- a/drivers/hv/hv_snapshot.c +++ b/drivers/hv/hv_snapshot.c @@ -48,7 +48,7 @@ */ static struct { - int state; /* hvutil_device_state */ + enum hvutil_device_state state; int recv_len; /* number of bytes received. */ struct vmbus_channel *recv_channel; /* chn we got the request */ u64 recv_req_id; /* request ID. */ @@ -64,6 +64,9 @@ static void vss_respond_to_host(int error); */ static int dm_reg_value; +#define vss_get_state() hvutil_device_get_state(&vss_transaction.state) +#define vss_set_state(s) hvutil_device_set_state(&vss_transaction.state, s) + static const char vss_devname[] = "vmbus/hv_vss"; static __u8 *recv_buffer; static struct hvutil_transport *hvt; @@ -87,8 +90,8 @@ static void vss_timeout_func(struct work_struct *dummy) vss_respond_to_host(HV_E_FAIL); /* Transaction is finished, reset the state. */ - if (vss_transaction.state > HVUTIL_READY) - vss_transaction.state = HVUTIL_READY; + if (vss_get_state() > HVUTIL_READY) + vss_set_state(HVUTIL_READY); hv_poll_channel(vss_transaction.vss_context, hv_vss_onchannelcallback); @@ -112,7 +115,7 @@ static int vss_handle_handshake(struct hv_vss_msg *vss_msg) default: return -EINVAL; } - vss_transaction.state = HVUTIL_READY; + vss_set_state(HVUTIL_READY); pr_debug("VSS: userspace daemon ver. %d registered\n", dm_reg_value); return 0; } @@ -130,15 +133,15 @@ static int vss_on_msg(void *msg, int len) * Don't process registration messages if we're in the middle * of a transaction processing. */ - if (vss_transaction.state > HVUTIL_READY) + if (vss_get_state() > HVUTIL_READY) return -EINVAL; return vss_handle_handshake(vss_msg); - } else if (vss_transaction.state == HVUTIL_USERSPACE_REQ) { - vss_transaction.state = HVUTIL_USERSPACE_RECV; + } else if (vss_get_state() == HVUTIL_USERSPACE_REQ) { + vss_set_state(HVUTIL_USERSPACE_RECV); if (cancel_delayed_work_sync(&vss_timeout_work)) { vss_respond_to_host(vss_msg->error); /* Transaction is finished, reset the state. */ - vss_transaction.state = HVUTIL_READY; + vss_set_state(HVUTIL_READY); hv_poll_channel(vss_transaction.vss_context, hv_vss_onchannelcallback); } @@ -158,7 +161,7 @@ static void vss_send_op(struct work_struct *dummy) struct hv_vss_msg *vss_msg; /* The transaction state is wrong. */ - if (vss_transaction.state != HVUTIL_HOSTMSG_RECEIVED) + if (vss_get_state() != HVUTIL_HOSTMSG_RECEIVED) return; vss_msg = kzalloc(sizeof(*vss_msg), GFP_KERNEL); @@ -167,13 +170,13 @@ static void vss_send_op(struct work_struct *dummy) vss_msg->vss_hdr.operation = op; - vss_transaction.state = HVUTIL_USERSPACE_REQ; + vss_set_state(HVUTIL_USERSPACE_REQ); rc = hvutil_transport_send(hvt, vss_msg, sizeof(*vss_msg)); if (rc) { pr_warn("VSS: failed to communicate to the daemon: %d\n", rc); if (cancel_delayed_work_sync(&vss_timeout_work)) { vss_respond_to_host(HV_E_FAIL); - vss_transaction.state = HVUTIL_READY; + vss_set_state(HVUTIL_READY); } } @@ -238,7 +241,7 @@ void hv_vss_onchannelcallback(void *context) struct icmsg_hdr *icmsghdrp; struct icmsg_negotiate *negop = NULL; - if (vss_transaction.state > HVUTIL_READY) { + if (vss_get_state() > HVUTIL_READY) { /* * We will defer processing this callback once * the current transaction is complete. @@ -288,12 +291,12 @@ void hv_vss_onchannelcallback(void *context) */ case VSS_OP_FREEZE: case VSS_OP_THAW: - if (vss_transaction.state < HVUTIL_READY) { + if (vss_get_state() < HVUTIL_READY) { /* Userspace is not registered yet */ vss_respond_to_host(HV_E_FAIL); return; } - vss_transaction.state = HVUTIL_HOSTMSG_RECEIVED; + vss_set_state(HVUTIL_HOSTMSG_RECEIVED); schedule_work(&vss_send_op_work); schedule_delayed_work(&vss_timeout_work, VSS_USERSPACE_TIMEOUT); @@ -332,7 +335,7 @@ static void vss_on_reset(void) { if (cancel_delayed_work_sync(&vss_timeout_work)) vss_respond_to_host(HV_E_FAIL); - vss_transaction.state = HVUTIL_DEVICE_INIT; + vss_set_state(HVUTIL_DEVICE_INIT); } int @@ -346,7 +349,7 @@ hv_vss_init(struct hv_util_service *srv) * Defer processing channel callbacks until the daemon * has registered. */ - vss_transaction.state = HVUTIL_DEVICE_INIT; + vss_set_state(HVUTIL_DEVICE_INIT); hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL, vss_on_msg, vss_on_reset); @@ -358,7 +361,7 @@ hv_vss_init(struct hv_util_service *srv) void hv_vss_deinit(void) { - vss_transaction.state = HVUTIL_DEVICE_DYING; + vss_set_state(HVUTIL_DEVICE_DYING); cancel_delayed_work_sync(&vss_timeout_work); cancel_work_sync(&vss_send_op_work); hvutil_transport_destroy(hvt); _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel