Files @ d6b9b2ac5869
Branch filter:

Location: vmkdrivers/BLD/build/HEADERS/vmkapi-current-all-public-bincomp/vmkernel64/release/base/vmkapi_world.h

unknown
ESXi-5.5-U2
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
/* **********************************************************
 * Copyright 2007 - 2012 VMware, Inc.  All rights reserved.
 * **********************************************************/

/*
 * @VMKAPIMOD_LICENSE@
 */

/*
 ***********************************************************************
 * Worlds                                                         */ /**
 * \defgroup Worlds Worlds
 *
 * Worlds are a schedulable entity in the VMkernel. For example worlds
 * are used to represent kernel threads, user processes, virtual CPUs,
 * etc. Each world is identified by an ID that is unique within the
 * system called the World ID. Worlds are blockable contexts; it is safe
 * to call functions that may block from a world context.
 *
 * User processes also belong to cartels.  A cartel is a group of worlds
 * that share certain resources including but not limited to their
 * address space.  A cartel can be thought of as a user process and the
 * individual worlds that make up the cartel can be thought of as user
 * threads.  Each user world will have a world ID and a cartel ID.  Each
 * world in a cartel will share the same cartel ID.  Note that it is
 * possible for a world's world ID and cartel ID to be equal, but
 * this can only be true for at most one world in the cartel.
 *
 *@{
 ***********************************************************************
 */

#ifndef _VMKAPI_WORLD_H_
#define _VMKAPI_WORLD_H_

/** \cond never */
#ifndef VMK_HEADER_INCLUDED_FROM_VMKAPI_H
#error This vmkapi file should never be included directly but only via vmkapi.h
#endif
/** \endcond never */

#include "device/vmkapi_vector_types.h"

/**
 * \brief Event to block on.
 *
 * Events to block on are, by convention, always kernel virtual addresses.
 */
typedef vmk_VA vmk_WorldEventID;

/** \brief The body function of a world. */
typedef VMK_ReturnStatus (*vmk_WorldStartFunc)(void *data);

/** \brief Opaque handle for a world */
typedef vmk_int32 vmk_WorldID;

#define VMK_INVALID_WORLD_ID ((vmk_WorldID)0)

/** \brief Special vmk_WorldEventID for a no-event wait
 *
 * When used as the eventId parameter to vmk_WorldWait(),
 * the world will wait without being added to the system's
 * internal event queue.  This allows for a lighter weight
 * synchronization mechanism, though the world sleeping in
 * this fashion can be awoken only by vmk_WorldForceWakeup(),
 * by a timeout, or if the world is being destroyed.
 */
#define VMK_EVENT_NONE ((vmk_WorldEventID)0)

/**
 * \brief Indication of unlimited CPU allocation (max)
 */
#define VMK_CPU_ALLOC_UNLIMITED ((vmk_uint32) -1)

/**
 * \brief Scheduler Class for a World
 *
 * Worlds of class VMK_WORLD_SCHED_CLASS_QUICK will be scheduled
 * to run ahead of worlds of class VMK_WORLD_SCHED_CLASS_DEFAULT.
 * Please be careful to use VMK_WORLD_SCHED_CLASS_QUICK only for
 * small deferred tasks that must execute promptly.
 *
 * If unsure of what class to use, pick VMK_WORLD_SCHED_CLASS_DEFAULT.
 */
typedef enum {

   /** Default scheduler class for kernel threads. */
   VMK_WORLD_SCHED_CLASS_DEFAULT = 1,

   /** Scheduler class for kernel threads that must execute prompty. */
   VMK_WORLD_SCHED_CLASS_QUICK = 100,

} vmk_WorldSchedClass;

/**
 * \brief Properties for creating a new world.
 */
typedef struct vmk_WorldProps {
   /** \brief Name associated with this world. */
   const char *name;

   /** \brief Module ID of the module creating this world. */
   vmk_ModuleID moduleID;

   /** \brief Function that the world begins executing at creation. */
   vmk_WorldStartFunc startFunction;

   /** \brief Opaque argument to the startFunction. */
   void *data;

   /** \brief Scheduler class for the new world. */
   vmk_WorldSchedClass schedClass;

} vmk_WorldProps;

/*
 ***********************************************************************
 * vmk_WorldCreate --                                             */ /**
 *
 * \ingroup Worlds
 * \brief Create and start a new kernel thread
 *
 * \note  This function may block.
 *
 * \warning Code running inside a system world can be preempted by
 *          default.  Code should be careful not to access Per-PCPU
 *          Storage, or to hold locks of type VMK_SPINLOCK_IRQ, for
 *          a period time exceeding 10us - since these acquisitions
 *          block preemption.
 *
 * \param[in]  props          Properties of this world.
 * \param[out] worldId        World ID associated with the newly
 *                            created world. If caller sets this
 *                            poitner to NULL, then the World ID is
 *                            not returned.
 *
 * \retval VMK_OK             World created.
 * \retval VMK_NO_MEMORY      Ran out of memory.
 * \retval VMK_DEATH_PENDING  World is in the process of dying.
 * \retval VMK_NO_MODULE_HEAP The module's heap is not set.
 * \retval VMK_BAD_PARAM      The priority specified is in the
 *                            properties is invalid.
 *
 ***********************************************************************
 */
VMK_ReturnStatus vmk_WorldCreate(vmk_WorldProps *props,
                                 vmk_WorldID *worldId);

/*
 ***********************************************************************
 * vmk_WorldDestroy --                                             */ /**
 *
 * \ingroup Worlds
 * \brief Destroy a world created by vmk_WorldCreate.
 *
 * \note  This function may block.
 *
 * \note  This function does not wait for the world to actually die.
 *        Use vmk_WorldWaitForDeath() to wait for death.
 *
 * \param[in] worldID         vmk_WorldID of the world to destroy.
 *
 * \retval VMK_OK             Kill was successfully posted.
 * \retval VMK_NOT_FOUND      Specified worldID was not found.
 *
 ***********************************************************************
 */
VMK_ReturnStatus vmk_WorldDestroy(
   vmk_WorldID worldID);

/*
 ***********************************************************************
 * vmk_WorldExit --                                               */ /**
 *
 * \ingroup Worlds
 * \brief End execution of the calling world.
 *
 * \note  This function never returns.
 *
 * \param[in] status   Status of the world on exit.
 *
 ***********************************************************************
 */
void vmk_WorldExit(VMK_ReturnStatus status);

/*
 ***********************************************************************
 * vmk_WorldGetID --                                              */ /**
 *
 * \ingroup Worlds
 * \brief Get the ID of the current world.
 *
 * \note  This function will not block.
 *
 * \return  WorldID of the currently running world that this
 *          call was invoked from or VMK_INVALID_WORLD_ID if
 *          this call was not invoked from a world context.
 *
 ***********************************************************************
 */
vmk_WorldID vmk_WorldGetID(
   void);

/*
 ***********************************************************************
 * vmk_WorldGetCartelID --                                        */ /**
 *
 * \ingroup Worlds
 * \brief Get the Cartel ID of the current world.
 *
 * \note  This function will not block.
 *
 * \return  WorldID of the cartel of the currently running world that
 *          this call was invoked from or VMK_INVALID_WORLD_ID if
 *          this call was not invoked from a user world context.
 *
 ***********************************************************************
 */
vmk_WorldID vmk_WorldGetCartelID(
   void);

/*
 ***********************************************************************
 * vmk_WorldIDToCartelID --                                       */ /**
 *
 * \ingroup Worlds
 * \brief Get the Cartel ID of the specified world.
 *
 * \note  This function will not block.
 *
 * \return  WorldID of the cartel of the provided world ID or
 *          VMK_INVALID_WORLD_ID if the provided world is not a user
 *          world context.
 *
 ***********************************************************************
 */
vmk_WorldID vmk_WorldIDToCartelID(
   vmk_WorldID worldID);

/*
 ***********************************************************************
 * vmk_WorldAssertIsSafeToBlockInt --
 *
 * This is used by vmk_WorldAssertIsSafeToBlock.  VMKAPI clients should
 * not call this function directly.
 *
 ***********************************************************************
 */

/** \cond nodoc */
void
vmk_WorldAssertIsSafeToBlockInt(
   void);
/** \endcond */

/*
 ***********************************************************************
 * vmk_WorldAssertIsSafeToBlock --                                */ /**
 *
 * \ingroup Globals
 * \brief Assert that it is OK for the caller to block.
 *
 * \note Only performs checking in debug builds.
 * \note This function will not block.
 *
 ***********************************************************************
 */

static VMK_ALWAYS_INLINE void 
vmk_WorldAssertIsSafeToBlock(
   void)
{
#ifdef VMX86_DEBUG
   vmk_WorldAssertIsSafeToBlockInt();
#endif
}

/*
 ***********************************************************************
 * vmk_WorldWait --                                               */ /**
 *
 * \brief Deschedule a World holding a non-IRQ Lock until awakened or
 *        until the specified timeout expires.
 *
 * \note  This function may block.
 *
 * \note Spurious wakeups are possible.  Specifially, users of this
 *       API must always verify that the condition on which they
 *       are waiting has actually occurred before taking action.
 *
 * \param[in]  eventId     Either a system wide unique identifier for the
 *                         event to sleep on, or VMK_EVENT_NONE.  When
 *                         VMK_EVENT_NONE is specified, the world can be
 *                         awoken only by vmk_WorldForceWakeup(), by a
 *                         timeout, or if the world is being destroyed.
 * \param[in]  lock        Lock of type VMK_SPINLOCK to release before
 *                         descheduling the world.  VMK_LOCK_INVALID 
 *                         indicates that no lock needs to be released
 *                         before descheduling the world.
 * \param[in]  timeoutMS   Number of milliseconds before timeout
 *                         VMK_TIMEOUT_UNLIMITED_MS indicates that the
 *                         caller wants to block forever.
 *                         VMK_TIMEOUT_NONBLOCKING is not a valid value
 *                         in this context.
 * \param[in]  reason      A short string that explains the reason for
 *                         the vmk_WorldWait call.
 *
 * \retval VMK_OK                World was descheduled and awoken by a
 *                               vmk_WorldWakeup on eventId.
 * \retval VMK_BAD_PARAM         World was not descheduled because a
 *                               provided parameter was invalid.  If a
 *                               lock was provided then it was not
 *                               released.
 * \retval VMK_TIMEOUT           World was descheduled and awoken
 *                               because of timeout expiration.
 * \retval VMK_DEATH_PENDING     World was descheduled and awoken
 *                               because the world is dying and being
 *                               reaped by the scheduler. The caller is
 *                               expected to return as soon as possible.
 * \retval VMK_WAIT_INTERRUPTED  World was descheduled and awoken for
 *                               some other reason not specified by
 *                               previous return codes. The caller is
 *                               allowed to re-enter vmk_WorldWait.
 *
 ***********************************************************************
 */

VMK_ReturnStatus vmk_WorldWait(
   vmk_WorldEventID eventId,
   vmk_Lock lock,
   vmk_uint32 timeoutMS,
   const char *reason);


/*
 ***********************************************************************
 * vmk_WorldWakeup --                                             */ /**
 *
 * \ingroup Worlds
 * \brief Wake up all the Worlds waiting on a event eventId
 *
 * \note  This function may block.
 *
 * \param[in] eventId      System wide unique identifier of the event.
 *
 * \retval VMK_OK          One or more worlds was awakened.
 * \retval VMK_NOT_FOUND   No worlds were found that wake up to eventId.
 *
 ***********************************************************************
 */
VMK_ReturnStatus vmk_WorldWakeup(
   vmk_WorldEventID eventId);

/*
 ***********************************************************************
 * vmk_WorldForceWakeup --                                        */ /**
 *
 * \ingroup Worlds
 * \brief Wake up a specific world directly, regardless of what
 *        event it is waiting on.
 *
 * \note  This function may block.
 *
 * \note  A forced wakeup is special, in that the wakeup it generates
 *        is "stateful" when used in conjuction with VMK_EVENT_NONE.
 *        Specifically, if a world is not waiting when a forced wakeup
 *        is generated, then the wakeup goes pending.  If the world
 *        then attempts to wait on VMK_EVENT_NONE, the world will
 *        not sleep (and the pending is cleared).
 *
 * \param[in] worldID      World ID of the world to wake up.
 *
 * \retval VMK_OK             The world was awoken.
 * \retval VMK_NOT_FOUND      The world was not found to need wakeup.
 * \retval VMK_INVALID_WORLD  The world ID did not correspond to an
 *                            existing world.
 *
 ***********************************************************************
 */
VMK_ReturnStatus vmk_WorldForceWakeup(
   vmk_WorldID worldID);

/*
 ***********************************************************************
 * vmk_WorldSleep --                                              */ /**
 *
 * \ingroup Worlds
 * \brief Wait for at least the amount of time given.
 *
 * \note  This function may block.
 *
 * \note  Very short delays may not result in the calling world
 *        blocking.
 *
 * \param[in] delayUs   Duration to wait in microseconds.
 *
 * \retval VMK_OK                Awakened after at least the specified
 *                               delay.
 * \retval VMK_DEATH_PENDING     Awakened because the world is dying
 *                               and being reaped by the scheduler.
 *                               The entire delay may not have passed.
 * \retval VMK_WAIT_INTERRUPTED  Awakened for some other reason.  The
 *                               entire delay may not have passed.
 *
 ***********************************************************************
 */
VMK_ReturnStatus vmk_WorldSleep(
   vmk_uint64 delayUs);

/*
 ***********************************************************************
 * vmk_WorldYield --                                              */ /**
 *
 * \ingroup Worlds
 * \brief Invokes the scheduler, possibly descheduling the calling
 *        World in favor of another.  The calling world continues to
 *        be runnable and may resume running at any time.
 *
 * \note  This function may block.
 *
 ***********************************************************************
 */
VMK_ReturnStatus vmk_WorldYield(
   void);

/*
 ***********************************************************************
 * vmk_WorldGetCPUMinMax --                                       */ /**
 *
 * \ingroup Worlds
 * \brief Get the min/max CPU allocation in MHz for the running world.
 *
 * \note  This function will not block.

 * \param[out] min   Minimum CPU allocation of the current running
 *                   world in MHz.
 * \param[out] max   Maximum CPU allocation of the current running
 *                   world in MHz.
 *
 ***********************************************************************
 */
VMK_ReturnStatus vmk_WorldGetCPUMinMax(
    vmk_uint32 *min,
    vmk_uint32 *max);

/*
 ***********************************************************************
 * vmk_WorldSetCPUMinMax --                                       */ /**
 *
 * \ingroup Worlds
 * \brief Set the min/max CPU allocation in MHz for the running world

 * \note The scheduling of the current world will change based on the
 *       input parameters.
 *
 * \note  This function will not block.
 *
 * \param[in] min    Minimum CPU allocation in MHz that will be
 *                   guaranteed.
 * \param[in] max    Maximum CPU allocation in MHz that the world can
 *                   use.
 *
 ***********************************************************************
 */
VMK_ReturnStatus vmk_WorldSetCPUMinMax(
    vmk_uint32 min,
    vmk_uint32 max);

/*
 ***********************************************************************
 * vmk_WorldsMax --                                               */ /**
 *
 * \ingroup Worlds
 * \brief Returns the maximum possible number of worlds the system
 *        will support.
 *
 * \note  This function will not block.

 * \note This includes VMs and any other worlds that the system needs
 *       to execute.
 *
 ***********************************************************************
 */
vmk_uint32 vmk_WorldsMax(void);

/*
 ***********************************************************************
 * vmk_WorldWaitForDeath --                                      */ /**
 *
 * \ingroup Worlds
 * \brief Waits until the specified world is no longer running.
 *
 * Note that holding an open world private storage handle on the
 * target world (via the vmk_WorldStorageLookUp interface) will
 * prevent the target world from dying, and will thus cause this
 * call to deadlock with the target world.  All such open handles
 * on the target world must be released via vmk_WorldStorageRelease
 * before calling this function.
 *
 * \note  This function may block.
 *
 * \retval VMK_OK              The requested world has died.
 * \retval VMK_INVALID_WORLD   The specified world was invalid.  It
 *                             may have already died.
 *
 ***********************************************************************
 */
VMK_ReturnStatus vmk_WorldWaitForDeath(
   vmk_WorldID worldID);

/*
 ***********************************************************************
 * vmk_WorldInterruptSet --                                       */ /**
 *
 * \brief Sets an interrupt association for the specified world.
 *
 * Interrupts will be delivered to the same PCPU that this world is
 * running on.
 *
 * \note  This function will not block.
 *
 * \param[in] worldID          ID of the world to set interrupt
 *                             association for.
 * \param[in] intrCookie       Interrupt cookie previously retrieved via
 *                             vmk_IntrRegister
 *
 * \retval VMK_OK              The vector association has been set.
 * \retval VMK_BAD_PARAM       The specified vector is invalid.
 * \retval VMK_LIMIT_EXCEEDED  The specified vector cannot be added.
 * \retval VMK_INVALID_WORLD   The specified world id was invalid.
 * \retval VMK_FAILURE         The interrupt association cannot be set.
 *
 ***********************************************************************
 */
VMK_ReturnStatus vmk_WorldInterruptSet(
   vmk_WorldID worldID,
   vmk_IntrCookie intrCookie);

/*
 ***********************************************************************
 * vmk_WorldInterruptUnset --                                     */ /**
 *
 * \ingroup Worlds
 * \brief Unsets an interrupt association for the specified world.
 *
 * \note  This function will not block.
 *
 * \param[in] worldID          ID of the world to unset interrupt
 *                             association for.
 * \param[in] intrCookie       Interrupt cookie previously retrieved via
 *                             vmk_IntrRegister
 *
 * \retval VMK_OK              The interrupt association has been unset.
 * \retval VMK_NOT_FOUND       The interrupt is currently not associated
 *                             with the world.
 * \retval VMK_INVALID_WORLD   The specified world id was invalid.
 * \retval VMK_FAILURE         The interrupt association cannot be unset.
 *
 ***********************************************************************
 */
VMK_ReturnStatus vmk_WorldInterruptUnset(
   vmk_WorldID worldID,
   vmk_IntrCookie intrCookie);

/*
 ***********************************************************************
 * vmk_WorldRelationAdd --                                        */ /**
 *
 * \brief Add a relationship between two worlds
 *
 * This interface should be used to give a hint to the scheduler that there is a
 * communication flow from world A to world B. This is useful for multi-threaded
 * producer-consumer implementations. World A would equal the producer and world
 * B would equal the consumer. If both worlds can be a producer and consumer
 * then the interface should be called twice.
 * Establishing a relationship between worlds is an important performance
 * optimization and should always be done for worlds that are part of a hot
 * path.
 *
 * \note  This function might block.
 *
 * \param[in] worldA           ID of the world initiating the communication.
 * \param[in] worldB           ID of the world receiving the communication.
 *
 ***********************************************************************
 */

VMK_ReturnStatus vmk_WorldRelationAdd(
   vmk_WorldID worldA,
   vmk_WorldID worldB);


/*
 ***********************************************************************
 * vmk_WorldRelationRemove --                                     */ /**
 *
 * \brief Remove a relationship between two worlds
 *
 * The relationship must have previously been set through vmk_WorldRelationAdd.
 *
 * \note  This function might block.
 *
 * \param[in] worldA           ID of the world initiating the communication.
 * \param[in] worldB           ID of the world receiving the communication.
 *
 ***********************************************************************
 */

VMK_ReturnStatus vmk_WorldRelationRemove(
   vmk_WorldID worldA,
   vmk_WorldID worldB);

#endif /* _VMKAPI_WORLD_H_ */
/** @} */