Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F101908836
D6405.id16432.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D6405.id16432.diff
View Options
Index: sys/dev/hyperv/vmbus/hv_connection.c
===================================================================
--- sys/dev/hyperv/vmbus/hv_connection.c
+++ sys/dev/hyperv/vmbus/hv_connection.c
@@ -289,56 +289,20 @@
return (ret);
}
-/**
- * Handler for events
- */
-void
-hv_vmbus_on_events(int cpu)
+static __inline void
+vmbus_event_flags_proc(unsigned long *event_flags, int flag_cnt)
{
- unsigned long *intr_flags;
- hv_vmbus_synic_event_flags *event;
- void *page_addr;
- int flag_cnt, f;
-
- KASSERT(cpu <= mp_maxid, ("VMBUS: hv_vmbus_on_events: "
- "cpu out of range!"));
-
- page_addr = hv_vmbus_g_context.syn_ic_event_page[cpu];
- event = (hv_vmbus_synic_event_flags *)
- page_addr + HV_VMBUS_MESSAGE_SINT;
- if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) ||
- (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) {
- flag_cnt = HV_MAX_NUM_CHANNELS_SUPPORTED >>
- HV_CHANNEL_ULONG_SHIFT;
- /*
- * receive size is 1/2 page and divide that by 4 bytes
- */
- if (atomic_testandclear_int(&event->flags32[0], 0))
- intr_flags = hv_vmbus_g_connection.recv_interrupt_page;
- else
- return;
- } else {
- /*
- * On Host with Win8 or above, the event page can be
- * checked directly to get the id of the channel
- * that has the pending interrupt.
- */
- flag_cnt = VMBUS_PCPU_GET(event_flag_cnt, cpu);
- intr_flags = event->flagsul;
- }
+ int f;
- /*
- * Check events
- */
- for (f = 0; f < flag_cnt; f++) {
+ for (f = 0; f < flag_cnt; ++f) {
uint32_t rel_id_base;
unsigned long flags;
int bit;
- if (intr_flags[f] == 0)
+ if (event_flags[f] == 0)
continue;
- flags = atomic_swap_long(&intr_flags[f], 0);
+ flags = atomic_swap_long(&event_flags[f], 0);
rel_id_base = f << HV_CHANNEL_ULONG_SHIFT;
while ((bit = ffsl(flags)) != 0) {
@@ -362,6 +326,37 @@
}
}
+void
+vmbus_event_proc(struct vmbus_softc *sc, int cpu)
+{
+ hv_vmbus_synic_event_flags *event;
+
+ event = ((hv_vmbus_synic_event_flags *)
+ hv_vmbus_g_context.syn_ic_event_page[cpu]) + HV_VMBUS_MESSAGE_SINT;
+
+ /*
+ * On Host with Win8 or above, the event page can be checked directly
+ * to get the id of the channel that has the pending interrupt.
+ */
+ vmbus_event_flags_proc(event->flagsul,
+ VMBUS_SC_PCPU_GET(sc, event_flag_cnt, cpu));
+}
+
+void
+vmbus_event_proc_compat(struct vmbus_softc *sc __unused, int cpu)
+{
+ hv_vmbus_synic_event_flags *event;
+
+ event = ((hv_vmbus_synic_event_flags *)
+ hv_vmbus_g_context.syn_ic_event_page[cpu]) + HV_VMBUS_MESSAGE_SINT;
+
+ if (atomic_testandclear_int(&event->flags32[0], 0)) {
+ vmbus_event_flags_proc(
+ hv_vmbus_g_connection.recv_interrupt_page,
+ HV_MAX_NUM_CHANNELS_SUPPORTED >> HV_CHANNEL_ULONG_SHIFT);
+ }
+}
+
/**
* Send a msg on the vmbus's message connection
*/
Index: sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
===================================================================
--- sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
+++ sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
@@ -146,6 +146,7 @@
static inline int
hv_vmbus_isr(struct trapframe *frame)
{
+ struct vmbus_softc *sc = vmbus_get_softc();
int cpu;
hv_vmbus_message* msg;
void* page_addr;
@@ -157,8 +158,7 @@
* before checking for messages. This is the way they do it
* in Windows when running as a guest in Hyper-V
*/
-
- hv_vmbus_on_events(cpu);
+ sc->vmbus_event_proc(sc, cpu);
/* Check if there are actual msgs to be process */
page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu];
@@ -388,6 +388,7 @@
static int
vmbus_bus_init(void)
{
+ struct vmbus_softc *sc;
int i, j, n, ret;
char buf[MAXCOMLEN + 1];
cpuset_t cpu_mask;
@@ -396,6 +397,7 @@
return (0);
vmbus_inited = 1;
+ sc = vmbus_get_softc();
ret = hv_vmbus_init();
@@ -481,6 +483,12 @@
if (ret != 0)
goto cleanup1;
+ if (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008 ||
+ hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)
+ sc->vmbus_event_proc = vmbus_event_proc_compat;
+ else
+ sc->vmbus_event_proc = vmbus_event_proc;
+
hv_vmbus_request_channel_offers();
vmbus_scan();
@@ -515,6 +523,11 @@
return (ret);
}
+static void
+vmbus_event_proc_dummy(struct vmbus_softc *sc __unused, int cpu __unused)
+{
+}
+
static int
vmbus_attach(device_t dev)
{
@@ -524,6 +537,13 @@
vmbus_devp = dev;
vmbus_sc = device_get_softc(dev);
+ /*
+ * Event processing logic will be configured:
+ * - After the vmbus protocol version negotiation.
+ * - Before we request channel offers.
+ */
+ vmbus_sc->vmbus_event_proc = vmbus_event_proc_dummy;
+
/*
* If the system has already booted and thread
* scheduling is possible indicated by the global
Index: sys/dev/hyperv/vmbus/hv_vmbus_priv.h
===================================================================
--- sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+++ sys/dev/hyperv/vmbus/hv_vmbus_priv.h
@@ -753,7 +753,6 @@
int hv_vmbus_disconnect(void);
int hv_vmbus_post_message(void *buffer, size_t buf_size);
int hv_vmbus_set_event(hv_vmbus_channel *channel);
-void hv_vmbus_on_events(int cpu);
/**
* Event Timer interfaces
Index: sys/dev/hyperv/vmbus/vmbus_var.h
===================================================================
--- sys/dev/hyperv/vmbus/vmbus_var.h
+++ sys/dev/hyperv/vmbus/vmbus_var.h
@@ -36,6 +36,7 @@
} __aligned(CACHE_LINE_SIZE);
struct vmbus_softc {
+ void (*vmbus_event_proc)(struct vmbus_softc *, int);
struct vmbus_pcpu_data vmbus_pcpu[MAXCPU];
};
@@ -47,11 +48,15 @@
return vmbus_sc;
}
-#define VMBUS_PCPU_GET(field, cpu) \
- (vmbus_get_softc())->vmbus_pcpu[cpu].field
-#define VMBUS_PCPU_PTR(field, cpu) \
- &(vmbus_get_softc())->vmbus_pcpu[cpu].field
+#define VMBUS_SC_PCPU_GET(sc, field, cpu) (sc)->vmbus_pcpu[(cpu)].field
+#define VMBUS_SC_PCPU_PTR(sc, field, cpu) &(sc)->vmbus_pcpu[(cpu)].field
+#define VMBUS_PCPU_GET(field, cpu) \
+ VMBUS_SC_PCPU_GET(vmbus_get_softc(), field, (cpu))
+#define VMBUS_PCPU_PTR(field, cpu) \
+ VMBUS_SC_PCPU_PTR(vmbus_get_softc(), field, (cpu))
void vmbus_on_channel_open(const struct hv_vmbus_channel *);
+void vmbus_event_proc(struct vmbus_softc *, int);
+void vmbus_event_proc_compat(struct vmbus_softc *, int);
#endif /* !_VMBUS_VAR_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 6, 12:03 PM (21 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14485683
Default Alt Text
D6405.id16432.diff (6 KB)
Attached To
Mode
D6405: hyperv/vmbus: Avoid two unnecessary protocol checks on isr handling path
Attached
Detach File
Event Timeline
Log In to Comment