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 Quintelabool 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 Quintelauint64_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 Quintelavoid 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)57*0743f41fSJuan Quintelavoid 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 Quintelauint64_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