Drivers: hv: Miscellaneous fixes/improvements
Subsystems (8)
cover Drivers: hv: Miscellaneous fixes/improvements
From: "K. Y. Srinivasan" <[email protected]>
Some miscellaneous fixes/improvements.
Arjan van de Ven (1):
use the new async probing feature for the hyperv drivers
Dexuan Cui (1):
Drivers: hv: vmbus: Fix the offer_in_progress in vmbus_process_offer()
Michael Kelley (4):
x86/hyperv: Add interrupt handler annotations
Drivers: hv: vmbus: Add comments on ring buffer signaling
Drivers: hv: vmbus: Remove x86 MSR refs in arch independent code
Drivers: hv: vmbus: Make TLFS #define names architecture neutral
Olaf Hering (1):
tools: hv: update lsvmbus to be compatible with python3
Vitaly Kuznetsov (1):
Tools: hv: vss: fix loop device detection
arch/x86/hyperv/hv_init.c | 4 +- arch/x86/include/asm/hyperv-tlfs.h | 12 ++--- arch/x86/include/asm/mshyperv.h | 12 +++-- arch/x86/kernel/cpu/mshyperv.c | 6 +-- drivers/hid/hid-hyperv.c | 3 ++ drivers/hv/channel_mgmt.c | 4 +- drivers/hv/hv.c | 30 ++++++------- drivers/hv/hv_balloon.c | 3 ++ drivers/hv/hv_util.c | 3 ++ drivers/hv/ring_buffer.c | 65 ++++++++++++++++++++++----- drivers/input/serio/hyperv-keyboard.c | 3 ++ drivers/net/hyperv/netvsc_drv.c | 3 ++ drivers/scsi/storvsc_drv.c | 3 ++ drivers/video/fbdev/hyperv_fb.c | 6 +++ include/linux/hyperv.h | 31 +++++++++---- tools/hv/hv_vss_daemon.c | 65 +++++++++++++++++++++++++-- tools/hv/lsvmbus | 12 ++--- 17 files changed, 201 insertions(+), 64 deletions(-)
Signature · 1 line
2.17.1
PATCH 1/8 use the new async probing feature for the hyperv drivers
From: Arjan van de Ven <[email protected]>
Recent kernels support asynchronous probing; most hyperv drivers can be probed async easily so set the required flag for this.
--- drivers/hid/hid-hyperv.c | 3 +++ drivers/hv/hv_balloon.c | 3 +++ drivers/hv/hv_util.c | 3 +++ drivers/input/serio/hyperv-keyboard.c | 3 +++ drivers/net/hyperv/netvsc_drv.c | 3 +++ drivers/scsi/storvsc_drv.c | 3 +++ drivers/video/fbdev/hyperv_fb.c | 6 ++++++ 7 files changed, 24 insertions(+)
drivers/hid/hid-hyperv.c +3 -0
@@ -598,6 +598,9 @@ static struct hv_driver mousevsc_drv = { .id_table = id_table, .probe = mousevsc_probe, .remove = mousevsc_remove, + .driver = { + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, };static int __init mousevsc_init (void )
drivers/hv/hv_balloon.c +3 -0
@@ -1765,6 +1765,9 @@ static struct hv_driver balloon_drv = { .id_table = id_table, .probe = balloon_probe, .remove = balloon_remove, + .driver = { + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, };static int __init init_balloon_drv (void )
drivers/hv/hv_util.c +3 -0
@@ -487,6 +487,9 @@ static struct hv_driver util_drv = { .id_table = id_table, .probe = util_probe, .remove = util_remove, + .driver = { + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, }; static int hv_ptp_enable(struct ptp_clock_info *info,
drivers/input/serio/hyperv-keyboard.c +3 -0
@@ -424,6 +424,9 @@ static struct hv_driver hv_kbd_drv = { .id_table = id_table, .probe = hv_kbd_probe, .remove = hv_kbd_remove, + .driver = { + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, };static int __init hv_kbd_init (void )
drivers/net/hyperv/netvsc_drv.c +3 -0
@@ -2155,6 +2155,9 @@ static struct hv_driver netvsc_drv = { .id_table = id_table, .probe = netvsc_probe, .remove = netvsc_remove, + .driver = { + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, };/*
drivers/scsi/storvsc_drv.c +3 -0
@@ -1893,6 +1893,9 @@ static struct hv_driver storvsc_drv = { .id_table = id_table, .probe = storvsc_probe, .remove = storvsc_remove, + .driver = { + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, };#if IS_ENABLED (CONFIG_SCSI_FC_ATTRS )
drivers/video/fbdev/hyperv_fb.c +6 -0
@@ -912,6 +912,9 @@ static struct hv_driver hvfb_drv = { .id_table = id_table, .probe = hvfb_probe, .remove = hvfb_remove, + .driver = { + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, }; static int hvfb_pci_stub_probe(struct pci_dev *pdev,
@@ -929,6 +932,9 @@ static struct pci_driver hvfb_pci_stub_driver = { .id_table = pci_stub_id_table, .probe = hvfb_pci_stub_probe, .remove = hvfb_pci_stub_remove, + .driver = { + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + } };static int __init hvfb_drv_init (void )
Signature · 1 line
2.17.1
PATCH 2/8 x86/hyperv: Add interrupt handler annotations
From: Michael Kelley <[email protected]>
Add standard interrupt handler annotations to hyperv_vector_handler(). This does not fix any observed bug, but avoids potential removal of the code by link time optimization and makes it consistent with hv_stimer0_vector_handler in the same source file.
--- arch/x86/kernel/cpu/mshyperv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/mshyperv.c +1 -1
@@ -41,7 +41,7 @@ static void (*hv_stimer0_handler)(void);static void (*hv_kexec_handler)(void );static void (*hv_crash_handler)(struct pt_regs *regs); -void hyperv_vector_handler (struct pt_regs *regs) +__visible void __irq_entry hyperv_vector_handler(struct pt_regs *regs) {struct pt_regs *old_regs =set_irq_regs (regs);
Signature · 1 line
2.17.1
PATCH 3/8 Drivers: hv: vmbus: Add comments on ring buffer signaling
In reply to [email protected]From: Michael Kelley <[email protected]>
Add comments describing intricacies of Hyper-V ring buffer signaling code. This information is not in Hyper-V public documents, so include here to capture the knowledge for future coders.
There are no code changes in this commit.
--- drivers/hv/ring_buffer.c | 65 +++++++++++++++++++++++++++++++++------- include/linux/hyperv.h | 31 ++++++++++++++----- 2 files changed, 77 insertions(+), 19 deletions(-)
drivers/hv/ring_buffer.c +54 -11
@@ -429,7 +429,24 @@ static u32 hv_pkt_iter_bytes_read(const struct hv_ring_buffer_info *rbi, }/* -* Update host ring buffer after iterating over packets. +* Update host ring buffer after iterating over packets. If the host has +* stopped queuing new entries because it found the ring buffer full, and +* sufficient space is being freed up, signal the host. But be careful to +* only signal the host when necessary, both for performance reasons and +* because Hyper-V protects itself by throttling guests that signal +* inappropriately. +* +* Determining when to signal is tricky. There are three key data inputs +* that must be handled in this order to avoid race conditions: +* +* 1. Update the read_index +* 2. Read the pending_send_sz +* 3. Read the current write_index +* +* The interrupt_mask is not used to determine when to signal. The +* interrupt_mask is used only on the guest->host ring buffer when +* sending requests to the host. The host does not use it on the host-> +* guest ring buffer to indicate whether it should be signaled. */ void hv_pkt_iter_close (struct vmbus_channel *channel) {
@@ -445,22 +462,30 @@ void hv_pkt_iter_close(struct vmbus_channel *channel) start_read_index = rbi->ring_buffer->read_index; rbi->ring_buffer->read_index = rbi->priv_read_index; +/* +* Older versions of Hyper-V (before WS2102 and Win8) do not +* implement pending_send_sz and simply poll if the host->guest +* ring buffer is full. No signaling is needed or expected. +*/ if (!rbi->ring_buffer->feature_bits.feat_pending_send_sz)return ;/* * Issue a full memory barrier before making the signaling decision. -* Here is the reason for having this barrier: -* If the reading of the pend_sz (in this function) -* were to be reordered and read before we commit the new read -* index (in the calling function) we could -* have a problem. If the host were to set the pending_sz after we -* have sampled pending_sz and go to sleep before we commit the +* If reading pending_send_sz were to be reordered and happen +* before we commit the new read_index, a race could occur. If the +* host were to set the pending_send_sz after we have sampled +* pending_send_sz, and the ring buffer blocks before we commit the * read index, we could miss sending the interrupt. Issue a full * memory barrier to address this. */ virt_mb (); +/* +* If the pending_send_sz is zero, then the ring buffer is not +* blocked and there is no need to signal. This is far by the +* most common case, so exit quickly for best performance. +*/ pending_sz =READ_ONCE (rbi->ring_buffer->pending_send_sz);if (!pending_sz)return ;
@@ -474,14 +499,32 @@ void hv_pkt_iter_close(struct vmbus_channel *channel) bytes_read =hv_pkt_iter_bytes_read (rbi, start_read_index);/* -* If there was space before we began iteration, -* then host was not blocked. +* We want to signal the host only if we're transitioning +* from a "not enough free space" state to a "enough free +* space" state. For example, it's possible that this function +* could run and free up enough space to signal the host, and then +* run again and free up additional space before the host has a +* chance to clear the pending_send_sz. The 2nd invocation would +* be a null transition from "enough free space" to "enough free +* space", which doesn't warrant a signal. +* +* Exactly filling the ring buffer is treated as "not enough +* space". The ring buffer always must have at least one byte +* empty so the empty and full conditions are distinguishable. +* hv_get_bytes_to_write() doesn't fully tell the truth in +* this regard. +* +* So first check if we were in the "enough free space" state +* before we began the iteration. If so, the host was not +* blocked, and there's no need to signal. */ -if (curr_write_sz - bytes_read > pending_sz)return ; -/* If pending write will not fit, don't give false hope. */ +/* +* Similarly, if the new state is "not enough space", then +* there's no need to signal. +*/ if (curr_write_sz <= pending_sz)return ;
include/linux/hyperv.h +23 -8
@@ -88,18 +88,33 @@ struct hv_ring_buffer {u32 interrupt_mask;/* -* Win8 uses some of the reserved bits to implement -* interrupt driven flow management. On the send side -* we can request that the receiver interrupt the sender -* when the ring transitions from being full to being able -* to handle a message of size "pending_send_sz". +* WS2012/Win8 and later versions of Hyper-V implement interrupt +* driven flow management. The feature bit feat_pending_send_sz +* is set by the host on the host->guest ring buffer, and by the +* guest on the guest->host ring buffer. * -* Add necessary state for this enhancement. +* The meaning of the feature bit is a bit complex in that it has +* semantics that apply to both ring buffers. If the guest sets +* the feature bit in the guest->host ring buffer, the guest is +* telling the host that: +* 1) It will set the pending_send_sz field in the guest->host ring +* buffer when it is waiting for space to become available, and +* 2) It will read the pending_send_sz field in the host->guest +* ring buffer and interrupt the host when it frees enough space +* +* Similarly, if the host sets the feature bit in the host->guest +* ring buffer, the host is telling the guest that: +* 1) It will set the pending_send_sz field in the host->guest ring +* buffer when it is waiting for space to become available, and +* 2) It will read the pending_send_sz field in the guest->host +* ring buffer and interrupt the guest when it frees enough space +* +* If either the guest or host does not set the feature bit that it +* owns, that guest or host must do polling if it encounters a full +* ring buffer, and not signal the other end with an interrupt. */ u32 pending_send_sz; -u32 reserved1[12 ]; - union { struct { u32 feat_pending_send_sz:1;
Signature · 1 line
2.17.1
PATCH 4/8 Drivers: hv: vmbus: Fix the offer_in_progress in vmbus_process_offer()
In reply to [email protected]From: Dexuan Cui <[email protected]>
I didn't really hit a real bug, but just happened to spot the bug:
we have decreased the counter at the beginning of vmbus_process_offer(), so we mustn't decrease it again.
--- drivers/hv/channel_mgmt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/hv/channel_mgmt.c +1 -3
@@ -527,10 +527,8 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)struct hv_device *dev = newchannel->primary_channel->device_obj; -if (vmbus_add_channel_kobj (dev, newchannel)) { -atomic_dec (&vmbus_connection.offer_in_progress); +if (vmbus_add_channel_kobj (dev, newchannel)) goto err_free_chan; - }if (channel->sc_creation_callback !=NULL ) channel->sc_creation_callback (newchannel);
Signature · 1 line
2.17.1
PATCH 5/8 Drivers: hv: vmbus: Remove x86 MSR refs in arch independent code
In reply to [email protected]From: Michael Kelley <[email protected]>
In architecture independent code for manipulating Hyper-V synthetic timers and synthetic interrupts, pass in an ordinal number identifying the timer or interrupt, rather than an actual MSR register address. Then in x86/x64 specific code, map the ordinal number to the appropriate MSR. This change facilitates the introduction of an ARM64 version of Hyper-V, which uses the same synthetic timers and interrupts, but a different mechanism for accessing them.
--- arch/x86/include/asm/mshyperv.h | 12 ++++++++---- drivers/hv/hv.c | 20 ++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-)
arch/x86/include/asm/mshyperv.h +8 -4
@@ -75,8 +75,10 @@ static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type) } } -#define hv_init_timer (timer, tick) wrmsrl(timer, tick) -#define hv_init_timer_config (config, val) wrmsrl(config, val) +#define hv_init_timer (timer, tick) \ + wrmsrl(HV_X64_MSR_STIMER0_COUNT + (2*timer), tick) +#define hv_init_timer_config (timer, val) \ + wrmsrl(HV_X64_MSR_STIMER0_CONFIG + (2*timer), val)#define hv_get_simp (val) rdmsrl(HV_X64_MSR_SIMP, val)#define hv_set_simp (val) wrmsrl(HV_X64_MSR_SIMP, val)
@@ -89,8 +91,10 @@ static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type)#define hv_get_vp_index (index) rdmsrl(HV_X64_MSR_VP_INDEX, index) -#define hv_get_synint_state (int_num, val) rdmsrl(int_num, val) -#define hv_set_synint_state (int_num, val) wrmsrl(int_num, val) +#define hv_get_synint_state (int_num, val) \ + rdmsrl(HV_X64_MSR_SINT0 + int_num, val) +#define hv_set_synint_state (int_num, val) \ + wrmsrl(HV_X64_MSR_SINT0 + int_num, val)void hyperv_callback_vector (void );void hyperv_reenlightenment_vector (void );
drivers/hv/hv.c +8 -12
@@ -127,14 +127,14 @@ static int hv_ce_set_next_event(unsigned long delta, current_tick = hyperv_cs->read (NULL ); current_tick += delta; -hv_init_timer (HV_X64_MSR_STIMER0_COUNT , current_tick); +hv_init_timer (0 , current_tick);return 0 ; }static int hv_ce_shutdown (struct clock_event_device *evt) { -hv_init_timer (HV_X64_MSR_STIMER0_COUNT ,0 ); -hv_init_timer_config (HV_X64_MSR_STIMER0_CONFIG ,0 ); +hv_init_timer (0 ,0 ); +hv_init_timer_config (0 ,0 );if (direct_mode_enabled)hv_disable_stimer0_percpu_irq (stimer0_irq);
@@ -164,7 +164,7 @@ static int hv_ce_set_oneshot(struct clock_event_device *evt) timer_cfg.direct_mode =0 ; timer_cfg.sintx =VMBUS_MESSAGE_SINT ; } -hv_init_timer_config (HV_X64_MSR_STIMER0_CONFIG , timer_cfg.as_uint64); +hv_init_timer_config (0 , timer_cfg.as_uint64);return 0 ; }
@@ -298,8 +298,7 @@ int hv_synic_init(unsigned int cpu)hv_set_siefp (siefp.as_uint64);/* Setup the shared SINT. */ -hv_get_synint_state (HV_X64_MSR_SINT0 +VMBUS_MESSAGE_SINT , - shared_sint.as_uint64); +hv_get_synint_state (VMBUS_MESSAGE_SINT , shared_sint.as_uint64); shared_sint.vector =HYPERVISOR_CALLBACK_VECTOR ; shared_sint.masked = false;
@@ -308,8 +307,7 @@ int hv_synic_init(unsigned int cpu)else shared_sint.auto_eoi = true; -hv_set_synint_state (HV_X64_MSR_SINT0 +VMBUS_MESSAGE_SINT , - shared_sint.as_uint64); +hv_set_synint_state (VMBUS_MESSAGE_SINT , shared_sint.as_uint64);/* Enable the global synic bit */ hv_get_synic_state (sctrl.as_uint64);
@@ -405,15 +403,13 @@ int hv_synic_cleanup(unsigned int cpu)put_cpu_ptr (hv_cpu); } -hv_get_synint_state (HV_X64_MSR_SINT0 +VMBUS_MESSAGE_SINT , - shared_sint.as_uint64); +hv_get_synint_state (VMBUS_MESSAGE_SINT , shared_sint.as_uint64); shared_sint.masked =1 ;/* Need to correctly cleanup in the case of SMP!!! */ /* Disable the interrupt */ -hv_set_synint_state (HV_X64_MSR_SINT0 +VMBUS_MESSAGE_SINT , - shared_sint.as_uint64); +hv_set_synint_state (VMBUS_MESSAGE_SINT , shared_sint.as_uint64);hv_get_simp (simp.as_uint64); simp.simp_enabled =0 ;
Signature · 1 line
2.17.1
PATCH 6/8 Drivers: hv: vmbus: Make TLFS #define names architecture neutral
In reply to [email protected]From: Michael Kelley <[email protected]>
The Hyper-V feature and hint flags in hyperv-tlfs.h are all defined with the string "X64" in the name. Some of these flags are indeed x86/x64 specific, but others are not. For the ones that are used in architecture independent Hyper-V driver code, or will be used in the upcoming support for Hyper-V for ARM64, this patch removes the "X64" from the name.
This patch changes the flags that are currently known to be used on multiple architectures. Hyper-V for ARM64 is still a work-in-progress and the Top Level Functional Spec (TLFS) has not been separated into x86/x64 and ARM64 areas. So additional flags may need to be updated later.
This patch only changes symbol names. There are no functional changes.
--- arch/x86/hyperv/hv_init.c | 4 ++-- arch/x86/include/asm/hyperv-tlfs.h | 12 ++++++------ arch/x86/kernel/cpu/mshyperv.c | 4 ++-- drivers/hv/hv.c | 10 +++++----- 4 files changed, 15 insertions(+), 15 deletions(-)
arch/x86/hyperv/hv_init.c +2 -2
@@ -302,7 +302,7 @@ void hyperv_init(void)* Register Hyper-V specific clocksource. */ #ifdef CONFIG_HYPERV_TSCPAGE -if (ms_hyperv.features &HV_X64_MSR_REFERENCE_TSC_AVAILABLE ) { +if (ms_hyperv.features &HV_MSR_REFERENCE_TSC_AVAILABLE ) {union hv_x64_msr_hypercall_contents tsc_msr; tsc_pg =__vmalloc (PAGE_SIZE ,GFP_KERNEL ,PAGE_KERNEL );
@@ -331,7 +331,7 @@ void hyperv_init(void)*/ hyperv_cs = &hyperv_cs_msr; -if (ms_hyperv.features &HV_X64_MSR_TIME_REF_COUNT_AVAILABLE ) +if (ms_hyperv.features &HV_MSR_TIME_REF_COUNT_AVAILABLE )clocksource_register_hz (&hyperv_cs_msr,NSEC_PER_SEC /100 );return ;
arch/x86/include/asm/hyperv-tlfs.h +6 -6
@@ -35,9 +35,9 @@/* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */ #define HV_X64_MSR_VP_RUNTIME_AVAILABLE (1 << 0)/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/ -#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1) +#define HV_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1)/* Partition reference TSC MSR is available */ -#define HV_X64_MSR_REFERENCE_TSC_AVAILABLE (1 << 9) +#define HV_MSR_REFERENCE_TSC_AVAILABLE (1 << 9)/* A partition's reference time stamp counter (TSC) page */ #define HV_X64_MSR_REFERENCE_TSC 0x40000021
@@ -60,7 +60,7 @@* Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through * HV_X64_MSR_STIMER3_COUNT) available */ -#define HV_X64_MSR_SYNTIMER_AVAILABLE (1 << 3) +#define HV_MSR_SYNTIMER_AVAILABLE (1 << 3)/* * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR) * are available
@@ -86,7 +86,7 @@#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)/* stimer Direct Mode is available */ -#define HV_X64_STIMER_DIRECT_MODE_AVAILABLE (1 << 19) +#define HV_STIMER_DIRECT_MODE_AVAILABLE (1 << 19)/* * Feature identification: EBX indicates which flags were specified at
@@ -160,9 +160,9 @@#define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5)/* -* Virtual APIC support +* Recommend not using Auto End-Of-Interrupt feature */ -#define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9) +#define HV_DEPRECATING_AEOI_RECOMMENDED (1 << 9)/* Recommend using the newer ExProcessorMasks interface */ #define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11)
arch/x86/kernel/cpu/mshyperv.c +2 -2
@@ -50,7 +50,7 @@ __visible void __irq_entry hyperv_vector_handler(struct pt_regs *regs)if (vmbus_handler)vmbus_handler (); -if (ms_hyperv.hints &HV_X64_DEPRECATING_AEOI_RECOMMENDED ) +if (ms_hyperv.hints &HV_DEPRECATING_AEOI_RECOMMENDED )ack_APIC_irq ();exiting_irq ();
@@ -300,7 +300,7 @@ static void __init ms_hyperv_init_platform(void) hyperv_reenlightenment_vector);/* Setup the IDT for stimer0 */ -if (ms_hyperv.misc_features &HV_X64_STIMER_DIRECT_MODE_AVAILABLE ) +if (ms_hyperv.misc_features &HV_STIMER_DIRECT_MODE_AVAILABLE )alloc_intr_gate (HYPERV_STIMER0_VECTOR , hv_stimer0_callback_vector);#endif
drivers/hv/hv.c +5 -5
@@ -64,7 +64,7 @@ int hv_init(void)return -ENOMEM ; direct_mode_enabled = ms_hyperv.misc_features & -HV_X64_STIMER_DIRECT_MODE_AVAILABLE ; +HV_STIMER_DIRECT_MODE_AVAILABLE ;return 0 ; }
@@ -302,7 +302,7 @@ int hv_synic_init(unsigned int cpu) shared_sint.vector =HYPERVISOR_CALLBACK_VECTOR ; shared_sint.masked = false; -if (ms_hyperv.hints &HV_X64_DEPRECATING_AEOI_RECOMMENDED ) +if (ms_hyperv.hints &HV_DEPRECATING_AEOI_RECOMMENDED ) shared_sint.auto_eoi = false;else shared_sint.auto_eoi = true;
@@ -320,7 +320,7 @@ int hv_synic_init(unsigned int cpu)/* * Register the per-cpu clockevent source. */ -if (ms_hyperv.features &HV_X64_MSR_SYNTIMER_AVAILABLE ) +if (ms_hyperv.features &HV_MSR_SYNTIMER_AVAILABLE ) clockevents_config_and_register(hv_cpu->clk_evt, HV_TIMER_FREQUENCY, HV_MIN_DELTA_TICKS,
@@ -335,7 +335,7 @@ void hv_synic_clockevents_cleanup(void) {int cpu; -if (!(ms_hyperv.features &HV_X64_MSR_SYNTIMER_AVAILABLE )) +if (!(ms_hyperv.features &HV_MSR_SYNTIMER_AVAILABLE ))return ;if (direct_mode_enabled)
@@ -394,7 +394,7 @@ int hv_synic_cleanup(unsigned int cpu)return -EBUSY ;/* Turn off clockevent device */ -if (ms_hyperv.features &HV_X64_MSR_SYNTIMER_AVAILABLE ) { +if (ms_hyperv.features &HV_MSR_SYNTIMER_AVAILABLE ) {struct hv_per_cpu_context *hv_cpu =this_cpu_ptr (hv_context.cpu_context);
Signature · 1 line
2.17.1
PATCH 7/8 tools: hv: update lsvmbus to be compatible with python3
In reply to [email protected]From: Olaf Hering <[email protected]>
Python3 changed the way how 'print' works.
Adjust the code to a syntax that is understood by python2 and python3.
--- tools/hv/lsvmbus | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
tools/hv/lsvmbus +6 -6
@@ -17,7 +17,7 @@ if options.verbose is not None: vmbus_sys_path = '/sys/bus/vmbus/devices' if not os.path.isdir(vmbus_sys_path): - print "%s doesn't exist: exiting..." % vmbus_sys_path + print("%s doesn't exist: exiting..." % vmbus_sys_path) exit(-1) vmbus_dev_dict = {
@@ -93,11 +93,11 @@ format2 = '%2s: Class_ID = %s - %s\n\tDevice_ID = %s\n\tSysfs path: %s\n%s' for d in vmbus_dev_list: if verbose == 0: - print ('VMBUS ID ' + format0) % (d.vmbus_id, d.dev_desc) + print(('VMBUS ID ' + format0) % (d.vmbus_id, d.dev_desc)) elif verbose == 1: - print ('VMBUS ID ' + format1) % \ - (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping) + print (('VMBUS ID ' + format1) % \ + (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping)) else: - print ('VMBUS ID ' + format2) % \ + print (('VMBUS ID ' + format2) % \ (d.vmbus_id, d.class_id, d.dev_desc, \ - d.device_id, d.sysfs_path, d.chn_vp_mapping) + d.device_id, d.sysfs_path, d.chn_vp_mapping))
Signature · 1 line
2.17.1
PATCH 8/8 Tools: hv: vss: fix loop device detection
In reply to [email protected]From: Vitaly Kuznetsov <[email protected]>
Commit ea81fdf0981d ("Tools: hv: vss: Skip freezing filesystems backed by loop") added skip for filesystems backed by loop device. However, it seems the detection of such cases is incomplete.
It was found that with 'devicemapper' storage driver docker creates the following chain:
NAME MAJ:MIN
loop0 7:0
..docker-8:4-8473394-pool 253:0
..docker-8:4-8473394-eac... 253:1
so when we're looking at the mounted device we see major '253' and not '7'.
Solve the issue by walking /sys/dev/block/*/slaves chain and checking if there's a loop device somewhere.
Other than that, don't skip mountpoints silently when stat() fails. In case e.g. SELinux is failing stat we don't want to skip freezing everything without letting user know about the failure.
--- tools/hv/hv_vss_daemon.c | 65 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-)
tools/hv/hv_vss_daemon.c +61 -4
@@ -36,6 +36,8 @@#include <linux/hyperv.h> #include <syslog.h> #include <getopt.h> +#include <stdbool.h> +#include <dirent.h> /* Don't use syslog() in the function since that can cause write to disk */ static int vss_do_freeze (char *dir,unsigned int cmd)
@@ -68,6 +70,55 @@ static int vss_do_freeze(char *dir, unsigned int cmd)return !!ret; } +static bool is_dev_loop (const char *blkname) +{ +char *buffer; +DIR *dir; +struct dirent *entry; +bool ret = false; + + buffer =malloc (PATH_MAX ); +if (!buffer) { +syslog (LOG_ERR ,"Can't allocate memory!" ); +exit (1 ); + } + +snprintf (buffer,PATH_MAX ,"%s/loop" , blkname); +if (!access (buffer,R_OK |X_OK )) { + ret = true; + goto free_buffer; + }else if (errno !=ENOENT ) { +syslog (LOG_ERR ,"Can't access: %s; error:%d %s!" , + buffer, errno,strerror (errno)); + } + +snprintf (buffer,PATH_MAX ,"%s/slaves" , blkname); + dir =opendir (buffer); +if (!dir) { +if (errno !=ENOENT ) +syslog (LOG_ERR ,"Can't opendir: %s; error:%d %s!" , + buffer, errno,strerror (errno)); + goto free_buffer; + } + +while ((entry =readdir (dir)) !=NULL ) { +if (strcmp (entry->d_name,"." ) ==0 || +strcmp (entry->d_name,".." ) ==0 ) +continue ; + +snprintf (buffer,PATH_MAX ,"%s/slaves/%s" , blkname, + entry->d_name); +if (is_dev_loop (buffer)) { + ret = true; +break ; + } + } +closedir (dir); +free_buffer: +free (buffer); +return ret; +} +static int vss_operate (int operation) {char match[] ="/dev/" ;
@@ -75,6 +126,7 @@ static int vss_operate(int operation)struct mntent *ent;struct stat sb;char errdir[1024 ] = {0 }; +char blkdir[23 ];/* /sys/dev/block/XXX:XXX */ unsigned int cmd;int error =0 , root_seen =0 , save_errno =0 ;
@@ -96,10 +148,15 @@ static int vss_operate(int operation)while ((ent =getmntent (mounts))) {if (strncmp (ent->mnt_fsname, match,strlen (match)))continue ; -if (stat (ent->mnt_fsname, &sb) ==-1 ) -continue ; -if (S_ISBLK (sb.st_mode) &&major (sb.st_rdev) ==LOOP_MAJOR ) -continue ; +if (stat (ent->mnt_fsname, &sb)) { +syslog (LOG_ERR ,"Can't stat: %s; error:%d %s!" , + ent->mnt_fsname, errno,strerror (errno)); + }else { +sprintf (blkdir,"/sys/dev/block/%d:%d" , +major (sb.st_rdev),minor (sb.st_rdev)); +if (is_dev_loop (blkdir)) +continue ; + }if (hasmntopt (ent,MNTOPT_RO ) !=NULL )continue ;if (strcmp (ent->mnt_type,"vfat" ) ==0 )
Signature · 1 line
2.17.1