summaryrefslogtreecommitdiffstats
path: root/sys/dev/hyperv/utilities
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-02-05 07:09:58 +0000
committersephe <sephe@FreeBSD.org>2016-02-05 07:09:58 +0000
commit241c7a11bd40d303492821ebef545ea3ffbca849 (patch)
tree9944b8d35d6357d2f101861eac433339caec3dce /sys/dev/hyperv/utilities
parent43993ba1f9ee4bff5c7ee1666dde2f5fc919456b (diff)
downloadFreeBSD-src-241c7a11bd40d303492821ebef545ea3ffbca849.zip
FreeBSD-src-241c7a11bd40d303492821ebef545ea3ffbca849.tar.gz
hyperv: Use standard taskqueue instead of hv_work_queue
HyperV code was ported from Linux. There is an implementation of work queue called hv_work_queue. In FreeBSD, taskqueue could be used for the same purpose. Convert all the consumer of hv_work_queue to use taskqueue, and remove work queue implementation. Submitted by: Jun Su <junsu microsoft com> Reviewed by: adrian, Hongjiang Zhang <honzhan microsoft com> Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D4963
Diffstat (limited to 'sys/dev/hyperv/utilities')
-rw-r--r--sys/dev/hyperv/utilities/hv_kvp.c35
-rw-r--r--sys/dev/hyperv/utilities/hv_util.c58
2 files changed, 29 insertions, 64 deletions
diff --git a/sys/dev/hyperv/utilities/hv_kvp.c b/sys/dev/hyperv/utilities/hv_kvp.c
index 58d565c4..86e037a 100644
--- a/sys/dev/hyperv/utilities/hv_kvp.c
+++ b/sys/dev/hyperv/utilities/hv_kvp.c
@@ -98,7 +98,7 @@ static d_poll_t hv_kvp_dev_daemon_poll;
static int hv_kvp_req_in_progress(void);
static void hv_kvp_transaction_init(uint32_t, hv_vmbus_channel *, uint64_t, uint8_t *);
static void hv_kvp_send_msg_to_daemon(void);
-static void hv_kvp_process_request(void *context);
+static void hv_kvp_process_request(void *context, int pending);
/* hv_kvp character device structure */
static struct cdevsw hv_kvp_cdevsw =
@@ -123,9 +123,6 @@ static struct selinfo hv_kvp_selinfo;
*/
static struct {
- /* Pre-allocated work item for queue */
- hv_work_item work_item;
-
/* Unless specified the pending mutex should be
* used to alter the values of the following paramters:
* 1. req_in_progress
@@ -642,7 +639,7 @@ hv_kvp_send_msg_to_daemon(void)
* and interact with daemon
*/
static void
-hv_kvp_process_request(void *context)
+hv_kvp_process_request(void *context, int pending)
{
uint8_t *kvp_buf;
hv_vmbus_channel *channel = context;
@@ -756,23 +753,18 @@ hv_kvp_callback(void *context)
uint64_t pending_cnt = 0;
if (kvp_globals.register_done == false) {
-
kvp_globals.channelp = context;
+ TASK_INIT(&service_table[HV_KVP].task, 0, hv_kvp_process_request, context);
} else {
-
mtx_lock(&kvp_globals.pending_mutex);
kvp_globals.pending_reqs = kvp_globals.pending_reqs + 1;
pending_cnt = kvp_globals.pending_reqs;
mtx_unlock(&kvp_globals.pending_mutex);
if (pending_cnt == 1) {
hv_kvp_log_info("%s: Queuing work item\n", __func__);
- hv_queue_work_item(
- service_table[HV_KVP].work_queue,
- hv_kvp_process_request,
- context
- );
+ taskqueue_enqueue(taskqueue_thread, &service_table[HV_KVP].task);
}
- }
+ }
}
@@ -977,26 +969,13 @@ int
hv_kvp_init(hv_vmbus_service *srv)
{
int error = 0;
- hv_work_queue *work_queue = NULL;
-
- memset(&kvp_globals, 0, sizeof(kvp_globals));
- work_queue = hv_work_queue_create("KVP Service");
- if (work_queue == NULL) {
- hv_kvp_log_info("%s: Work queue alloc failed\n", __func__);
- error = ENOMEM;
- hv_kvp_log_error("%s: ENOMEM\n", __func__);
- goto Finish;
- }
- srv->work_queue = work_queue;
+ memset(&kvp_globals, 0, sizeof(kvp_globals));
error = hv_kvp_dev_init();
mtx_init(&kvp_globals.pending_mutex, "hv-kvp pending mutex",
- NULL, MTX_DEF);
- kvp_globals.pending_reqs = 0;
-
+ NULL, MTX_DEF);
-Finish:
return (error);
}
diff --git a/sys/dev/hyperv/utilities/hv_util.c b/sys/dev/hyperv/utilities/hv_util.c
index dc4b1e2..38054ca 100644
--- a/sys/dev/hyperv/utilities/hv_util.c
+++ b/sys/dev/hyperv/utilities/hv_util.c
@@ -52,6 +52,8 @@ static void hv_heartbeat_cb(void *context);
static void hv_timesync_cb(void *context);
static int hv_timesync_init(hv_vmbus_service *serv);
+static int hv_timesync_uninit(hv_vmbus_service *serv);
+static void hv_set_host_time(void *context, int pending);
/*
* Note: GUID codes below are predefined by the host hypervisor
@@ -73,6 +75,7 @@ hv_vmbus_service service_table[] = {
.enabled = TRUE,
.init = hv_timesync_init,
.callback = hv_timesync_cb,
+ .uninit = hv_timesync_uninit,
},
/* Heartbeat Service */
@@ -111,10 +114,16 @@ struct hv_ictimesync_data {
static int
hv_timesync_init(hv_vmbus_service *serv)
{
+ void *time_msg = malloc(sizeof(time_sync_data), M_DEVBUF, M_WAITOK);
+ TASK_INIT(&serv->task, 1, hv_set_host_time, time_msg);
+ return (0);
+}
- serv->work_queue = hv_work_queue_create("Time Sync");
- if (serv->work_queue == NULL)
- return (ENOMEM);
+static int
+hv_timesync_uninit(hv_vmbus_service *serv)
+{
+ taskqueue_drain(taskqueue_thread, &serv->task);
+ free(serv->task.ta_context, M_DEVBUF);
return (0);
}
@@ -152,9 +161,9 @@ hv_negotiate_version(
* Set host time based on time sync message from host
*/
static void
-hv_set_host_time(void *context)
+hv_set_host_time(void *context, int pending)
{
- time_sync_data* time_msg = (time_sync_data*) context;
+ time_sync_data* time_msg = (time_sync_data*) context;
uint64_t hosttime = time_msg->data;
struct timespec guest_ts, host_ts;
uint64_t host_tns;
@@ -166,7 +175,7 @@ hv_set_host_time(void *context)
host_ts.tv_nsec = (long)(host_tns%HV_NANO_SEC_PER_SEC);
nanotime(&guest_ts);
-
+
diff = (int64_t)host_ts.tv_sec - (int64_t)guest_ts.tv_sec;
/*
@@ -175,12 +184,7 @@ hv_set_host_time(void *context)
if (diff > 5 || diff < -5) {
error = kern_clock_settime(curthread, CLOCK_REALTIME,
&host_ts);
- }
-
- /*
- * Free the hosttime that was allocated in hv_adj_guesttime()
- */
- free(time_msg, M_DEVBUF);
+ }
}
/**
@@ -197,23 +201,13 @@ hv_set_host_time(void *context)
static inline
void hv_adj_guesttime(uint64_t hosttime, uint8_t flags)
{
- time_sync_data* time_msg;
-
- time_msg = malloc(sizeof(time_sync_data), M_DEVBUF, M_NOWAIT);
+ time_sync_data* time_msg = service_table[HV_TIME_SYNCH].task.ta_context;
- if (time_msg == NULL)
- return;
-
time_msg->data = hosttime;
- if ((flags & HV_ICTIMESYNCFLAG_SYNC) != 0) {
- hv_queue_work_item(service_table[HV_TIME_SYNCH].work_queue,
- hv_set_host_time, time_msg);
- } else if ((flags & HV_ICTIMESYNCFLAG_SAMPLE) != 0) {
- hv_queue_work_item(service_table[HV_TIME_SYNCH].work_queue,
- hv_set_host_time, time_msg);
- } else {
- free(time_msg, M_DEVBUF);
+ if (((flags & HV_ICTIMESYNCFLAG_SYNC) != 0) ||
+ ((flags & HV_ICTIMESYNCFLAG_SAMPLE) != 0)) {
+ taskqueue_enqueue(taskqueue_thread, &service_table[HV_TIME_SYNCH].task);
}
}
@@ -452,19 +446,14 @@ hv_util_detach(device_t dev)
service = device_get_softc(dev);
receive_buffer_offset = service - &service_table[0];
- if (service->work_queue != NULL)
- hv_work_queue_close(service->work_queue);
+ if (service->uninit != NULL)
+ service->uninit(service);
free(receive_buffer[receive_buffer_offset], M_DEVBUF);
receive_buffer[receive_buffer_offset] = NULL;
return (0);
}
-static void
-hv_util_init(void)
-{
-}
-
static int
hv_util_modevent(module_t mod, int event, void *arg)
{
@@ -495,6 +484,3 @@ static devclass_t util_devclass;
DRIVER_MODULE(hv_utils, vmbus, util_driver, util_devclass, hv_util_modevent, 0);
MODULE_VERSION(hv_utils, 1);
MODULE_DEPEND(hv_utils, vmbus, 1, 1, 1);
-
-SYSINIT(hv_util_initx, SI_SUB_KTHREAD_IDLE, SI_ORDER_MIDDLE + 1,
- hv_util_init, NULL);
OpenPOWER on IntegriCloud