diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-01-12 23:07:46 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-01-12 23:07:46 +0100 |
commit | 0a87a2db485a1456b7427914969c0e8195a1bbda (patch) | |
tree | 8d0186672af22c6ee76118c471881cd66a36502d /drivers/hv/hv_snapshot.c | |
parent | 7226572d8ed48f7e1aa9de5383d919490d6e9a0c (diff) | |
parent | fcf3aac5fc307f0cae429f5844ddc25761662858 (diff) |
Merge tag 'topic/i915-hda-componentized-2015-01-12' into drm-intel-next-queued
Conflicts:
drivers/gpu/drm/i915/intel_runtime_pm.c
Separate branch so that Takashi can also pull just this refactoring
into sound-next.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'drivers/hv/hv_snapshot.c')
-rw-r--r-- | drivers/hv/hv_snapshot.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c index 34f14fddb666..9d5e0d1efdb5 100644 --- a/drivers/hv/hv_snapshot.c +++ b/drivers/hv/hv_snapshot.c @@ -28,7 +28,7 @@ #define VSS_MINOR 0 #define VSS_VERSION (VSS_MAJOR << 16 | VSS_MINOR) - +#define VSS_USERSPACE_TIMEOUT (msecs_to_jiffies(10 * 1000)) /* * Global state maintained for transaction that is being processed. @@ -55,12 +55,24 @@ static const char vss_name[] = "vss_kernel_module"; static __u8 *recv_buffer; static void vss_send_op(struct work_struct *dummy); +static void vss_timeout_func(struct work_struct *dummy); + +static DECLARE_DELAYED_WORK(vss_timeout_work, vss_timeout_func); static DECLARE_WORK(vss_send_op_work, vss_send_op); /* * Callback when data is received from user mode. */ +static void vss_timeout_func(struct work_struct *dummy) +{ + /* + * Timeout waiting for userspace component to reply happened. + */ + pr_warn("VSS: timeout waiting for daemon to reply\n"); + vss_respond_to_host(HV_E_FAIL); +} + static void vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) { @@ -76,13 +88,15 @@ vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) return; } - vss_respond_to_host(vss_msg->error); + if (cancel_delayed_work_sync(&vss_timeout_work)) + vss_respond_to_host(vss_msg->error); } static void vss_send_op(struct work_struct *dummy) { int op = vss_transaction.msg->vss_hdr.operation; + int rc; struct cn_msg *msg; struct hv_vss_msg *vss_msg; @@ -98,7 +112,12 @@ static void vss_send_op(struct work_struct *dummy) vss_msg->vss_hdr.operation = op; msg->len = sizeof(struct hv_vss_msg); - cn_netlink_send(msg, 0, 0, GFP_ATOMIC); + rc = cn_netlink_send(msg, 0, 0, GFP_ATOMIC); + if (rc) { + pr_warn("VSS: failed to communicate to the daemon: %d\n", rc); + if (cancel_delayed_work_sync(&vss_timeout_work)) + vss_respond_to_host(HV_E_FAIL); + } kfree(msg); return; @@ -223,6 +242,8 @@ void hv_vss_onchannelcallback(void *context) case VSS_OP_FREEZE: case VSS_OP_THAW: schedule_work(&vss_send_op_work); + schedule_delayed_work(&vss_timeout_work, + VSS_USERSPACE_TIMEOUT); return; case VSS_OP_HOT_BACKUP: @@ -277,5 +298,6 @@ hv_vss_init(struct hv_util_service *srv) void hv_vss_deinit(void) { cn_del_callback(&vss_id); + cancel_delayed_work_sync(&vss_timeout_work); cancel_work_sync(&vss_send_op_work); } |