Blame SOURCES/kvm-block-add-aio_context-field-in-ThrottleGroupMember.patch

4a2fec
From 5531090858f0cb3aabf6e95a948256b4eeb36e5a Mon Sep 17 00:00:00 2001
4a2fec
From: Stefan Hajnoczi <stefanha@redhat.com>
4a2fec
Date: Fri, 17 Nov 2017 11:19:01 +0100
4a2fec
Subject: [PATCH 02/15] block: add aio_context field in ThrottleGroupMember
4a2fec
4a2fec
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
4a2fec
Message-id: <20171117111908.8815-3-stefanha@redhat.com>
4a2fec
Patchwork-id: 77735
4a2fec
O-Subject: [RHV7.5 qemu-kvm-rhev PATCH 2/9] block: add aio_context field in ThrottleGroupMember
4a2fec
Bugzilla: 1492295
4a2fec
RH-Acked-by: John Snow <jsnow@redhat.com>
4a2fec
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
4a2fec
RH-Acked-by: Thomas Huth <thuth@redhat.com>
4a2fec
4a2fec
From: Manos Pitsidianakis <el13635@mail.ntua.gr>
4a2fec
4a2fec
timer_cb() needs to know about the current Aio context of the throttle
4a2fec
request that is woken up. In order to make ThrottleGroupMember backend
4a2fec
agnostic, this information is stored in an aio_context field instead of
4a2fec
accessing it from BlockBackend.
4a2fec
4a2fec
Reviewed-by: Alberto Garcia <berto@igalia.com>
4a2fec
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4a2fec
Signed-off-by: Manos Pitsidianakis <el13635@mail.ntua.gr>
4a2fec
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4a2fec
(cherry picked from commit c61791fc23ecd96e6a1e038c379c4033ffd5f40c)
4a2fec
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
4a2fec
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
4a2fec
---
4a2fec
 block/block-backend.c           | 15 ++++------
4a2fec
 block/throttle-groups.c         | 38 ++++++++++++++++---------
4a2fec
 include/block/throttle-groups.h |  7 ++++-
4a2fec
 tests/test-throttle.c           | 63 +++++++++++++++++++++--------------------
4a2fec
 4 files changed, 69 insertions(+), 54 deletions(-)
4a2fec
4a2fec
diff --git a/block/block-backend.c b/block/block-backend.c
4a2fec
index e61f072..515be10 100644
4a2fec
--- a/block/block-backend.c
4a2fec
+++ b/block/block-backend.c
4a2fec
@@ -1766,18 +1766,14 @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
4a2fec
 void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
4a2fec
 {
4a2fec
     BlockDriverState *bs = blk_bs(blk);
4a2fec
-    ThrottleTimers *tt;
4a2fec
+    ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
4a2fec
 
4a2fec
     if (bs) {
4a2fec
-        if (blk->public.throttle_group_member.throttle_state) {
4a2fec
-            tt = &blk->public.throttle_group_member.throttle_timers;
4a2fec
-            throttle_timers_detach_aio_context(tt);
4a2fec
+        if (tgm->throttle_state) {
4a2fec
+            throttle_group_detach_aio_context(tgm);
4a2fec
+            throttle_group_attach_aio_context(tgm, new_context);
4a2fec
         }
4a2fec
         bdrv_set_aio_context(bs, new_context);
4a2fec
-        if (blk->public.throttle_group_member.throttle_state) {
4a2fec
-            tt = &blk->public.throttle_group_member.throttle_timers;
4a2fec
-            throttle_timers_attach_aio_context(tt, new_context);
4a2fec
-        }
4a2fec
     }
4a2fec
 }
4a2fec
 
4a2fec
@@ -2010,7 +2006,8 @@ void blk_io_limits_disable(BlockBackend *blk)
4a2fec
 void blk_io_limits_enable(BlockBackend *blk, const char *group)
4a2fec
 {
4a2fec
     assert(!blk->public.throttle_group_member.throttle_state);
4a2fec
-    throttle_group_register_tgm(&blk->public.throttle_group_member, group);
4a2fec
+    throttle_group_register_tgm(&blk->public.throttle_group_member,
4a2fec
+                                group, blk_get_aio_context(blk));
4a2fec
 }
4a2fec
 
4a2fec
 void blk_io_limits_update_group(BlockBackend *blk, const char *group)
4a2fec
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
4a2fec
index c8ed16d..3b07b25 100644
4a2fec
--- a/block/throttle-groups.c
4a2fec
+++ b/block/throttle-groups.c
4a2fec
@@ -391,9 +391,6 @@ static void coroutine_fn throttle_group_restart_queue_entry(void *opaque)
4a2fec
 
4a2fec
 static void throttle_group_restart_queue(ThrottleGroupMember *tgm, bool is_write)
4a2fec
 {
4a2fec
-    BlockBackendPublic *blkp = container_of(tgm, BlockBackendPublic,
4a2fec
-            throttle_group_member);
4a2fec
-    BlockBackend *blk = blk_by_public(blkp);
4a2fec
     Coroutine *co;
4a2fec
     RestartData rd = {
4a2fec
         .tgm = tgm,
4a2fec
@@ -401,7 +398,7 @@ static void throttle_group_restart_queue(ThrottleGroupMember *tgm, bool is_write
4a2fec
     };
4a2fec
 
4a2fec
     co = qemu_coroutine_create(throttle_group_restart_queue_entry, &rd);
4a2fec
-    aio_co_enter(blk_get_aio_context(blk), co);
4a2fec
+    aio_co_enter(tgm->aio_context, co);
4a2fec
 }
4a2fec
 
4a2fec
 void throttle_group_restart_tgm(ThrottleGroupMember *tgm)
4a2fec
@@ -449,13 +446,11 @@ void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg)
4a2fec
 /* ThrottleTimers callback. This wakes up a request that was waiting
4a2fec
  * because it had been throttled.
4a2fec
  *
4a2fec
- * @blk:       the BlockBackend whose request had been throttled
4a2fec
+ * @tgm:       the ThrottleGroupMember whose request had been throttled
4a2fec
  * @is_write:  the type of operation (read/write)
4a2fec
  */
4a2fec
-static void timer_cb(BlockBackend *blk, bool is_write)
4a2fec
+static void timer_cb(ThrottleGroupMember *tgm, bool is_write)
4a2fec
 {
4a2fec
-    BlockBackendPublic *blkp = blk_get_public(blk);
4a2fec
-    ThrottleGroupMember *tgm = &blkp->throttle_group_member;
4a2fec
     ThrottleState *ts = tgm->throttle_state;
4a2fec
     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
4a2fec
 
4a2fec
@@ -484,18 +479,18 @@ static void write_timer_cb(void *opaque)
4a2fec
  *
4a2fec
  * @tgm:       the ThrottleGroupMember to insert
4a2fec
  * @groupname: the name of the group
4a2fec
+ * @ctx:       the AioContext to use
4a2fec
  */
4a2fec
 void throttle_group_register_tgm(ThrottleGroupMember *tgm,
4a2fec
-                                 const char *groupname)
4a2fec
+                                 const char *groupname,
4a2fec
+                                 AioContext *ctx)
4a2fec
 {
4a2fec
     int i;
4a2fec
-    BlockBackendPublic *blkp = container_of(tgm, BlockBackendPublic,
4a2fec
-            throttle_group_member);
4a2fec
-    BlockBackend *blk = blk_by_public(blkp);
4a2fec
     ThrottleState *ts = throttle_group_incref(groupname);
4a2fec
     ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
4a2fec
 
4a2fec
     tgm->throttle_state = ts;
4a2fec
+    tgm->aio_context = ctx;
4a2fec
 
4a2fec
     qemu_mutex_lock(&tg->lock);
4a2fec
     /* If the ThrottleGroup is new set this ThrottleGroupMember as the token */
4a2fec
@@ -508,11 +503,11 @@ void throttle_group_register_tgm(ThrottleGroupMember *tgm,
4a2fec
     QLIST_INSERT_HEAD(&tg->head, tgm, round_robin);
4a2fec
 
4a2fec
     throttle_timers_init(&tgm->throttle_timers,
4a2fec
-                         blk_get_aio_context(blk),
4a2fec
+                         tgm->aio_context,
4a2fec
                          tg->clock_type,
4a2fec
                          read_timer_cb,
4a2fec
                          write_timer_cb,
4a2fec
-                         blk);
4a2fec
+                         tgm);
4a2fec
 
4a2fec
     qemu_mutex_unlock(&tg->lock);
4a2fec
 }
4a2fec
@@ -559,6 +554,21 @@ void throttle_group_unregister_tgm(ThrottleGroupMember *tgm)
4a2fec
     tgm->throttle_state = NULL;
4a2fec
 }
4a2fec
 
4a2fec
+void throttle_group_attach_aio_context(ThrottleGroupMember *tgm,
4a2fec
+                                       AioContext *new_context)
4a2fec
+{
4a2fec
+    ThrottleTimers *tt = &tgm->throttle_timers;
4a2fec
+    throttle_timers_attach_aio_context(tt, new_context);
4a2fec
+    tgm->aio_context = new_context;
4a2fec
+}
4a2fec
+
4a2fec
+void throttle_group_detach_aio_context(ThrottleGroupMember *tgm)
4a2fec
+{
4a2fec
+    ThrottleTimers *tt = &tgm->throttle_timers;
4a2fec
+    throttle_timers_detach_aio_context(tt);
4a2fec
+    tgm->aio_context = NULL;
4a2fec
+}
4a2fec
+
4a2fec
 static void throttle_groups_init(void)
4a2fec
 {
4a2fec
     qemu_mutex_init(&throttle_groups_lock);
4a2fec
diff --git a/include/block/throttle-groups.h b/include/block/throttle-groups.h
4a2fec
index 1a6bcda..a0f27ca 100644
4a2fec
--- a/include/block/throttle-groups.h
4a2fec
+++ b/include/block/throttle-groups.h
4a2fec
@@ -33,6 +33,7 @@
4a2fec
  */
4a2fec
 
4a2fec
 typedef struct ThrottleGroupMember {
4a2fec
+    AioContext   *aio_context;
4a2fec
     /* throttled_reqs_lock protects the CoQueues for throttled requests.  */
4a2fec
     CoMutex      throttled_reqs_lock;
4a2fec
     CoQueue      throttled_reqs[2];
4a2fec
@@ -61,12 +62,16 @@ void throttle_group_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
4a2fec
 void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
4a2fec
 
4a2fec
 void throttle_group_register_tgm(ThrottleGroupMember *tgm,
4a2fec
-                                const char *groupname);
4a2fec
+                                const char *groupname,
4a2fec
+                                AioContext *ctx);
4a2fec
 void throttle_group_unregister_tgm(ThrottleGroupMember *tgm);
4a2fec
 void throttle_group_restart_tgm(ThrottleGroupMember *tgm);
4a2fec
 
4a2fec
 void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm,
4a2fec
                                                         unsigned int bytes,
4a2fec
                                                         bool is_write);
4a2fec
+void throttle_group_attach_aio_context(ThrottleGroupMember *tgm,
4a2fec
+                                       AioContext *new_context);
4a2fec
+void throttle_group_detach_aio_context(ThrottleGroupMember *tgm);
4a2fec
 
4a2fec
 #endif
4a2fec
diff --git a/tests/test-throttle.c b/tests/test-throttle.c
4a2fec
index 6e6d926..57cf5ba 100644
4a2fec
--- a/tests/test-throttle.c
4a2fec
+++ b/tests/test-throttle.c
4a2fec
@@ -24,8 +24,9 @@
4a2fec
 static AioContext     *ctx;
4a2fec
 static LeakyBucket    bkt;
4a2fec
 static ThrottleConfig cfg;
4a2fec
+static ThrottleGroupMember tgm;
4a2fec
 static ThrottleState  ts;
4a2fec
-static ThrottleTimers tt;
4a2fec
+static ThrottleTimers *tt;
4a2fec
 
4a2fec
 /* useful function */
4a2fec
 static bool double_cmp(double x, double y)
4a2fec
@@ -153,19 +154,21 @@ static void test_init(void)
4a2fec
 {
4a2fec
     int i;
4a2fec
 
4a2fec
+    tt = &tgm.throttle_timers;
4a2fec
+
4a2fec
     /* fill the structures with crap */
4a2fec
     memset(&ts, 1, sizeof(ts));
4a2fec
-    memset(&tt, 1, sizeof(tt));
4a2fec
+    memset(tt, 1, sizeof(*tt));
4a2fec
 
4a2fec
     /* init structures */
4a2fec
     throttle_init(&ts);
4a2fec
-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
+    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
                          read_timer_cb, write_timer_cb, &ts);
4a2fec
 
4a2fec
     /* check initialized fields */
4a2fec
-    g_assert(tt.clock_type == QEMU_CLOCK_VIRTUAL);
4a2fec
-    g_assert(tt.timers[0]);
4a2fec
-    g_assert(tt.timers[1]);
4a2fec
+    g_assert(tt->clock_type == QEMU_CLOCK_VIRTUAL);
4a2fec
+    g_assert(tt->timers[0]);
4a2fec
+    g_assert(tt->timers[1]);
4a2fec
 
4a2fec
     /* check other fields where cleared */
4a2fec
     g_assert(!ts.previous_leak);
4a2fec
@@ -176,18 +179,18 @@ static void test_init(void)
4a2fec
         g_assert(!ts.cfg.buckets[i].level);
4a2fec
     }
4a2fec
 
4a2fec
-    throttle_timers_destroy(&tt;;
4a2fec
+    throttle_timers_destroy(tt);
4a2fec
 }
4a2fec
 
4a2fec
 static void test_destroy(void)
4a2fec
 {
4a2fec
     int i;
4a2fec
     throttle_init(&ts);
4a2fec
-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
+    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
                          read_timer_cb, write_timer_cb, &ts);
4a2fec
-    throttle_timers_destroy(&tt;;
4a2fec
+    throttle_timers_destroy(tt);
4a2fec
     for (i = 0; i < 2; i++) {
4a2fec
-        g_assert(!tt.timers[i]);
4a2fec
+        g_assert(!tt->timers[i]);
4a2fec
     }
4a2fec
 }
4a2fec
 
4a2fec
@@ -224,7 +227,7 @@ static void test_config_functions(void)
4a2fec
     orig_cfg.op_size = 1;
4a2fec
 
4a2fec
     throttle_init(&ts);
4a2fec
-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
+    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
                          read_timer_cb, write_timer_cb, &ts);
4a2fec
     /* structure reset by throttle_init previous_leak should be null */
4a2fec
     g_assert(!ts.previous_leak);
4a2fec
@@ -236,7 +239,7 @@ static void test_config_functions(void)
4a2fec
     /* get back the fixed configuration */
4a2fec
     throttle_get_config(&ts, &final_cfg);
4a2fec
 
4a2fec
-    throttle_timers_destroy(&tt;;
4a2fec
+    throttle_timers_destroy(tt);
4a2fec
 
4a2fec
     g_assert(final_cfg.buckets[THROTTLE_BPS_TOTAL].avg == 153);
4a2fec
     g_assert(final_cfg.buckets[THROTTLE_BPS_READ].avg  == 56);
4a2fec
@@ -417,45 +420,45 @@ static void test_have_timer(void)
4a2fec
 {
4a2fec
     /* zero structures */
4a2fec
     memset(&ts, 0, sizeof(ts));
4a2fec
-    memset(&tt, 0, sizeof(tt));
4a2fec
+    memset(tt, 0, sizeof(*tt));
4a2fec
 
4a2fec
     /* no timer set should return false */
4a2fec
-    g_assert(!throttle_timers_are_initialized(&tt));
4a2fec
+    g_assert(!throttle_timers_are_initialized(tt));
4a2fec
 
4a2fec
     /* init structures */
4a2fec
     throttle_init(&ts);
4a2fec
-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
+    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
                          read_timer_cb, write_timer_cb, &ts);
4a2fec
 
4a2fec
     /* timer set by init should return true */
4a2fec
-    g_assert(throttle_timers_are_initialized(&tt));
4a2fec
+    g_assert(throttle_timers_are_initialized(tt));
4a2fec
 
4a2fec
-    throttle_timers_destroy(&tt;;
4a2fec
+    throttle_timers_destroy(tt);
4a2fec
 }
4a2fec
 
4a2fec
 static void test_detach_attach(void)
4a2fec
 {
4a2fec
     /* zero structures */
4a2fec
     memset(&ts, 0, sizeof(ts));
4a2fec
-    memset(&tt, 0, sizeof(tt));
4a2fec
+    memset(tt, 0, sizeof(*tt));
4a2fec
 
4a2fec
     /* init the structure */
4a2fec
     throttle_init(&ts);
4a2fec
-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
+    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
                          read_timer_cb, write_timer_cb, &ts);
4a2fec
 
4a2fec
     /* timer set by init should return true */
4a2fec
-    g_assert(throttle_timers_are_initialized(&tt));
4a2fec
+    g_assert(throttle_timers_are_initialized(tt));
4a2fec
 
4a2fec
     /* timer should no longer exist after detaching */
4a2fec
-    throttle_timers_detach_aio_context(&tt;;
4a2fec
-    g_assert(!throttle_timers_are_initialized(&tt));
4a2fec
+    throttle_timers_detach_aio_context(tt);
4a2fec
+    g_assert(!throttle_timers_are_initialized(tt));
4a2fec
 
4a2fec
     /* timer should exist again after attaching */
4a2fec
-    throttle_timers_attach_aio_context(&tt, ctx);
4a2fec
-    g_assert(throttle_timers_are_initialized(&tt));
4a2fec
+    throttle_timers_attach_aio_context(tt, ctx);
4a2fec
+    g_assert(throttle_timers_are_initialized(tt));
4a2fec
 
4a2fec
-    throttle_timers_destroy(&tt;;
4a2fec
+    throttle_timers_destroy(tt);
4a2fec
 }
4a2fec
 
4a2fec
 static bool do_test_accounting(bool is_ops, /* are we testing bps or ops */
4a2fec
@@ -484,7 +487,7 @@ static bool do_test_accounting(bool is_ops, /* are we testing bps or ops */
4a2fec
     cfg.op_size = op_size;
4a2fec
 
4a2fec
     throttle_init(&ts);
4a2fec
-    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
+    throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
4a2fec
                          read_timer_cb, write_timer_cb, &ts);
4a2fec
     throttle_config(&ts, QEMU_CLOCK_VIRTUAL, &cfg;;
4a2fec
 
4a2fec
@@ -511,7 +514,7 @@ static bool do_test_accounting(bool is_ops, /* are we testing bps or ops */
4a2fec
         return false;
4a2fec
     }
4a2fec
 
4a2fec
-    throttle_timers_destroy(&tt;;
4a2fec
+    throttle_timers_destroy(tt);
4a2fec
 
4a2fec
     return true;
4a2fec
 }
4a2fec
@@ -611,9 +614,9 @@ static void test_groups(void)
4a2fec
     g_assert(tgm2->throttle_state == NULL);
4a2fec
     g_assert(tgm3->throttle_state == NULL);
4a2fec
 
4a2fec
-    throttle_group_register_tgm(tgm1, "bar");
4a2fec
-    throttle_group_register_tgm(tgm2, "foo");
4a2fec
-    throttle_group_register_tgm(tgm3, "bar");
4a2fec
+    throttle_group_register_tgm(tgm1, "bar", blk_get_aio_context(blk1));
4a2fec
+    throttle_group_register_tgm(tgm2, "foo", blk_get_aio_context(blk2));
4a2fec
+    throttle_group_register_tgm(tgm3, "bar", blk_get_aio_context(blk3));
4a2fec
 
4a2fec
     g_assert(tgm1->throttle_state != NULL);
4a2fec
     g_assert(tgm2->throttle_state != NULL);
4a2fec
-- 
4a2fec
1.8.3.1
4a2fec