diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index e99ff2ddad40..9a90b915b5be 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -112,7 +112,7 @@ static void kvp_poll_wrapper(void *channel) { /* Transaction is finished, reset the state here to avoid races. */ kvp_transaction.state = HVUTIL_READY; - hv_kvp_onchannelcallback(channel); + tasklet_schedule(&((struct vmbus_channel *)channel)->callback_event); } static void kvp_register_done(void) @@ -159,7 +159,7 @@ static void kvp_timeout_func(struct work_struct *dummy) static void kvp_host_handshake_func(struct work_struct *dummy) { - hv_poll_channel(kvp_transaction.recv_channel, hv_kvp_onchannelcallback); + tasklet_schedule(&kvp_transaction.recv_channel->callback_event); } static int kvp_handle_handshake(struct hv_kvp_msg *msg) @@ -625,16 +625,17 @@ void hv_kvp_onchannelcallback(void *context) NEGO_IN_PROGRESS, NEGO_FINISHED} host_negotiatied = NEGO_NOT_STARTED; - if (host_negotiatied == NEGO_NOT_STARTED && - kvp_transaction.state < HVUTIL_READY) { + if (kvp_transaction.state < HVUTIL_READY) { /* * If userspace daemon is not connected and host is asking * us to negotiate we need to delay to not lose messages. * This is important for Failover IP setting. */ - host_negotiatied = NEGO_IN_PROGRESS; - schedule_delayed_work(&kvp_host_handshake_work, + if (host_negotiatied == NEGO_NOT_STARTED) { + host_negotiatied = NEGO_IN_PROGRESS; + schedule_delayed_work(&kvp_host_handshake_work, HV_UTIL_NEGO_TIMEOUT * HZ); + } return; } if (kvp_transaction.state > HVUTIL_READY) @@ -702,6 +703,7 @@ void hv_kvp_onchannelcallback(void *context) VM_PKT_DATA_INBAND, 0); host_negotiatied = NEGO_FINISHED; + hv_poll_channel(kvp_transaction.recv_channel, kvp_poll_wrapper); } }