diff options
author | Andrea Parri (Microsoft) <parri.andrea@gmail.com> | 2020-05-22 19:19:01 +0200 |
---|---|---|
committer | Wei Liu <wei.liu@kernel.org> | 2020-05-23 09:07:00 +0000 |
commit | afaa33da08abd10be8978781d7c99a9e67d2bbff (patch) | |
tree | 16d4437b59751684ee0a08b2a4d8283edb1a7e66 /include | |
parent | a949e86c0d7802c05b2ae726a84fae89ddb5be7d (diff) |
Drivers: hv: vmbus: Resolve more races involving init_vp_index()
init_vp_index() uses the (per-node) hv_numa_map[] masks to record the
CPUs allocated for channel interrupts at a given time, and distribute
the performance-critical channels across the available CPUs: in part.,
the mask of "candidate" target CPUs in a given NUMA node, for a newly
offered channel, is determined by XOR-ing the node's CPU mask and the
node's hv_numa_map. This operation/mechanism assumes that no offline
CPUs is set in the hv_numa_map mask, an assumption that does not hold
since such mask is currently not updated when a channel is removed or
assigned to a different CPU.
To address the issues described above, this adds hooks in the channel
removal path (hv_process_channel_removal()) and in target_cpu_store()
in order to clear, resp. to update, the hv_numa_map[] masks as needed.
This also adds a (missed) update of the masks in init_vp_index() (cf.,
e.g., the memory-allocation failure path in this function).
Like in the case of init_vp_index(), such hooks require to determine
if the given channel is performance critical. init_vp_index() does
this by parsing the channel's offer, it can not rely on the device
data structure (device_obj) to retrieve such information because the
device data structure has not been allocated/linked with the channel
by the time that init_vp_index() executes. A similar situation may
hold in hv_is_alloced_cpu() (defined below); the adopted approach is
to "cache" the device type of the channel, as computed by parsing the
channel's offer, in the channel structure itself.
Fixes: 7527810573436f ("Drivers: hv: vmbus: Introduce the CHANNELMSG_MODIFYCHANNEL message type")
Signed-off-by: Andrea Parri (Microsoft) <parri.andrea@gmail.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Link: https://lore.kernel.org/r/20200522171901.204127-3-parri.andrea@gmail.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/hyperv.h | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index d783847d8cb4..40df3103e890 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -902,6 +902,13 @@ struct vmbus_channel { bool probe_done; /* + * Cache the device ID here for easy access; this is useful, in + * particular, in situations where the channel's device_obj has + * not been allocated/initialized yet. + */ + u16 device_id; + + /* * We must offload the handling of the primary/sub channels * from the single-threaded vmbus_connection.work_queue to * two different workqueue, otherwise we can block |