aboutsummaryrefslogtreecommitdiff
path: root/migration/migration-stats.c
blob: f98c8260be47905f7ff6ee73fab842ea75419ea2 (plain)
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
/*
 * Migration stats
 *
 * Copyright (c) 2012-2023 Red Hat Inc
 *
 * Authors:
 *  Juan Quintela <quintela@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/stats64.h"
#include "qemu-file.h"
#include "trace.h"
#include "migration-stats.h"

MigrationAtomicStats mig_stats;

bool migration_rate_exceeded(QEMUFile *f)
{
    if (qemu_file_get_error(f)) {
        return true;
    }

    uint64_t rate_limit_start = stat64_get(&mig_stats.rate_limit_start);
    uint64_t rate_limit_current = migration_transferred_bytes(f);
    uint64_t rate_limit_used = rate_limit_current - rate_limit_start;
    uint64_t rate_limit_max = stat64_get(&mig_stats.rate_limit_max);

    if (rate_limit_max == RATE_LIMIT_DISABLED) {
        return false;
    }
    if (rate_limit_max > 0 && rate_limit_used > rate_limit_max) {
        return true;
    }
    return false;
}

uint64_t migration_rate_get(void)
{
    return stat64_get(&mig_stats.rate_limit_max);
}

#define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY)

void migration_rate_set(uint64_t limit)
{
    /*
     * 'limit' is per second.  But we check it each BUFER_DELAY miliseconds.
     */
    stat64_set(&mig_stats.rate_limit_max, limit / XFER_LIMIT_RATIO);
}

void migration_rate_reset(QEMUFile *f)
{
    stat64_set(&mig_stats.rate_limit_start, migration_transferred_bytes(f));
}

uint64_t migration_transferred_bytes(QEMUFile *f)
{
    uint64_t multifd = stat64_get(&mig_stats.multifd_bytes);
    uint64_t qemu_file = qemu_file_transferred(f);

    trace_migration_transferred_bytes(qemu_file, multifd);
    return qemu_file + multifd;
}