summaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-27 03:13:04 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-27 03:13:04 -0400
commit57c0eabbd57e1a0872122525f6eeefe1f6529c33 (patch)
tree788d036bfbc9c92fb7663588033f50d2d6f5c828 /drivers/hv
parent392910cf3f8a0161d3da45d02ea17f2910d9193b (diff)
parentc02ed2e75ef4c74e41e421acb4ef1494671585e8 (diff)
Merge 4.11-rc4 into char-misc-next
We want the char-misc fixes in here as well. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/channel.c25
-rw-r--r--drivers/hv/channel_mgmt.c27
-rw-r--r--drivers/hv/hv_fcopy.c4
-rw-r--r--drivers/hv/hv_kvp.c4
-rw-r--r--drivers/hv/hv_snapshot.c4
-rw-r--r--drivers/hv/hv_util.c2
-rw-r--r--drivers/hv/hv_utils_transport.c12
-rw-r--r--drivers/hv/hv_utils_transport.h1
-rw-r--r--drivers/hv/vmbus_drv.c6
9 files changed, 33 insertions, 52 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 5c1aa1c09064..736ac76d2a6a 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -502,12 +502,15 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
502 502
503 wait_for_completion(&info->waitevent); 503 wait_for_completion(&info->waitevent);
504 504
505 if (channel->rescind) {
506 ret = -ENODEV;
507 goto post_msg_err;
508 }
509
510post_msg_err: 505post_msg_err:
506 /*
507 * If the channel has been rescinded;
508 * we will be awakened by the rescind
509 * handler; set the error code to zero so we don't leak memory.
510 */
511 if (channel->rescind)
512 ret = 0;
513
511 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); 514 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
512 list_del(&info->msglistentry); 515 list_del(&info->msglistentry);
513 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); 516 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
@@ -530,15 +533,13 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
530 int ret; 533 int ret;
531 534
532 /* 535 /*
533 * vmbus_on_event(), running in the tasklet, can race 536 * vmbus_on_event(), running in the per-channel tasklet, can race
534 * with vmbus_close_internal() in the case of SMP guest, e.g., when 537 * with vmbus_close_internal() in the case of SMP guest, e.g., when
535 * the former is accessing channel->inbound.ring_buffer, the latter 538 * the former is accessing channel->inbound.ring_buffer, the latter
536 * could be freeing the ring_buffer pages. 539 * could be freeing the ring_buffer pages, so here we must stop it
537 * 540 * first.
538 * To resolve the race, we can serialize them by disabling the
539 * tasklet when the latter is running here.
540 */ 541 */
541 hv_event_tasklet_disable(channel); 542 tasklet_disable(&channel->callback_event);
542 543
543 /* 544 /*
544 * In case a device driver's probe() fails (e.g., 545 * In case a device driver's probe() fails (e.g.,
@@ -605,8 +606,6 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
605 get_order(channel->ringbuffer_pagecount * PAGE_SIZE)); 606 get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
606 607
607out: 608out:
608 hv_event_tasklet_enable(channel);
609
610 return ret; 609 return ret;
611} 610}
612 611
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index c1ba440a4987..735f9363f2e4 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -350,7 +350,8 @@ static struct vmbus_channel *alloc_channel(void)
350static void free_channel(struct vmbus_channel *channel) 350static void free_channel(struct vmbus_channel *channel)
351{ 351{
352 tasklet_kill(&channel->callback_event); 352 tasklet_kill(&channel->callback_event);
353 kfree(channel); 353
354 kfree_rcu(channel, rcu);
354} 355}
355 356
356static void percpu_channel_enq(void *arg) 357static void percpu_channel_enq(void *arg)
@@ -359,14 +360,14 @@ static void percpu_channel_enq(void *arg)
359 struct hv_per_cpu_context *hv_cpu 360 struct hv_per_cpu_context *hv_cpu
360 = this_cpu_ptr(hv_context.cpu_context); 361 = this_cpu_ptr(hv_context.cpu_context);
361 362
362 list_add_tail(&channel->percpu_list, &hv_cpu->chan_list); 363 list_add_tail_rcu(&channel->percpu_list, &hv_cpu->chan_list);
363} 364}
364 365
365static void percpu_channel_deq(void *arg) 366static void percpu_channel_deq(void *arg)
366{ 367{
367 struct vmbus_channel *channel = arg; 368 struct vmbus_channel *channel = arg;
368 369
369 list_del(&channel->percpu_list); 370 list_del_rcu(&channel->percpu_list);
370} 371}
371 372
372 373
@@ -381,19 +382,6 @@ static void vmbus_release_relid(u32 relid)
381 true); 382 true);
382} 383}
383 384
384void hv_event_tasklet_disable(struct vmbus_channel *channel)
385{
386 tasklet_disable(&channel->callback_event);
387}
388
389void hv_event_tasklet_enable(struct vmbus_channel *channel)
390{
391 tasklet_enable(&channel->callback_event);
392
393 /* In case there is any pending event */
394 tasklet_schedule(&channel->callback_event);
395}
396
397void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) 385void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
398{ 386{
399 unsigned long flags; 387 unsigned long flags;
@@ -402,7 +390,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
402 BUG_ON(!channel->rescind); 390 BUG_ON(!channel->rescind);
403 BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex)); 391 BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex));
404 392
405 hv_event_tasklet_disable(channel);
406 if (channel->target_cpu != get_cpu()) { 393 if (channel->target_cpu != get_cpu()) {
407 put_cpu(); 394 put_cpu();
408 smp_call_function_single(channel->target_cpu, 395 smp_call_function_single(channel->target_cpu,
@@ -411,7 +398,6 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
411 percpu_channel_deq(channel); 398 percpu_channel_deq(channel);
412 put_cpu(); 399 put_cpu();
413 } 400 }
414 hv_event_tasklet_enable(channel);
415 401
416 if (channel->primary_channel == NULL) { 402 if (channel->primary_channel == NULL) {
417 list_del(&channel->listentry); 403 list_del(&channel->listentry);
@@ -505,7 +491,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
505 491
506 init_vp_index(newchannel, dev_type); 492 init_vp_index(newchannel, dev_type);
507 493
508 hv_event_tasklet_disable(newchannel);
509 if (newchannel->target_cpu != get_cpu()) { 494 if (newchannel->target_cpu != get_cpu()) {
510 put_cpu(); 495 put_cpu();
511 smp_call_function_single(newchannel->target_cpu, 496 smp_call_function_single(newchannel->target_cpu,
@@ -515,7 +500,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
515 percpu_channel_enq(newchannel); 500 percpu_channel_enq(newchannel);
516 put_cpu(); 501 put_cpu();
517 } 502 }
518 hv_event_tasklet_enable(newchannel);
519 503
520 /* 504 /*
521 * This state is used to indicate a successful open 505 * This state is used to indicate a successful open
@@ -565,7 +549,6 @@ err_deq_chan:
565 list_del(&newchannel->listentry); 549 list_del(&newchannel->listentry);
566 mutex_unlock(&vmbus_connection.channel_mutex); 550 mutex_unlock(&vmbus_connection.channel_mutex);
567 551
568 hv_event_tasklet_disable(newchannel);
569 if (newchannel->target_cpu != get_cpu()) { 552 if (newchannel->target_cpu != get_cpu()) {
570 put_cpu(); 553 put_cpu();
571 smp_call_function_single(newchannel->target_cpu, 554 smp_call_function_single(newchannel->target_cpu,
@@ -574,7 +557,6 @@ err_deq_chan:
574 percpu_channel_deq(newchannel); 557 percpu_channel_deq(newchannel);
575 put_cpu(); 558 put_cpu();
576 } 559 }
577 hv_event_tasklet_enable(newchannel);
578 560
579 vmbus_release_relid(newchannel->offermsg.child_relid); 561 vmbus_release_relid(newchannel->offermsg.child_relid);
580 562
@@ -814,6 +796,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
814 /* Allocate the channel object and save this offer. */ 796 /* Allocate the channel object and save this offer. */
815 newchannel = alloc_channel(); 797 newchannel = alloc_channel();
816 if (!newchannel) { 798 if (!newchannel) {
799 vmbus_release_relid(offer->child_relid);
817 pr_err("Unable to allocate channel object\n"); 800 pr_err("Unable to allocate channel object\n");
818 return; 801 return;
819 } 802 }
diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c
index 3ce7559d7b41..daa75bd41f86 100644
--- a/drivers/hv/hv_fcopy.c
+++ b/drivers/hv/hv_fcopy.c
@@ -71,7 +71,6 @@ static DECLARE_WORK(fcopy_send_work, fcopy_send_data);
71static const char fcopy_devname[] = "vmbus/hv_fcopy"; 71static const char fcopy_devname[] = "vmbus/hv_fcopy";
72static u8 *recv_buffer; 72static u8 *recv_buffer;
73static struct hvutil_transport *hvt; 73static struct hvutil_transport *hvt;
74static struct completion release_event;
75/* 74/*
76 * This state maintains the version number registered by the daemon. 75 * This state maintains the version number registered by the daemon.
77 */ 76 */
@@ -329,7 +328,6 @@ static void fcopy_on_reset(void)
329 328
330 if (cancel_delayed_work_sync(&fcopy_timeout_work)) 329 if (cancel_delayed_work_sync(&fcopy_timeout_work))
331 fcopy_respond_to_host(HV_E_FAIL); 330 fcopy_respond_to_host(HV_E_FAIL);
332 complete(&release_event);
333} 331}
334 332
335int hv_fcopy_init(struct hv_util_service *srv) 333int hv_fcopy_init(struct hv_util_service *srv)
@@ -337,7 +335,6 @@ int hv_fcopy_init(struct hv_util_service *srv)
337 recv_buffer = srv->recv_buffer; 335 recv_buffer = srv->recv_buffer;
338 fcopy_transaction.recv_channel = srv->channel; 336 fcopy_transaction.recv_channel = srv->channel;
339 337
340 init_completion(&release_event);
341 /* 338 /*
342 * When this driver loads, the user level daemon that 339 * When this driver loads, the user level daemon that
343 * processes the host requests may not yet be running. 340 * processes the host requests may not yet be running.
@@ -359,5 +356,4 @@ void hv_fcopy_deinit(void)
359 fcopy_transaction.state = HVUTIL_DEVICE_DYING; 356 fcopy_transaction.state = HVUTIL_DEVICE_DYING;
360 cancel_delayed_work_sync(&fcopy_timeout_work); 357 cancel_delayed_work_sync(&fcopy_timeout_work);
361 hvutil_transport_destroy(hvt); 358 hvutil_transport_destroy(hvt);
362 wait_for_completion(&release_event);
363} 359}
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index b0a36e8a7268..e99ff2ddad40 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -101,7 +101,6 @@ static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
101static const char kvp_devname[] = "vmbus/hv_kvp"; 101static const char kvp_devname[] = "vmbus/hv_kvp";
102static u8 *recv_buffer; 102static u8 *recv_buffer;
103static struct hvutil_transport *hvt; 103static struct hvutil_transport *hvt;
104static struct completion release_event;
105/* 104/*
106 * Register the kernel component with the user-level daemon. 105 * Register the kernel component with the user-level daemon.
107 * As part of this registration, pass the LIC version number. 106 * As part of this registration, pass the LIC version number.
@@ -712,7 +711,6 @@ static void kvp_on_reset(void)
712 if (cancel_delayed_work_sync(&kvp_timeout_work)) 711 if (cancel_delayed_work_sync(&kvp_timeout_work))
713 kvp_respond_to_host(NULL, HV_E_FAIL); 712 kvp_respond_to_host(NULL, HV_E_FAIL);
714 kvp_transaction.state = HVUTIL_DEVICE_INIT; 713 kvp_transaction.state = HVUTIL_DEVICE_INIT;
715 complete(&release_event);
716} 714}
717 715
718int 716int
@@ -721,7 +719,6 @@ hv_kvp_init(struct hv_util_service *srv)
721 recv_buffer = srv->recv_buffer; 719 recv_buffer = srv->recv_buffer;
722 kvp_transaction.recv_channel = srv->channel; 720 kvp_transaction.recv_channel = srv->channel;
723 721
724 init_completion(&release_event);
725 /* 722 /*
726 * When this driver loads, the user level daemon that 723 * When this driver loads, the user level daemon that
727 * processes the host requests may not yet be running. 724 * processes the host requests may not yet be running.
@@ -745,5 +742,4 @@ void hv_kvp_deinit(void)
745 cancel_delayed_work_sync(&kvp_timeout_work); 742 cancel_delayed_work_sync(&kvp_timeout_work);
746 cancel_work_sync(&kvp_sendkey_work); 743 cancel_work_sync(&kvp_sendkey_work);
747 hvutil_transport_destroy(hvt); 744 hvutil_transport_destroy(hvt);
748 wait_for_completion(&release_event);
749} 745}
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
index 216d02277759..6831efd73394 100644
--- a/drivers/hv/hv_snapshot.c
+++ b/drivers/hv/hv_snapshot.c
@@ -79,7 +79,6 @@ static int dm_reg_value;
79static const char vss_devname[] = "vmbus/hv_vss"; 79static const char vss_devname[] = "vmbus/hv_vss";
80static __u8 *recv_buffer; 80static __u8 *recv_buffer;
81static struct hvutil_transport *hvt; 81static struct hvutil_transport *hvt;
82static struct completion release_event;
83 82
84static void vss_timeout_func(struct work_struct *dummy); 83static void vss_timeout_func(struct work_struct *dummy);
85static void vss_handle_request(struct work_struct *dummy); 84static void vss_handle_request(struct work_struct *dummy);
@@ -359,13 +358,11 @@ static void vss_on_reset(void)
359 if (cancel_delayed_work_sync(&vss_timeout_work)) 358 if (cancel_delayed_work_sync(&vss_timeout_work))
360 vss_respond_to_host(HV_E_FAIL); 359 vss_respond_to_host(HV_E_FAIL);
361 vss_transaction.state = HVUTIL_DEVICE_INIT; 360 vss_transaction.state = HVUTIL_DEVICE_INIT;
362 complete(&release_event);
363} 361}
364 362
365int 363int
366hv_vss_init(struct hv_util_service *srv) 364hv_vss_init(struct hv_util_service *srv)
367{ 365{
368 init_completion(&release_event);
369 if (vmbus_proto_version < VERSION_WIN8_1) { 366 if (vmbus_proto_version < VERSION_WIN8_1) {
370 pr_warn("Integration service 'Backup (volume snapshot)'" 367 pr_warn("Integration service 'Backup (volume snapshot)'"
371 " not supported on this host version.\n"); 368 " not supported on this host version.\n");
@@ -398,5 +395,4 @@ void hv_vss_deinit(void)
398 cancel_delayed_work_sync(&vss_timeout_work); 395 cancel_delayed_work_sync(&vss_timeout_work);
399 cancel_work_sync(&vss_handle_request_work); 396 cancel_work_sync(&vss_handle_request_work);
400 hvutil_transport_destroy(hvt); 397 hvutil_transport_destroy(hvt);
401 wait_for_completion(&release_event);
402} 398}
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index 3042eaa13062..186b10083c55 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -590,6 +590,8 @@ static int hv_timesync_init(struct hv_util_service *srv)
590 if (!hyperv_cs) 590 if (!hyperv_cs)
591 return -ENODEV; 591 return -ENODEV;
592 592
593 spin_lock_init(&host_ts.lock);
594
593 INIT_WORK(&wrk.work, hv_set_host_time); 595 INIT_WORK(&wrk.work, hv_set_host_time);
594 596
595 /* 597 /*
diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c
index c235a9515267..4402a71e23f7 100644
--- a/drivers/hv/hv_utils_transport.c
+++ b/drivers/hv/hv_utils_transport.c
@@ -182,10 +182,11 @@ static int hvt_op_release(struct inode *inode, struct file *file)
182 * connects back. 182 * connects back.
183 */ 183 */
184 hvt_reset(hvt); 184 hvt_reset(hvt);
185 mutex_unlock(&hvt->lock);
186 185
187 if (mode_old == HVUTIL_TRANSPORT_DESTROY) 186 if (mode_old == HVUTIL_TRANSPORT_DESTROY)
188 hvt_transport_free(hvt); 187 complete(&hvt->release);
188
189 mutex_unlock(&hvt->lock);
189 190
190 return 0; 191 return 0;
191} 192}
@@ -304,6 +305,7 @@ struct hvutil_transport *hvutil_transport_init(const char *name,
304 305
305 init_waitqueue_head(&hvt->outmsg_q); 306 init_waitqueue_head(&hvt->outmsg_q);
306 mutex_init(&hvt->lock); 307 mutex_init(&hvt->lock);
308 init_completion(&hvt->release);
307 309
308 spin_lock(&hvt_list_lock); 310 spin_lock(&hvt_list_lock);
309 list_add(&hvt->list, &hvt_list); 311 list_add(&hvt->list, &hvt_list);
@@ -351,6 +353,8 @@ void hvutil_transport_destroy(struct hvutil_transport *hvt)
351 if (hvt->cn_id.idx > 0 && hvt->cn_id.val > 0) 353 if (hvt->cn_id.idx > 0 && hvt->cn_id.val > 0)
352 cn_del_callback(&hvt->cn_id); 354 cn_del_callback(&hvt->cn_id);
353 355
354 if (mode_old != HVUTIL_TRANSPORT_CHARDEV) 356 if (mode_old == HVUTIL_TRANSPORT_CHARDEV)
355 hvt_transport_free(hvt); 357 wait_for_completion(&hvt->release);
358
359 hvt_transport_free(hvt);
356} 360}
diff --git a/drivers/hv/hv_utils_transport.h b/drivers/hv/hv_utils_transport.h
index d98f5225c3e6..79afb626e166 100644
--- a/drivers/hv/hv_utils_transport.h
+++ b/drivers/hv/hv_utils_transport.h
@@ -41,6 +41,7 @@ struct hvutil_transport {
41 int outmsg_len; /* its length */ 41 int outmsg_len; /* its length */
42 wait_queue_head_t outmsg_q; /* poll/read wait queue */ 42 wait_queue_head_t outmsg_q; /* poll/read wait queue */
43 struct mutex lock; /* protects struct members */ 43 struct mutex lock; /* protects struct members */
44 struct completion release; /* synchronize with fd release */
44}; 45};
45 46
46struct hvutil_transport *hvutil_transport_init(const char *name, 47struct hvutil_transport *hvutil_transport_init(const char *name,
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 8b272d389ce5..0087b49095eb 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -937,8 +937,10 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu)
937 if (relid == 0) 937 if (relid == 0)
938 continue; 938 continue;
939 939
940 rcu_read_lock();
941
940 /* Find channel based on relid */ 942 /* Find channel based on relid */
941 list_for_each_entry(channel, &hv_cpu->chan_list, percpu_list) { 943 list_for_each_entry_rcu(channel, &hv_cpu->chan_list, percpu_list) {
942 if (channel->offermsg.child_relid != relid) 944 if (channel->offermsg.child_relid != relid)
943 continue; 945 continue;
944 946
@@ -954,6 +956,8 @@ static void vmbus_chan_sched(struct hv_per_cpu_context *hv_cpu)
954 tasklet_schedule(&channel->callback_event); 956 tasklet_schedule(&channel->callback_event);
955 } 957 }
956 } 958 }
959
960 rcu_read_unlock();
957 } 961 }
958} 962}
959 963