Commit 4e4fa398 authored by Jan Kiszka's avatar Jan Kiszka Committed by Anthony Liguori
Browse files

qdev: Introduce lost tick policy property



Potentially tick-generating timer devices will gain a common property:
lock_tick_policy. It allows to encode 4 different ways how to deal with
tick events the guest did not process in time:

discard - ignore lost ticks (e.g. if the guest compensates for them
          already)
delay   - replay all lost ticks in a row once the guest accepts them
          again
merge   - if multiple ticks are lost, all of them are merged into one
          which is replayed once the guest accepts it again
slew    - lost ticks are gradually replayed at a higher frequency than
          the original tick

Not all timer device will need to support all modes. However, all need
to accept the configuration via this common property.

Signed-off-by: default avatarJan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent 67ed96f9
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -885,6 +885,55 @@ PropertyInfo qdev_prop_macaddr = {
    .set   = set_generic,
};


/* --- lost tick policy --- */

static const struct {
    const char *name;
    LostTickPolicy code;
} lost_tick_policy_table[] = {
    { .name = "discard", .code = LOST_TICK_DISCARD },
    { .name = "delay", .code = LOST_TICK_DELAY },
    { .name = "merge", .code = LOST_TICK_MERGE },
    { .name = "slew", .code = LOST_TICK_SLEW },
};

static int parse_lost_tick_policy(DeviceState *dev, Property *prop,
                                  const char *str)
{
    LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);
    int i;

    for (i = 0; i < ARRAY_SIZE(lost_tick_policy_table); i++) {
        if (!strcasecmp(str, lost_tick_policy_table[i].name)) {
            *ptr = lost_tick_policy_table[i].code;
            break;
        }
    }
    if (i == ARRAY_SIZE(lost_tick_policy_table)) {
        return -EINVAL;
    }
    return 0;
}

static int print_lost_tick_policy(DeviceState *dev, Property *prop, char *dest,
                                  size_t len)
{
    LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);

    return snprintf(dest, len, "%s", lost_tick_policy_table[*ptr].name);
}

PropertyInfo qdev_prop_losttickpolicy = {
    .name  = "lost_tick_policy",
    .type  = PROP_TYPE_LOSTTICKPOLICY,
    .size  = sizeof(LostTickPolicy),
    .parse = parse_lost_tick_policy,
    .print = print_lost_tick_policy,
    .get   = get_generic,
    .set   = set_generic,
};

/* --- pci address --- */

/*
@@ -1127,6 +1176,12 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
    qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
}

void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
                                  LostTickPolicy *value)
{
    qdev_prop_set(dev, name, value, PROP_TYPE_LOSTTICKPOLICY);
}

void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
{
    qdev_prop_set(dev, name, &value, PROP_TYPE_PTR);
+7 −0
Original line number Diff line number Diff line
@@ -158,6 +158,7 @@ enum PropertyType {
    PROP_TYPE_UINT64,
    PROP_TYPE_TADDR,
    PROP_TYPE_MACADDR,
    PROP_TYPE_LOSTTICKPOLICY,
    PROP_TYPE_DRIVE,
    PROP_TYPE_CHR,
    PROP_TYPE_STRING,
@@ -307,6 +308,7 @@ extern PropertyInfo qdev_prop_string;
extern PropertyInfo qdev_prop_chr;
extern PropertyInfo qdev_prop_ptr;
extern PropertyInfo qdev_prop_macaddr;
extern PropertyInfo qdev_prop_losttickpolicy;
extern PropertyInfo qdev_prop_drive;
extern PropertyInfo qdev_prop_netdev;
extern PropertyInfo qdev_prop_vlan;
@@ -367,6 +369,9 @@ extern PropertyInfo qdev_prop_pci_devfn;
    DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
#define DEFINE_PROP_MACADDR(_n, _s, _f)         \
    DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
                        LostTickPolicy)

#define DEFINE_PROP_END_OF_LIST()               \
    {}
@@ -389,6 +394,8 @@ void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value);
int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT;
void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value);
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
                                  LostTickPolicy *value);
/* FIXME: Remove opaque pointer properties.  */
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
void qdev_prop_set_defaults(DeviceState *dev, Property *props);
+7 −0
Original line number Diff line number Diff line
@@ -250,6 +250,13 @@ typedef struct QEMUSGList QEMUSGList;

typedef uint64_t pcibus_t;

typedef enum LostTickPolicy {
    LOST_TICK_DISCARD,
    LOST_TICK_DELAY,
    LOST_TICK_MERGE,
    LOST_TICK_SLEW,
} LostTickPolicy;

void tcg_exec_init(unsigned long tb_size);
bool tcg_enabled(void);