205
198
*-----------------------------------------------------------------------------
209
* Print a string into a bounded memory location.
212
* Number of character printed including trailing \0.
217
*-----------------------------------------------------------------------------
221
OS_Snprintf(char *buf, // OUT
223
const char *format, // IN
228
* XXX disabled because the varargs header file doesn't seem to
229
* work in the current (gcc 2.95.3) cross-compiler environment.
230
* Not used for Solaris anyway.
237
*-----------------------------------------------------------------------------
241
* Returns an identifier for the guest OS family.
249
*-----------------------------------------------------------------------------
255
return BALLOON_GUEST_SOLARIS;
260
*-----------------------------------------------------------------------------
262
200
* OS_ReservedPageGetLimit --
264
202
* Predict the maximum achievable balloon size.
456
394
*-----------------------------------------------------------------------------
398
vmmemctl_poll_worker(os_timer *t) // IN
462
os_timer *t = &global_state.timer;
465
402
mutex_enter(&t->lock);
466
404
while (!t->stop) {
467
/* invoke registered handler */
468
405
mutex_exit(&t->lock);
469
(void) (*(t->handler))(t->data);
407
Balloon_QueryAndExecute();
470
409
mutex_enter(&t->lock);
472
410
/* check again whether we should stop */
476
414
/* wait for timeout */
477
415
(void) drv_getparm(LBOLT, &timeout);
478
416
timeout += t->period;
479
if (cv_timedwait_sig(&t->cv, &t->lock, timeout) == 0) {
480
mutex_exit(&t->lock);
481
return EINTR; /* took a signal, return to user level */
417
cv_timedwait_sig(&t->cv, &t->lock, timeout);
484
420
mutex_exit(&t->lock);
486
return 0; /* normal termination */
503
439
*-----------------------------------------------------------------------------
507
OS_TimerStart(OSTimerHandler *handler, // IN
508
void *clientData) // IN
443
vmmemctl_poll_start(void)
510
445
os_timer *t = &global_state.timer;
512
448
/* setup the timer structure */
514
t->handler = handler;
515
t->data = clientData;
516
t->period = drv_usectohz(ONE_SECOND_IN_MICROSECONDS);
451
t->period = drv_usectohz(BALLOON_POLL_PERIOD * ONE_SECOND_IN_MICROSECONDS);
518
453
mutex_init(&t->lock, NULL, MUTEX_DRIVER, NULL);
519
454
cv_init(&t->cv, NULL, CV_DRIVER, NULL);
521
/* start the timer */
457
* All Solaris drivers that I checked assume that thread_create() will
458
* succeed, let's follow the suit.
460
tp = thread_create(NULL, 0, vmmemctl_poll_worker, (void *)t,
461
0, &p0, TS_RUN, minclsyspri);
462
t->thread_id = tp->t_did;
529
469
*-----------------------------------------------------------------------------
471
* vmmemctl_poll_stop --
473
* Signal polling thread to stop and wait till it exists.
595
*-----------------------------------------------------------------------------
599
* Called at driver startup, initializes the balloon state and structures.
608
*-----------------------------------------------------------------------------
612
OS_Init(const char *name, // IN
613
const char *nameVerbose, // IN
614
OSStatusHandler *handler) // IN
616
os_state *state = &global_state;
617
static int initialized = 0;
619
/* initialize only once */
624
/* zero global state */
625
bzero(state, sizeof(global_state));
627
state->kstats = BalloonKstatCreate();
628
state->id_space = id_space_create("vmmemctl", 0, INT_MAX);
630
state->name_verbose = nameVerbose;
632
/* disable memscrubber */
634
disable_memscrub = 1;
639
/* log device load */
640
cmn_err(CE_CONT, "!%s initialized\n", nameVerbose);
646
*-----------------------------------------------------------------------------
650
* Called when the driver is terminating, cleanup initialized structures.
658
*-----------------------------------------------------------------------------
664
os_state *state = &global_state;
667
BalloonKstatDelete(state->kstats);
668
id_space_destroy(state->id_space);
670
/* log device unload */
671
cmn_err(CE_CONT, "!%s unloaded\n", state->name_verbose);
676
* Device configuration entry points
681
vmmemctl_attach(dev_info_t *dip, // IN
682
ddi_attach_cmd_t cmd) // IN
687
if (ddi_create_minor_node(dip, "0", S_IFCHR, ddi_get_instance(dip),
688
DDI_PSEUDO,0) != DDI_SUCCESS) {
700
vmmemctl_detach(dev_info_t *dip, // IN
701
ddi_detach_cmd_t cmd) // IN
706
ddi_remove_minor_node(dip, NULL);
715
*-----------------------------------------------------------------------------
719
* Commands used by the user level daemon to control the driver.
720
* Since the daemon is single threaded, we use a simple monitor to
721
* make sure that only one thread is executing here at a time.
725
* On failure: error code
730
*-----------------------------------------------------------------------------
734
vmmemctl_ioctl(dev_t dev, // IN: Unused
736
intptr_t arg, // IN: Unused
737
int mode, // IN: Unused
739
int *rvalp) // IN: Unused
742
static int busy = 0; /* set when a thread is in this function */
743
static kmutex_t lock; /* lock to protect busy count */
745
if (drv_priv(cred) != 0)
751
* Only one thread at a time.
781
static struct cb_ops vmmemctl_cb_ops = {
784
nodev, /* strategy */
794
ddi_prop_op, /* prop_op */
799
static struct dev_ops vmmemctl_dev_ops = {
802
ddi_no_info, /* getinfo */
803
nulldev, /* identify */
808
&vmmemctl_cb_ops, /* cb_ops */
813
537
static struct modldrv vmmodldrv = {
815
539
"VMware Memory Control b" BUILD_NUMBER_NUMERIC_STRING,
819
542
static struct modlinkage vmmodlinkage = {
551
os_state *state = &global_state;
830
if (Balloon_ModuleInit() != BALLOON_SUCCESS) {
554
if (!Balloon_Init(BALLOON_GUEST_SOLARIS)) {
558
state->kstats = BalloonKstatCreate();
559
state->id_space = id_space_create(BALLOON_NAME, 0, INT_MAX);
561
/* disable memscrubber */
564
error = vmmemctl_poll_start();
833
570
error = mod_install(&vmmodlinkage);
835
Balloon_ModuleCleanup();
575
cmn_err(CE_CONT, "!%s initialized\n", BALLOON_NAME_VERBOSE);
579
vmmemctl_poll_stop();
582
id_space_destroy(state->id_space);
583
BalloonKstatDelete(state->kstats);