xref: /qemu/migration/migration-stats.c (revision 0743f41f)
1947701ccSJuan Quintela /*
2947701ccSJuan Quintela  * Migration stats
3947701ccSJuan Quintela  *
4947701ccSJuan Quintela  * Copyright (c) 2012-2023 Red Hat Inc
5947701ccSJuan Quintela  *
6947701ccSJuan Quintela  * Authors:
7947701ccSJuan Quintela  *  Juan Quintela <quintela@redhat.com>
8947701ccSJuan Quintela  *
9947701ccSJuan Quintela  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10947701ccSJuan Quintela  * See the COPYING file in the top-level directory.
11947701ccSJuan Quintela  */
12947701ccSJuan Quintela 
13947701ccSJuan Quintela #include "qemu/osdep.h"
14947701ccSJuan Quintela #include "qemu/stats64.h"
15e1fde0e0SJuan Quintela #include "qemu-file.h"
163db9c05aSJuan Quintela #include "trace.h"
17947701ccSJuan Quintela #include "migration-stats.h"
18947701ccSJuan Quintela 
1996820df2SJuan Quintela MigrationAtomicStats mig_stats;
20e1fde0e0SJuan Quintela 
migration_rate_exceeded(QEMUFile * f)21e1fde0e0SJuan Quintela bool migration_rate_exceeded(QEMUFile *f)
22e1fde0e0SJuan Quintela {
23e1fde0e0SJuan Quintela     if (qemu_file_get_error(f)) {
24e1fde0e0SJuan Quintela         return true;
25e1fde0e0SJuan Quintela     }
26e1fde0e0SJuan Quintela 
2760c7981aSElena Ufimtseva     uint64_t rate_limit_max = migration_rate_get();
28e1fde0e0SJuan Quintela     if (rate_limit_max == RATE_LIMIT_DISABLED) {
29e1fde0e0SJuan Quintela         return false;
30e1fde0e0SJuan Quintela     }
3160c7981aSElena Ufimtseva 
3260c7981aSElena Ufimtseva     uint64_t rate_limit_start = stat64_get(&mig_stats.rate_limit_start);
33f57e5a6cSJuan Quintela     uint64_t rate_limit_current = migration_transferred_bytes();
3460c7981aSElena Ufimtseva     uint64_t rate_limit_used = rate_limit_current - rate_limit_start;
3560c7981aSElena Ufimtseva 
36e1fde0e0SJuan Quintela     if (rate_limit_max > 0 && rate_limit_used > rate_limit_max) {
37e1fde0e0SJuan Quintela         return true;
38e1fde0e0SJuan Quintela     }
39e1fde0e0SJuan Quintela     return false;
40e1fde0e0SJuan Quintela }
41e1fde0e0SJuan Quintela 
migration_rate_get(void)42e1fde0e0SJuan Quintela uint64_t migration_rate_get(void)
43e1fde0e0SJuan Quintela {
44e1fde0e0SJuan Quintela     return stat64_get(&mig_stats.rate_limit_max);
45e1fde0e0SJuan Quintela }
46e1fde0e0SJuan Quintela 
47e1fde0e0SJuan Quintela #define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY)
48e1fde0e0SJuan Quintela 
migration_rate_set(uint64_t limit)49e1fde0e0SJuan Quintela void migration_rate_set(uint64_t limit)
50e1fde0e0SJuan Quintela {
51e1fde0e0SJuan Quintela     /*
52d8b71d96SMichael Tokarev      * 'limit' is per second.  But we check it each BUFFER_DELAY milliseconds.
53e1fde0e0SJuan Quintela      */
54e1fde0e0SJuan Quintela     stat64_set(&mig_stats.rate_limit_max, limit / XFER_LIMIT_RATIO);
55e1fde0e0SJuan Quintela }
56e1fde0e0SJuan Quintela 
migration_rate_reset(void)570743f41fSJuan Quintela void migration_rate_reset(void)
58e1fde0e0SJuan Quintela {
59f57e5a6cSJuan Quintela     stat64_set(&mig_stats.rate_limit_start, migration_transferred_bytes());
60e1fde0e0SJuan Quintela }
61e1fde0e0SJuan Quintela 
migration_transferred_bytes(void)62f57e5a6cSJuan Quintela uint64_t migration_transferred_bytes(void)
6399319e2dSJuan Quintela {
643db9c05aSJuan Quintela     uint64_t multifd = stat64_get(&mig_stats.multifd_bytes);
6567c31c9cSJuan Quintela     uint64_t rdma = stat64_get(&mig_stats.rdma_bytes);
66737840e2SJuan Quintela     uint64_t qemu_file = stat64_get(&mig_stats.qemu_file_transferred);
673db9c05aSJuan Quintela 
6867c31c9cSJuan Quintela     trace_migration_transferred_bytes(qemu_file, multifd, rdma);
6967c31c9cSJuan Quintela     return qemu_file + multifd + rdma;
7099319e2dSJuan Quintela }
71