Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
Show All 33 Lines | |||||
#include <dev/hyperv/vmbus/hv_vmbus_priv.h> | #include <dev/hyperv/vmbus/hv_vmbus_priv.h> | ||||
#include <dev/hyperv/vmbus/vmbus_reg.h> | #include <dev/hyperv/vmbus/vmbus_reg.h> | ||||
#include <dev/hyperv/vmbus/vmbus_var.h> | #include <dev/hyperv/vmbus/vmbus_var.h> | ||||
typedef void (*vmbus_chanmsg_proc_t) | typedef void (*vmbus_chanmsg_proc_t) | ||||
(struct vmbus_softc *, const struct vmbus_message *); | (struct vmbus_softc *, const struct vmbus_message *); | ||||
static void vmbus_channel_on_offer_internal( | static struct hv_vmbus_channel *hv_vmbus_allocate_channel(struct vmbus_softc *); | ||||
static void vmbus_channel_on_offer_internal(struct vmbus_softc *, | |||||
const hv_vmbus_channel_offer_channel *offer); | const hv_vmbus_channel_offer_channel *offer); | ||||
static void vmbus_channel_on_offer_rescind_internal(void *context); | static void vmbus_channel_on_offer_rescind_internal(void *context); | ||||
static void vmbus_channel_on_offer(struct vmbus_softc *, | static void vmbus_channel_on_offer(struct vmbus_softc *, | ||||
const struct vmbus_message *); | const struct vmbus_message *); | ||||
static void vmbus_channel_on_open_result(struct vmbus_softc *, | static void vmbus_channel_on_open_result(struct vmbus_softc *, | ||||
const struct vmbus_message *); | const struct vmbus_message *); | ||||
static void vmbus_channel_on_offer_rescind(struct vmbus_softc *, | static void vmbus_channel_on_offer_rescind(struct vmbus_softc *, | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | hv_queue_work_item( | ||||
return (taskqueue_enqueue(taskqueue_thread, &w->work)); | return (taskqueue_enqueue(taskqueue_thread, &w->work)); | ||||
} | } | ||||
/** | /** | ||||
* @brief Allocate and initialize a vmbus channel object | * @brief Allocate and initialize a vmbus channel object | ||||
*/ | */ | ||||
hv_vmbus_channel* | static struct hv_vmbus_channel * | ||||
hv_vmbus_allocate_channel(void) | hv_vmbus_allocate_channel(struct vmbus_softc *sc) | ||||
{ | { | ||||
hv_vmbus_channel* channel; | struct hv_vmbus_channel *channel; | ||||
channel = (hv_vmbus_channel*) malloc( | channel = malloc(sizeof(*channel), M_DEVBUF, M_WAITOK | M_ZERO); | ||||
sizeof(hv_vmbus_channel), | channel->vmbus_sc = sc; | ||||
M_DEVBUF, | |||||
M_WAITOK | M_ZERO); | |||||
mtx_init(&channel->sc_lock, "vmbus multi channel", NULL, MTX_DEF); | mtx_init(&channel->sc_lock, "vmbus multi channel", NULL, MTX_DEF); | ||||
TAILQ_INIT(&channel->sc_list_anchor); | TAILQ_INIT(&channel->sc_list_anchor); | ||||
return (channel); | return (channel); | ||||
} | } | ||||
/** | /** | ||||
▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | vmbus_channel_cpu_set(struct hv_vmbus_channel *chan, int cpu) | ||||
if (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008 || | if (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008 || | ||||
hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7) { | hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7) { | ||||
/* Only cpu0 is supported */ | /* Only cpu0 is supported */ | ||||
cpu = 0; | cpu = 0; | ||||
} | } | ||||
chan->target_cpu = cpu; | chan->target_cpu = cpu; | ||||
chan->target_vcpu = VMBUS_PCPU_GET(vmbus_get_softc(), vcpuid, cpu); | chan->target_vcpu = VMBUS_PCPU_GET(chan->vmbus_sc, vcpuid, cpu); | ||||
if (bootverbose) { | if (bootverbose) { | ||||
printf("vmbus_chan%u: assigned to cpu%u [vcpu%u]\n", | printf("vmbus_chan%u: assigned to cpu%u [vcpu%u]\n", | ||||
chan->offer_msg.child_rel_id, | chan->offer_msg.child_rel_id, | ||||
chan->target_cpu, chan->target_vcpu); | chan->target_cpu, chan->target_vcpu); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | vmbus_channel_on_offer(struct vmbus_softc *sc, const struct vmbus_message *msg) | ||||
const hv_vmbus_channel_offer_channel *offer; | const hv_vmbus_channel_offer_channel *offer; | ||||
mtx_lock(&vmbus_chwait_lock); | mtx_lock(&vmbus_chwait_lock); | ||||
if ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0) | if ((vmbus_chancnt & VMBUS_CHANCNT_DONE) == 0) | ||||
vmbus_chancnt++; | vmbus_chancnt++; | ||||
mtx_unlock(&vmbus_chwait_lock); | mtx_unlock(&vmbus_chwait_lock); | ||||
offer = (const hv_vmbus_channel_offer_channel *)msg->msg_data; | offer = (const hv_vmbus_channel_offer_channel *)msg->msg_data; | ||||
vmbus_channel_on_offer_internal(offer); | vmbus_channel_on_offer_internal(sc, offer); | ||||
} | } | ||||
static void | static void | ||||
vmbus_channel_on_offer_internal(const hv_vmbus_channel_offer_channel *offer) | vmbus_channel_on_offer_internal(struct vmbus_softc *sc, | ||||
const hv_vmbus_channel_offer_channel *offer) | |||||
{ | { | ||||
hv_vmbus_channel* new_channel; | hv_vmbus_channel* new_channel; | ||||
/* Allocate the channel object and save this offer */ | /* Allocate the channel object and save this offer */ | ||||
new_channel = hv_vmbus_allocate_channel(); | new_channel = hv_vmbus_allocate_channel(sc); | ||||
/* | /* | ||||
* By default we setup state to enable batched | * By default we setup state to enable batched | ||||
* reading. A specific service can choose to | * reading. A specific service can choose to | ||||
* disable this prior to opening the channel. | * disable this prior to opening the channel. | ||||
*/ | */ | ||||
new_channel->batched_reading = TRUE; | new_channel->batched_reading = TRUE; | ||||
▲ Show 20 Lines • Show All 276 Lines • ▼ Show 20 Lines | vmbus_select_outgoing_channel(struct hv_vmbus_channel *primary) | ||||
if (TAILQ_EMPTY(&primary->sc_list_anchor)) { | if (TAILQ_EMPTY(&primary->sc_list_anchor)) { | ||||
return outgoing_channel; | return outgoing_channel; | ||||
} | } | ||||
if (smp_pro_id >= MAXCPU) { | if (smp_pro_id >= MAXCPU) { | ||||
return outgoing_channel; | return outgoing_channel; | ||||
} | } | ||||
cur_vcpu = VMBUS_PCPU_GET(vmbus_get_softc(), vcpuid, smp_pro_id); | cur_vcpu = VMBUS_PCPU_GET(primary->vmbus_sc, vcpuid, smp_pro_id); | ||||
TAILQ_FOREACH(new_channel, &primary->sc_list_anchor, sc_list_entry) { | TAILQ_FOREACH(new_channel, &primary->sc_list_anchor, sc_list_entry) { | ||||
if (new_channel->state != HV_CHANNEL_OPENED_STATE){ | if (new_channel->state != HV_CHANNEL_OPENED_STATE){ | ||||
continue; | continue; | ||||
} | } | ||||
if (new_channel->target_vcpu == cur_vcpu){ | if (new_channel->target_vcpu == cur_vcpu){ | ||||
return new_channel; | return new_channel; | ||||
▲ Show 20 Lines • Show All 90 Lines • Show Last 20 Lines |