diff options
author | Dexuan Cui <decui@microsoft.com> | 2015-01-14 04:55:10 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-01-25 12:17:58 -0500 |
commit | d9b1652947c695d247b5e4603a16213ec55661ed (patch) | |
tree | d9d5b81e2b05aeadc3eebda0dac8f20859e89097 | |
parent | d61031ee8df6214d58371a1cc36a0591e242fba0 (diff) |
hv: hv_fcopy: drop the obsolete message on transfer failure
In the case the user-space daemon crashes, hangs or is killed, we
need to down the semaphore, otherwise, after the daemon starts next
time, the obsolete data in fcopy_transaction.message or
fcopy_transaction.fcopy_msg will be used immediately.
Cc: Jason Wang <jasowang@redhat.com>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/hv/hv_fcopy.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c index 23b2ce294c4c..cd453e4b2a07 100644 --- a/drivers/hv/hv_fcopy.c +++ b/drivers/hv/hv_fcopy.c | |||
@@ -86,6 +86,18 @@ static void fcopy_work_func(struct work_struct *dummy) | |||
86 | * process the pending transaction. | 86 | * process the pending transaction. |
87 | */ | 87 | */ |
88 | fcopy_respond_to_host(HV_E_FAIL); | 88 | fcopy_respond_to_host(HV_E_FAIL); |
89 | |||
90 | /* In the case the user-space daemon crashes, hangs or is killed, we | ||
91 | * need to down the semaphore, otherwise, after the daemon starts next | ||
92 | * time, the obsolete data in fcopy_transaction.message or | ||
93 | * fcopy_transaction.fcopy_msg will be used immediately. | ||
94 | * | ||
95 | * NOTE: fcopy_read() happens to get the semaphore (very rare)? We're | ||
96 | * still OK, because we've reported the failure to the host. | ||
97 | */ | ||
98 | if (down_trylock(&fcopy_transaction.read_sema)) | ||
99 | ; | ||
100 | |||
89 | } | 101 | } |
90 | 102 | ||
91 | static int fcopy_handle_handshake(u32 version) | 103 | static int fcopy_handle_handshake(u32 version) |
@@ -344,6 +356,14 @@ static int fcopy_open(struct inode *inode, struct file *f) | |||
344 | return 0; | 356 | return 0; |
345 | } | 357 | } |
346 | 358 | ||
359 | /* XXX: there are still some tricky corner cases, e.g., | ||
360 | * 1) In a SMP guest, when fcopy_release() runs between | ||
361 | * schedule_delayed_work() and fcopy_send_data(), there is | ||
362 | * still a chance an obsolete message will be queued. | ||
363 | * | ||
364 | * 2) When the fcopy daemon is running, if we unload the driver, | ||
365 | * we'll notice a kernel oops when we kill the daemon later. | ||
366 | */ | ||
347 | static int fcopy_release(struct inode *inode, struct file *f) | 367 | static int fcopy_release(struct inode *inode, struct file *f) |
348 | { | 368 | { |
349 | /* | 369 | /* |
@@ -351,6 +371,13 @@ static int fcopy_release(struct inode *inode, struct file *f) | |||
351 | */ | 371 | */ |
352 | in_hand_shake = true; | 372 | in_hand_shake = true; |
353 | opened = false; | 373 | opened = false; |
374 | |||
375 | if (cancel_delayed_work_sync(&fcopy_work)) { | ||
376 | /* We haven't up()-ed the semaphore(very rare)? */ | ||
377 | if (down_trylock(&fcopy_transaction.read_sema)) | ||
378 | ; | ||
379 | fcopy_respond_to_host(HV_E_FAIL); | ||
380 | } | ||
354 | return 0; | 381 | return 0; |
355 | } | 382 | } |
356 | 383 | ||