File:  [Qemu by Fabrice Bellard] / qemu / balloon.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:55:37 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu1000, qemu0151, HEAD
qemu 0.15.1

    1: /*
    2:  * Generic Balloon handlers and management
    3:  *
    4:  * Copyright (c) 2003-2008 Fabrice Bellard
    5:  * Copyright (C) 2011 Red Hat, Inc.
    6:  * Copyright (C) 2011 Amit Shah <amit.shah@redhat.com>
    7:  *
    8:  * Permission is hereby granted, free of charge, to any person obtaining a copy
    9:  * of this software and associated documentation files (the "Software"), to deal
   10:  * in the Software without restriction, including without limitation the rights
   11:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   12:  * copies of the Software, and to permit persons to whom the Software is
   13:  * furnished to do so, subject to the following conditions:
   14:  *
   15:  * The above copyright notice and this permission notice shall be included in
   16:  * all copies or substantial portions of the Software.
   17:  *
   18:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   19:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   20:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   21:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   22:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   23:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   24:  * THE SOFTWARE.
   25:  */
   26: 
   27: #include "monitor.h"
   28: #include "qjson.h"
   29: #include "qint.h"
   30: #include "cpu-common.h"
   31: #include "kvm.h"
   32: #include "balloon.h"
   33: #include "trace.h"
   34: 
   35: static QEMUBalloonEvent *balloon_event_fn;
   36: static QEMUBalloonStatus *balloon_stat_fn;
   37: static void *balloon_opaque;
   38: 
   39: int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
   40:                              QEMUBalloonStatus *stat_func, void *opaque)
   41: {
   42:     if (balloon_event_fn || balloon_stat_fn || balloon_opaque) {
   43:         /* We're already registered one balloon handler.  How many can
   44:          * a guest really have?
   45:          */
   46:         error_report("Another balloon device already registered");
   47:         return -1;
   48:     }
   49:     balloon_event_fn = event_func;
   50:     balloon_stat_fn = stat_func;
   51:     balloon_opaque = opaque;
   52:     return 0;
   53: }
   54: 
   55: static int qemu_balloon(ram_addr_t target)
   56: {
   57:     if (!balloon_event_fn) {
   58:         return 0;
   59:     }
   60:     trace_balloon_event(balloon_opaque, target);
   61:     balloon_event_fn(balloon_opaque, target);
   62:     return 1;
   63: }
   64: 
   65: static int qemu_balloon_status(MonitorCompletion cb, void *opaque)
   66: {
   67:     if (!balloon_stat_fn) {
   68:         return 0;
   69:     }
   70:     balloon_stat_fn(balloon_opaque, cb, opaque);
   71:     return 1;
   72: }
   73: 
   74: static void print_balloon_stat(const char *key, QObject *obj, void *opaque)
   75: {
   76:     Monitor *mon = opaque;
   77: 
   78:     if (strcmp(key, "actual")) {
   79:         monitor_printf(mon, ",%s=%" PRId64, key,
   80:                        qint_get_int(qobject_to_qint(obj)));
   81:     }
   82: }
   83: 
   84: void monitor_print_balloon(Monitor *mon, const QObject *data)
   85: {
   86:     QDict *qdict;
   87: 
   88:     qdict = qobject_to_qdict(data);
   89:     if (!qdict_haskey(qdict, "actual")) {
   90:         return;
   91:     }
   92:     monitor_printf(mon, "balloon: actual=%" PRId64,
   93:                    qdict_get_int(qdict, "actual") >> 20);
   94:     qdict_iter(qdict, print_balloon_stat, mon);
   95:     monitor_printf(mon, "\n");
   96: }
   97: 
   98: /**
   99:  * do_info_balloon(): Balloon information
  100:  *
  101:  * Make an asynchronous request for balloon info.  When the request completes
  102:  * a QDict will be returned according to the following specification:
  103:  *
  104:  * - "actual": current balloon value in bytes
  105:  * The following fields may or may not be present:
  106:  * - "mem_swapped_in": Amount of memory swapped in (bytes)
  107:  * - "mem_swapped_out": Amount of memory swapped out (bytes)
  108:  * - "major_page_faults": Number of major faults
  109:  * - "minor_page_faults": Number of minor faults
  110:  * - "free_mem": Total amount of free and unused memory (bytes)
  111:  * - "total_mem": Total amount of available memory (bytes)
  112:  *
  113:  * Example:
  114:  *
  115:  * { "actual": 1073741824, "mem_swapped_in": 0, "mem_swapped_out": 0,
  116:  *   "major_page_faults": 142, "minor_page_faults": 239245,
  117:  *   "free_mem": 1014185984, "total_mem": 1044668416 }
  118:  */
  119: int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque)
  120: {
  121:     int ret;
  122: 
  123:     if (kvm_enabled() && !kvm_has_sync_mmu()) {
  124:         qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
  125:         return -1;
  126:     }
  127: 
  128:     ret = qemu_balloon_status(cb, opaque);
  129:     if (!ret) {
  130:         qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
  131:         return -1;
  132:     }
  133: 
  134:     return 0;
  135: }
  136: 
  137: /**
  138:  * do_balloon(): Request VM to change its memory allocation
  139:  */
  140: int do_balloon(Monitor *mon, const QDict *params,
  141: 	       MonitorCompletion cb, void *opaque)
  142: {
  143:     int64_t target;
  144:     int ret;
  145: 
  146:     if (kvm_enabled() && !kvm_has_sync_mmu()) {
  147:         qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
  148:         return -1;
  149:     }
  150: 
  151:     target = qdict_get_int(params, "value");
  152:     if (target <= 0) {
  153:         qerror_report(QERR_INVALID_PARAMETER_VALUE, "target", "a size");
  154:         return -1;
  155:     }
  156:     ret = qemu_balloon(target);
  157:     if (ret == 0) {
  158:         qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
  159:         return -1;
  160:     }
  161: 
  162:     cb(opaque, NULL);
  163:     return 0;
  164: }

unix.superglobalmegacorp.com