summaryrefslogtreecommitdiffstats
path: root/drivers/staging/hv/hv_util.c
diff options
context:
space:
mode:
authorK. Y. Srinivasan2011-08-27 20:31:31 +0200
committerGreg Kroah-Hartman2011-08-29 20:05:30 +0200
commit95ff7cde91f5513ebc95ccf0cd482f07dc3454e4 (patch)
tree4d549735e883230f008ec2302aac23b7ba100a48 /drivers/staging/hv/hv_util.c
parentStaging: hv: util: Forcefully shutdown when shutdown is requested (diff)
downloadkernel-qcow2-linux-95ff7cde91f5513ebc95ccf0cd482f07dc3454e4.tar.gz
kernel-qcow2-linux-95ff7cde91f5513ebc95ccf0cd482f07dc3454e4.tar.xz
kernel-qcow2-linux-95ff7cde91f5513ebc95ccf0cd482f07dc3454e4.zip
Staging: hv: util: Adjust guest time in a process context
The current code was adjusting guest time in interrupt context; do this in process context since we may have to initiate cross-processor interrupts as part of setting time. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/hv/hv_util.c')
-rw-r--r--drivers/staging/hv/hv_util.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
index 876d44a8a861..e29a2a23eda5 100644
--- a/drivers/staging/hv/hv_util.c
+++ b/drivers/staging/hv/hv_util.c
@@ -107,6 +107,24 @@ static inline void do_adj_guesttime(u64 hosttime)
}
/*
+ * Set the host time in a process context.
+ */
+
+struct adj_time_work {
+ struct work_struct work;
+ u64 host_time;
+};
+
+static void hv_set_host_time(struct work_struct *work)
+{
+ struct adj_time_work *wrk;
+
+ wrk = container_of(work, struct adj_time_work, work);
+ do_adj_guesttime(wrk->host_time);
+ kfree(wrk);
+}
+
+/*
* Synchronize time with host after reboot, restore, etc.
*
* ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM.
@@ -119,17 +137,26 @@ static inline void do_adj_guesttime(u64 hosttime)
*/
static inline void adj_guesttime(u64 hosttime, u8 flags)
{
+ struct adj_time_work *wrk;
static s32 scnt = 50;
+ wrk = kmalloc(sizeof(struct adj_time_work), GFP_ATOMIC);
+ if (wrk == NULL)
+ return;
+
+ wrk->host_time = hosttime;
if ((flags & ICTIMESYNCFLAG_SYNC) != 0) {
- do_adj_guesttime(hosttime);
+ INIT_WORK(&wrk->work, hv_set_host_time);
+ schedule_work(&wrk->work);
return;
}
if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) {
scnt--;
- do_adj_guesttime(hosttime);
- }
+ INIT_WORK(&wrk->work, hv_set_host_time);
+ schedule_work(&wrk->work);
+ } else
+ kfree(wrk);
}
/*