Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / drivers / hv / channel_mgmt.c
1 /*
2  * Copyright (c) 2009, Microsoft Corporation.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15  * Place - Suite 330, Boston, MA 02111-1307 USA.
16  *
17  * Authors:
18  *   Haiyang Zhang <haiyangz@microsoft.com>
19  *   Hank Janssen  <hjanssen@microsoft.com>
20  */
21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23 #include <linux/kernel.h>
24 #include <linux/sched.h>
25 #include <linux/wait.h>
26 #include <linux/mm.h>
27 #include <linux/slab.h>
28 #include <linux/list.h>
29 #include <linux/module.h>
30 #include <linux/completion.h>
31 #include <linux/hyperv.h>
32
33 #include "hyperv_vmbus.h"
34
35 struct vmbus_channel_message_table_entry {
36         enum vmbus_channel_message_type message_type;
37         void (*message_handler)(struct vmbus_channel_message_header *msg);
38 };
39
40
41 /**
42  * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
43  * @icmsghdrp: Pointer to msg header structure
44  * @icmsg_negotiate: Pointer to negotiate message structure
45  * @buf: Raw buffer channel data
46  *
47  * @icmsghdrp is of type &struct icmsg_hdr.
48  * @negop is of type &struct icmsg_negotiate.
49  * Set up and fill in default negotiate response message.
50  *
51  * The max_fw_version specifies the maximum framework version that
52  * we can support and max _srv_version specifies the maximum service
53  * version we can support. A special value MAX_SRV_VER can be
54  * specified to indicate that we can handle the maximum version
55  * exposed by the host.
56  *
57  * Mainly used by Hyper-V drivers.
58  */
59 void vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
60                                 struct icmsg_negotiate *negop, u8 *buf,
61                                 int max_fw_version, int max_srv_version)
62 {
63         int icframe_vercnt;
64         int icmsg_vercnt;
65         int i;
66
67         icmsghdrp->icmsgsize = 0x10;
68
69         negop = (struct icmsg_negotiate *)&buf[
70                 sizeof(struct vmbuspipe_hdr) +
71                 sizeof(struct icmsg_hdr)];
72
73         icframe_vercnt = negop->icframe_vercnt;
74         icmsg_vercnt = negop->icmsg_vercnt;
75
76         /*
77          * Select the framework version number we will
78          * support.
79          */
80
81         for (i = 0; i < negop->icframe_vercnt; i++) {
82                 if (negop->icversion_data[i].major <= max_fw_version)
83                         icframe_vercnt = negop->icversion_data[i].major;
84         }
85
86         for (i = negop->icframe_vercnt;
87                  (i < negop->icframe_vercnt + negop->icmsg_vercnt); i++) {
88                 if (negop->icversion_data[i].major <= max_srv_version)
89                         icmsg_vercnt = negop->icversion_data[i].major;
90         }
91
92         /*
93          * Respond with the maximum framework and service
94          * version numbers we can support.
95          */
96         negop->icframe_vercnt = 1;
97         negop->icmsg_vercnt = 1;
98         negop->icversion_data[0].major = icframe_vercnt;
99         negop->icversion_data[0].minor = 0;
100         negop->icversion_data[1].major = icmsg_vercnt;
101         negop->icversion_data[1].minor = 0;
102 }
103
104 EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp);
105
106 /*
107  * alloc_channel - Allocate and initialize a vmbus channel object
108  */
109 static struct vmbus_channel *alloc_channel(void)
110 {
111         struct vmbus_channel *channel;
112
113         channel = kzalloc(sizeof(*channel), GFP_ATOMIC);
114         if (!channel)
115                 return NULL;
116
117         spin_lock_init(&channel->inbound_lock);
118         spin_lock_init(&channel->sc_lock);
119
120         INIT_LIST_HEAD(&channel->sc_list);
121
122         channel->controlwq = create_workqueue("hv_vmbus_ctl");
123         if (!channel->controlwq) {
124                 kfree(channel);
125                 return NULL;
126         }
127
128         return channel;
129 }
130
131 /*
132  * release_hannel - Release the vmbus channel object itself
133  */
134 static void release_channel(struct work_struct *work)
135 {
136         struct vmbus_channel *channel = container_of(work,
137                                                      struct vmbus_channel,
138                                                      work);
139
140         destroy_workqueue(channel->controlwq);
141
142         kfree(channel);
143 }
144
145 /*
146  * free_channel - Release the resources used by the vmbus channel object
147  */
148 static void free_channel(struct vmbus_channel *channel)
149 {
150
151         /*
152          * We have to release the channel's workqueue/thread in the vmbus's
153          * workqueue/thread context
154          * ie we can't destroy ourselves.
155          */
156         INIT_WORK(&channel->work, release_channel);
157         queue_work(vmbus_connection.work_queue, &channel->work);
158 }
159
160
161
162 /*
163  * vmbus_process_rescind_offer -
164  * Rescind the offer by initiating a device removal
165  */
166 static void vmbus_process_rescind_offer(struct work_struct *work)
167 {
168         struct vmbus_channel *channel = container_of(work,
169                                                      struct vmbus_channel,
170                                                      work);
171         unsigned long flags;
172         struct vmbus_channel *primary_channel;
173         struct vmbus_channel_relid_released msg;
174
175         vmbus_device_unregister(channel->device_obj);
176         memset(&msg, 0, sizeof(struct vmbus_channel_relid_released));
177         msg.child_relid = channel->offermsg.child_relid;
178         msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
179         vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released));
180
181         if (channel->primary_channel == NULL) {
182                 spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
183                 list_del(&channel->listentry);
184                 spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
185         } else {
186                 primary_channel = channel->primary_channel;
187                 spin_lock_irqsave(&primary_channel->sc_lock, flags);
188                 list_del(&channel->listentry);
189                 spin_unlock_irqrestore(&primary_channel->sc_lock, flags);
190         }
191         free_channel(channel);
192 }
193
194 void vmbus_free_channels(void)
195 {
196         struct vmbus_channel *channel;
197
198         list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
199                 vmbus_device_unregister(channel->device_obj);
200                 kfree(channel->device_obj);
201                 free_channel(channel);
202         }
203 }
204
205 /*
206  * vmbus_process_offer - Process the offer by creating a channel/device
207  * associated with this offer
208  */
209 static void vmbus_process_offer(struct work_struct *work)
210 {
211         struct vmbus_channel *newchannel = container_of(work,
212                                                         struct vmbus_channel,
213                                                         work);
214         struct vmbus_channel *channel;
215         bool fnew = true;
216         int ret;
217         unsigned long flags;
218
219         /* The next possible work is rescind handling */
220         INIT_WORK(&newchannel->work, vmbus_process_rescind_offer);
221
222         /* Make sure this is a new offer */
223         spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
224
225         list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
226                 if (!uuid_le_cmp(channel->offermsg.offer.if_type,
227                         newchannel->offermsg.offer.if_type) &&
228                         !uuid_le_cmp(channel->offermsg.offer.if_instance,
229                                 newchannel->offermsg.offer.if_instance)) {
230                         fnew = false;
231                         break;
232                 }
233         }
234
235         if (fnew)
236                 list_add_tail(&newchannel->listentry,
237                               &vmbus_connection.chn_list);
238
239         spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
240
241         if (!fnew) {
242                 /*
243                  * Check to see if this is a sub-channel.
244                  */
245                 if (newchannel->offermsg.offer.sub_channel_index != 0) {
246                         /*
247                          * Process the sub-channel.
248                          */
249                         newchannel->primary_channel = channel;
250                         spin_lock_irqsave(&channel->sc_lock, flags);
251                         list_add_tail(&newchannel->sc_list, &channel->sc_list);
252                         spin_unlock_irqrestore(&channel->sc_lock, flags);
253                         newchannel->state = CHANNEL_OPEN_STATE;
254                         if (channel->sc_creation_callback != NULL)
255                                 channel->sc_creation_callback(newchannel);
256
257                         return;
258                 }
259
260                 free_channel(newchannel);
261                 return;
262         }
263
264         /*
265          * Start the process of binding this offer to the driver
266          * We need to set the DeviceObject field before calling
267          * vmbus_child_dev_add()
268          */
269         newchannel->device_obj = vmbus_device_create(
270                 &newchannel->offermsg.offer.if_type,
271                 &newchannel->offermsg.offer.if_instance,
272                 newchannel);
273
274         /*
275          * Add the new device to the bus. This will kick off device-driver
276          * binding which eventually invokes the device driver's AddDevice()
277          * method.
278          */
279         ret = vmbus_device_register(newchannel->device_obj);
280         if (ret != 0) {
281                 pr_err("unable to add child device object (relid %d)\n",
282                            newchannel->offermsg.child_relid);
283
284                 spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
285                 list_del(&newchannel->listentry);
286                 spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
287                 kfree(newchannel->device_obj);
288
289                 free_channel(newchannel);
290         } else {
291                 /*
292                  * This state is used to indicate a successful open
293                  * so that when we do close the channel normally, we
294                  * can cleanup properly
295                  */
296                 newchannel->state = CHANNEL_OPEN_STATE;
297         }
298 }
299
300 enum {
301         IDE = 0,
302         SCSI,
303         NIC,
304         MAX_PERF_CHN,
305 };
306
307 /*
308  * This is an array of device_ids (device types) that are performance critical.
309  * We attempt to distribute the interrupt load for these devices across
310  * all available CPUs.
311  */
312 static const struct hv_vmbus_device_id hp_devs[] = {
313         /* IDE */
314         { HV_IDE_GUID, },
315         /* Storage - SCSI */
316         { HV_SCSI_GUID, },
317         /* Network */
318         { HV_NIC_GUID, },
319 };
320
321
322 /*
323  * We use this state to statically distribute the channel interrupt load.
324  */
325 static u32  next_vp;
326
327 /*
328  * Starting with Win8, we can statically distribute the incoming
329  * channel interrupt load by binding a channel to VCPU. We
330  * implement here a simple round robin scheme for distributing
331  * the interrupt load.
332  * We will bind channels that are not performance critical to cpu 0 and
333  * performance critical channels (IDE, SCSI and Network) will be uniformly
334  * distributed across all available CPUs.
335  */
336 static u32 get_vp_index(uuid_le *type_guid)
337 {
338         u32 cur_cpu;
339         int i;
340         bool perf_chn = false;
341         u32 max_cpus = num_online_cpus();
342
343         for (i = IDE; i < MAX_PERF_CHN; i++) {
344                 if (!memcmp(type_guid->b, hp_devs[i].guid,
345                                  sizeof(uuid_le))) {
346                         perf_chn = true;
347                         break;
348                 }
349         }
350         if ((vmbus_proto_version == VERSION_WS2008) ||
351             (vmbus_proto_version == VERSION_WIN7) || (!perf_chn)) {
352                 /*
353                  * Prior to win8, all channel interrupts are
354                  * delivered on cpu 0.
355                  * Also if the channel is not a performance critical
356                  * channel, bind it to cpu 0.
357                  */
358                 return 0;
359         }
360         cur_cpu = (++next_vp % max_cpus);
361         return hv_context.vp_index[cur_cpu];
362 }
363
364 /*
365  * vmbus_onoffer - Handler for channel offers from vmbus in parent partition.
366  *
367  */
368 static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
369 {
370         struct vmbus_channel_offer_channel *offer;
371         struct vmbus_channel *newchannel;
372
373         offer = (struct vmbus_channel_offer_channel *)hdr;
374
375         /* Allocate the channel object and save this offer. */
376         newchannel = alloc_channel();
377         if (!newchannel) {
378                 pr_err("Unable to allocate channel object\n");
379                 return;
380         }
381
382         /*
383          * By default we setup state to enable batched
384          * reading. A specific service can choose to
385          * disable this prior to opening the channel.
386          */
387         newchannel->batched_reading = true;
388
389         /*
390          * Setup state for signalling the host.
391          */
392         newchannel->sig_event = (struct hv_input_signal_event *)
393                                 (ALIGN((unsigned long)
394                                 &newchannel->sig_buf,
395                                 HV_HYPERCALL_PARAM_ALIGN));
396
397         newchannel->sig_event->connectionid.asu32 = 0;
398         newchannel->sig_event->connectionid.u.id = VMBUS_EVENT_CONNECTION_ID;
399         newchannel->sig_event->flag_number = 0;
400         newchannel->sig_event->rsvdz = 0;
401
402         if (vmbus_proto_version != VERSION_WS2008) {
403                 newchannel->is_dedicated_interrupt =
404                                 (offer->is_dedicated_interrupt != 0);
405                 newchannel->sig_event->connectionid.u.id =
406                                 offer->connection_id;
407         }
408
409         newchannel->target_vp = get_vp_index(&offer->offer.if_type);
410
411         memcpy(&newchannel->offermsg, offer,
412                sizeof(struct vmbus_channel_offer_channel));
413         newchannel->monitor_grp = (u8)offer->monitorid / 32;
414         newchannel->monitor_bit = (u8)offer->monitorid % 32;
415
416         INIT_WORK(&newchannel->work, vmbus_process_offer);
417         queue_work(newchannel->controlwq, &newchannel->work);
418 }
419
420 /*
421  * vmbus_onoffer_rescind - Rescind offer handler.
422  *
423  * We queue a work item to process this offer synchronously
424  */
425 static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
426 {
427         struct vmbus_channel_rescind_offer *rescind;
428         struct vmbus_channel *channel;
429
430         rescind = (struct vmbus_channel_rescind_offer *)hdr;
431         channel = relid2channel(rescind->child_relid);
432
433         if (channel == NULL)
434                 /* Just return here, no channel found */
435                 return;
436
437         /* work is initialized for vmbus_process_rescind_offer() from
438          * vmbus_process_offer() where the channel got created */
439         queue_work(channel->controlwq, &channel->work);
440 }
441
442 /*
443  * vmbus_onoffers_delivered -
444  * This is invoked when all offers have been delivered.
445  *
446  * Nothing to do here.
447  */
448 static void vmbus_onoffers_delivered(
449                         struct vmbus_channel_message_header *hdr)
450 {
451 }
452
453 /*
454  * vmbus_onopen_result - Open result handler.
455  *
456  * This is invoked when we received a response to our channel open request.
457  * Find the matching request, copy the response and signal the requesting
458  * thread.
459  */
460 static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr)
461 {
462         struct vmbus_channel_open_result *result;
463         struct vmbus_channel_msginfo *msginfo;
464         struct vmbus_channel_message_header *requestheader;
465         struct vmbus_channel_open_channel *openmsg;
466         unsigned long flags;
467
468         result = (struct vmbus_channel_open_result *)hdr;
469
470         /*
471          * Find the open msg, copy the result and signal/unblock the wait event
472          */
473         spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
474
475         list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
476                                 msglistentry) {
477                 requestheader =
478                         (struct vmbus_channel_message_header *)msginfo->msg;
479
480                 if (requestheader->msgtype == CHANNELMSG_OPENCHANNEL) {
481                         openmsg =
482                         (struct vmbus_channel_open_channel *)msginfo->msg;
483                         if (openmsg->child_relid == result->child_relid &&
484                             openmsg->openid == result->openid) {
485                                 memcpy(&msginfo->response.open_result,
486                                        result,
487                                        sizeof(
488                                         struct vmbus_channel_open_result));
489                                 complete(&msginfo->waitevent);
490                                 break;
491                         }
492                 }
493         }
494         spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
495 }
496
497 /*
498  * vmbus_ongpadl_created - GPADL created handler.
499  *
500  * This is invoked when we received a response to our gpadl create request.
501  * Find the matching request, copy the response and signal the requesting
502  * thread.
503  */
504 static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr)
505 {
506         struct vmbus_channel_gpadl_created *gpadlcreated;
507         struct vmbus_channel_msginfo *msginfo;
508         struct vmbus_channel_message_header *requestheader;
509         struct vmbus_channel_gpadl_header *gpadlheader;
510         unsigned long flags;
511
512         gpadlcreated = (struct vmbus_channel_gpadl_created *)hdr;
513
514         /*
515          * Find the establish msg, copy the result and signal/unblock the wait
516          * event
517          */
518         spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
519
520         list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
521                                 msglistentry) {
522                 requestheader =
523                         (struct vmbus_channel_message_header *)msginfo->msg;
524
525                 if (requestheader->msgtype == CHANNELMSG_GPADL_HEADER) {
526                         gpadlheader =
527                         (struct vmbus_channel_gpadl_header *)requestheader;
528
529                         if ((gpadlcreated->child_relid ==
530                              gpadlheader->child_relid) &&
531                             (gpadlcreated->gpadl == gpadlheader->gpadl)) {
532                                 memcpy(&msginfo->response.gpadl_created,
533                                        gpadlcreated,
534                                        sizeof(
535                                         struct vmbus_channel_gpadl_created));
536                                 complete(&msginfo->waitevent);
537                                 break;
538                         }
539                 }
540         }
541         spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
542 }
543
544 /*
545  * vmbus_ongpadl_torndown - GPADL torndown handler.
546  *
547  * This is invoked when we received a response to our gpadl teardown request.
548  * Find the matching request, copy the response and signal the requesting
549  * thread.
550  */
551 static void vmbus_ongpadl_torndown(
552                         struct vmbus_channel_message_header *hdr)
553 {
554         struct vmbus_channel_gpadl_torndown *gpadl_torndown;
555         struct vmbus_channel_msginfo *msginfo;
556         struct vmbus_channel_message_header *requestheader;
557         struct vmbus_channel_gpadl_teardown *gpadl_teardown;
558         unsigned long flags;
559
560         gpadl_torndown = (struct vmbus_channel_gpadl_torndown *)hdr;
561
562         /*
563          * Find the open msg, copy the result and signal/unblock the wait event
564          */
565         spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
566
567         list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
568                                 msglistentry) {
569                 requestheader =
570                         (struct vmbus_channel_message_header *)msginfo->msg;
571
572                 if (requestheader->msgtype == CHANNELMSG_GPADL_TEARDOWN) {
573                         gpadl_teardown =
574                         (struct vmbus_channel_gpadl_teardown *)requestheader;
575
576                         if (gpadl_torndown->gpadl == gpadl_teardown->gpadl) {
577                                 memcpy(&msginfo->response.gpadl_torndown,
578                                        gpadl_torndown,
579                                        sizeof(
580                                         struct vmbus_channel_gpadl_torndown));
581                                 complete(&msginfo->waitevent);
582                                 break;
583                         }
584                 }
585         }
586         spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
587 }
588
589 /*
590  * vmbus_onversion_response - Version response handler
591  *
592  * This is invoked when we received a response to our initiate contact request.
593  * Find the matching request, copy the response and signal the requesting
594  * thread.
595  */
596 static void vmbus_onversion_response(
597                 struct vmbus_channel_message_header *hdr)
598 {
599         struct vmbus_channel_msginfo *msginfo;
600         struct vmbus_channel_message_header *requestheader;
601         struct vmbus_channel_version_response *version_response;
602         unsigned long flags;
603
604         version_response = (struct vmbus_channel_version_response *)hdr;
605         spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
606
607         list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
608                                 msglistentry) {
609                 requestheader =
610                         (struct vmbus_channel_message_header *)msginfo->msg;
611
612                 if (requestheader->msgtype ==
613                     CHANNELMSG_INITIATE_CONTACT) {
614                         memcpy(&msginfo->response.version_response,
615                               version_response,
616                               sizeof(struct vmbus_channel_version_response));
617                         complete(&msginfo->waitevent);
618                 }
619         }
620         spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
621 }
622
623 /* Channel message dispatch table */
624 static struct vmbus_channel_message_table_entry
625         channel_message_table[CHANNELMSG_COUNT] = {
626         {CHANNELMSG_INVALID,                    NULL},
627         {CHANNELMSG_OFFERCHANNEL,               vmbus_onoffer},
628         {CHANNELMSG_RESCIND_CHANNELOFFER,       vmbus_onoffer_rescind},
629         {CHANNELMSG_REQUESTOFFERS,              NULL},
630         {CHANNELMSG_ALLOFFERS_DELIVERED,        vmbus_onoffers_delivered},
631         {CHANNELMSG_OPENCHANNEL,                NULL},
632         {CHANNELMSG_OPENCHANNEL_RESULT, vmbus_onopen_result},
633         {CHANNELMSG_CLOSECHANNEL,               NULL},
634         {CHANNELMSG_GPADL_HEADER,               NULL},
635         {CHANNELMSG_GPADL_BODY,         NULL},
636         {CHANNELMSG_GPADL_CREATED,              vmbus_ongpadl_created},
637         {CHANNELMSG_GPADL_TEARDOWN,             NULL},
638         {CHANNELMSG_GPADL_TORNDOWN,             vmbus_ongpadl_torndown},
639         {CHANNELMSG_RELID_RELEASED,             NULL},
640         {CHANNELMSG_INITIATE_CONTACT,           NULL},
641         {CHANNELMSG_VERSION_RESPONSE,           vmbus_onversion_response},
642         {CHANNELMSG_UNLOAD,                     NULL},
643 };
644
645 /*
646  * vmbus_onmessage - Handler for channel protocol messages.
647  *
648  * This is invoked in the vmbus worker thread context.
649  */
650 void vmbus_onmessage(void *context)
651 {
652         struct hv_message *msg = context;
653         struct vmbus_channel_message_header *hdr;
654         int size;
655
656         hdr = (struct vmbus_channel_message_header *)msg->u.payload;
657         size = msg->header.payload_size;
658
659         if (hdr->msgtype >= CHANNELMSG_COUNT) {
660                 pr_err("Received invalid channel message type %d size %d\n",
661                            hdr->msgtype, size);
662                 print_hex_dump_bytes("", DUMP_PREFIX_NONE,
663                                      (unsigned char *)msg->u.payload, size);
664                 return;
665         }
666
667         if (channel_message_table[hdr->msgtype].message_handler)
668                 channel_message_table[hdr->msgtype].message_handler(hdr);
669         else
670                 pr_err("Unhandled channel message type %d\n", hdr->msgtype);
671 }
672
673 /*
674  * vmbus_request_offers - Send a request to get all our pending offers.
675  */
676 int vmbus_request_offers(void)
677 {
678         struct vmbus_channel_message_header *msg;
679         struct vmbus_channel_msginfo *msginfo;
680         int ret, t;
681
682         msginfo = kmalloc(sizeof(*msginfo) +
683                           sizeof(struct vmbus_channel_message_header),
684                           GFP_KERNEL);
685         if (!msginfo)
686                 return -ENOMEM;
687
688         init_completion(&msginfo->waitevent);
689
690         msg = (struct vmbus_channel_message_header *)msginfo->msg;
691
692         msg->msgtype = CHANNELMSG_REQUESTOFFERS;
693
694
695         ret = vmbus_post_msg(msg,
696                                sizeof(struct vmbus_channel_message_header));
697         if (ret != 0) {
698                 pr_err("Unable to request offers - %d\n", ret);
699
700                 goto cleanup;
701         }
702
703         t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
704         if (t == 0) {
705                 ret = -ETIMEDOUT;
706                 goto cleanup;
707         }
708
709
710
711 cleanup:
712         kfree(msginfo);
713
714         return ret;
715 }
716
717 /*
718  * Retrieve the (sub) channel on which to send an outgoing request.
719  * When a primary channel has multiple sub-channels, we choose a
720  * channel whose VCPU binding is closest to the VCPU on which
721  * this call is being made.
722  */
723 struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
724 {
725         struct list_head *cur, *tmp;
726         int cur_cpu = hv_context.vp_index[smp_processor_id()];
727         struct vmbus_channel *cur_channel;
728         struct vmbus_channel *outgoing_channel = primary;
729         int cpu_distance, new_cpu_distance;
730
731         if (list_empty(&primary->sc_list))
732                 return outgoing_channel;
733
734         list_for_each_safe(cur, tmp, &primary->sc_list) {
735                 cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
736                 if (cur_channel->state != CHANNEL_OPENED_STATE)
737                         continue;
738
739                 if (cur_channel->target_vp == cur_cpu)
740                         return cur_channel;
741
742                 cpu_distance = ((outgoing_channel->target_vp > cur_cpu) ?
743                                 (outgoing_channel->target_vp - cur_cpu) :
744                                 (cur_cpu - outgoing_channel->target_vp));
745
746                 new_cpu_distance = ((cur_channel->target_vp > cur_cpu) ?
747                                 (cur_channel->target_vp - cur_cpu) :
748                                 (cur_cpu - cur_channel->target_vp));
749
750                 if (cpu_distance < new_cpu_distance)
751                         continue;
752
753                 outgoing_channel = cur_channel;
754         }
755
756         return outgoing_channel;
757 }
758 EXPORT_SYMBOL_GPL(vmbus_get_outgoing_channel);
759
760 static void invoke_sc_cb(struct vmbus_channel *primary_channel)
761 {
762         struct list_head *cur, *tmp;
763         struct vmbus_channel *cur_channel;
764
765         if (primary_channel->sc_creation_callback == NULL)
766                 return;
767
768         list_for_each_safe(cur, tmp, &primary_channel->sc_list) {
769                 cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
770
771                 primary_channel->sc_creation_callback(cur_channel);
772         }
773 }
774
775 void vmbus_set_sc_create_callback(struct vmbus_channel *primary_channel,
776                                 void (*sc_cr_cb)(struct vmbus_channel *new_sc))
777 {
778         primary_channel->sc_creation_callback = sc_cr_cb;
779 }
780 EXPORT_SYMBOL_GPL(vmbus_set_sc_create_callback);
781
782 bool vmbus_are_subchannels_present(struct vmbus_channel *primary)
783 {
784         bool ret;
785
786         ret = !list_empty(&primary->sc_list);
787
788         if (ret) {
789                 /*
790                  * Invoke the callback on sub-channel creation.
791                  * This will present a uniform interface to the
792                  * clients.
793                  */
794                 invoke_sc_cb(primary);
795         }
796
797         return ret;
798 }
799 EXPORT_SYMBOL_GPL(vmbus_are_subchannels_present);