Patch "Drivers: hv: vmbus: Fix rescind handling issues" has been added to the 4.13-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
Drivers: hv: vmbus: Fix rescind handling issues
to the 4.13-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drivers-hv-vmbus-fix-rescind-handling-issues.patch
and it can be found in the queue-4.13 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
6f3d791f300618caf82a2be0c27456edd76d5164Mon Sep 17 00:00:00 2001
From: "K. Y. Srinivasan" <[email protected]>
Date: Fri, 11 Aug 2017 10:03:59 -0700
Subject: Drivers: hv: vmbus: Fix rescind handling issues
From: K. Y. Srinivasan <[email protected]>
commit 6f3d791f300618caf82a2be0c27456edd76d5164 upstream.
This patch handles the following issues that were observed when we are handling racing channel offer message and rescind message for the same offer:
1. Since the host does not respond to messages on a rescinded channel, in the current code, we could be indefinitely blocked on the vmbus_open() call.
2. When a rescinded channel is being closed, if there is a pending interrupt on the channel, we could end up freeing the channel that the interrupt handler would run on.
--- drivers/hv/channel.c | 14 ++++++++++++++ drivers/hv/channel_mgmt.c | 29 ++++++++++++++++++++++++++--- drivers/hv/vmbus_drv.c | 3 +++ include/linux/hyperv.h | 2 ++ 4 files changed, 45 insertions(+), 3 deletions(-)
drivers/hv/channel.c +14 -0
@@ -177,6 +177,11 @@ int vmbus_open(struct vmbus_channel *new &vmbus_connection.chn_msg_list);spin_unlock_irqrestore (&vmbus_connection.channelmsg_lock, flags); +if (newchannel->rescind) { + err = -ENODEV ; + goto error_free_gpadl; + } + ret =vmbus_post_msg (open_msg,sizeof (struct vmbus_channel_open_channel ), true);
@@ -421,6 +426,11 @@ int vmbus_establish_gpadl(struct vmbus_cspin_unlock_irqrestore (&vmbus_connection.channelmsg_lock, flags); +if (channel->rescind) { + ret = -ENODEV ; + goto cleanup; + } + ret =vmbus_post_msg (gpadlmsg, msginfo->msgsize -sizeof (*msginfo), true);if (ret !=0 )
@@ -494,6 +504,10 @@ int vmbus_teardown_gpadl(struct vmbus_chlist_add_tail (&info->msglistentry, &vmbus_connection.chn_msg_list);spin_unlock_irqrestore (&vmbus_connection.channelmsg_lock, flags); + +if (channel->rescind) + goto post_msg_err; + ret =vmbus_post_msg (msg,sizeof (struct vmbus_channel_gpadl_teardown ), true);
drivers/hv/channel_mgmt.c +26 -3
@@ -451,6 +451,12 @@ static void vmbus_process_offer(struct v/* Make sure this is a new offer */ mutex_lock (&vmbus_connection.channel_mutex); +/* +* Now that we have acquired the channel_mutex, +* we can release the potentially racing rescind thread. +*/ +atomic_dec (&vmbus_connection.offer_in_progress); +list_for_each_entry (channel, &vmbus_connection.chn_list, listentry) { if (!uuid_le_cmp(channel->offermsg.offer.if_type, newchannel->offermsg.offer.if_type) &&
@@ -481,7 +487,6 @@ static void vmbus_process_offer(struct v channel->num_sc++;spin_unlock_irqrestore (&channel->lock, flags); }else { -atomic_dec (&vmbus_connection.offer_in_progress); goto err_free_chan; } }
@@ -510,7 +515,6 @@ static void vmbus_process_offer(struct vif (!fnew) {if (channel->sc_creation_callback !=NULL ) channel->sc_creation_callback (newchannel); -atomic_dec (&vmbus_connection.offer_in_progress);return ; }
@@ -541,7 +545,7 @@ static void vmbus_process_offer(struct v goto err_deq_chan; } -atomic_dec (&vmbus_connection.offer_in_progress); + newchannel->probe_done = true;return ; err_deq_chan:
@@ -882,8 +886,27 @@ static void vmbus_onoffer_rescind(struct channel->rescind = true;spin_unlock_irqrestore (&channel->lock, flags); +/* +* Now that we have posted the rescind state, perform +* rescind related cleanup. +*/ vmbus_rescind_cleanup (channel); +/* +* Now wait for offer handling to complete. +*/ +while (READ_ONCE (channel->probe_done) == false) { +/* +* We wait here until any channel offer is currently +* being processed. +*/ +msleep (1 ); + } + +/* +* At this point, the rescind handling can proceed safely. +*/ +if (channel->device_obj) {if (channel->chn_rescind_callback) { channel->chn_rescind_callback (channel);
drivers/hv/vmbus_drv.c +3 -0
@@ -940,6 +940,9 @@ static void vmbus_chan_sched(struct hv_pif (channel->offermsg.child_relid != relid)continue ; +if (channel->rescind) +continue ; +switch (channel->callback_mode) {case HV_CALL_ISR :vmbus_channel_isr (channel);
include/linux/hyperv.h +2 -0
@@ -895,6 +895,8 @@ struct vmbus_channel {*/ enum hv_numa_policy affinity_policy; +bool probe_done; + };static inline bool is_hvsock_channel (const struct vmbus_channel *c)
Patches currently in stable-queue which might be from [email protected] are
queue-4.13/drivers-hv-vmbus-fix-bugs-in-rescind-handling.patch queue-4.13/drivers-hv-vmbus-fix-rescind-handling-issues.patch