From nobody Thu May 2 01:56:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1517926195308254.31577057783488; Tue, 6 Feb 2018 06:09:55 -0800 (PST) Received: from localhost ([::1]:47938 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej3wU-0004mu-H2 for importer@patchew.org; Tue, 06 Feb 2018 09:09:50 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43904) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ej3uY-0003QO-9i for qemu-devel@nongnu.org; Tue, 06 Feb 2018 09:07:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ej3uS-0004Sm-Vl for qemu-devel@nongnu.org; Tue, 06 Feb 2018 09:07:50 -0500 Received: from [45.249.212.35] (port=33460 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ej3uS-0004Ql-BZ for qemu-devel@nongnu.org; Tue, 06 Feb 2018 09:07:44 -0500 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id E6AD12AE4B23D; Tue, 6 Feb 2018 22:07:38 +0800 (CST) Received: from localhost (10.177.18.62) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.361.1; Tue, 6 Feb 2018 22:07:31 +0800 From: Gonglei To: Date: Tue, 6 Feb 2018 22:07:19 +0800 Message-ID: <1517926039-86416-1-git-send-email-arei.gonglei@huawei.com> X-Mailer: git-send-email 2.8.2.windows.1 MIME-Version: 1.0 X-Originating-IP: [10.177.18.62] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 45.249.212.35 Subject: [Qemu-devel] [PATCH v2] rtc: placing RTC memory region outside BQL X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: pbonzini@redhat.com, Gonglei , weidong.huang@huawei.com, peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" As windows guest use rtc as the clock source device, and access rtc frequently. Let's move the rtc memory region outside BQL to decrease overhead for windows guests. Meanwhile, adding a new lock to avoid different vCPUs access the RTC together. $ cat strace_c.sh strace -tt -p $1 -c -o result_$1.log & sleep $2 pid=3D$(pidof strace) kill $pid cat result_$1.log Before appling this change: $ ./strace_c.sh 10528 30 % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 93.87 0.119070 30 4000 ppoll 3.27 0.004148 2 2038 ioctl 2.66 0.003370 2 2014 futex 0.09 0.000113 1 106 read 0.09 0.000109 1 104 io_getevents 0.02 0.000029 1 30 poll 0.00 0.000000 0 1 write ------ ----------- ----------- --------- --------- ---------------- 100.00 0.126839 8293 total After appling the change: $ ./strace_c.sh 23829 30 % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 92.86 0.067441 16 4094 ppoll 4.85 0.003522 2 2136 ioctl 1.17 0.000850 4 189 futex 0.54 0.000395 2 202 read 0.52 0.000379 2 202 io_getevents 0.05 0.000037 1 30 poll ------ ----------- ----------- --------- --------- ---------------- 100.00 0.072624 6853 total The futex call number decreases ~90.6% on an idle windows 7 guest. Signed-off-by: Gonglei --- v2->v1: a)Adding a new lock to avoid different vCPUs access the RTC together. [Paolo] b)Taking the BQL before raising the outbound IRQ line. [Peter] c)Don't hold BQL if it was holden. [Peter] hw/timer/mc146818rtc.c | 55 ++++++++++++++++++++++++++++++++++++++++++----= ---- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 35a05a6..f0a2a62 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -85,6 +85,7 @@ typedef struct RTCState { uint16_t irq_reinject_on_ack_count; uint32_t irq_coalesced; uint32_t period; + QemuMutex rtc_lock; QEMUTimer *coalesced_timer; Notifier clock_reset_notifier; LostTickPolicy lost_tick_policy; @@ -125,6 +126,36 @@ static void rtc_coalesced_timer_update(RTCState *s) } } =20 +static void rtc_rasie_irq(RTCState *s) +{ + bool unlocked =3D !qemu_mutex_iothread_locked(); + + if (unlocked) { + qemu_mutex_lock_iothread(); + } + + qemu_irq_raise(s->irq); + + if (unlocked) { + qemu_mutex_unlock_iothread(); + } +} + +static void rtc_lower_irq(RTCState *s) +{ + bool unlocked =3D !qemu_mutex_iothread_locked(); + + if (unlocked) { + qemu_mutex_lock_iothread(); + } + + qemu_irq_lower(s->irq); + + if (unlocked) { + qemu_mutex_unlock_iothread(); + } +} + static QLIST_HEAD(, RTCState) rtc_devices =3D QLIST_HEAD_INITIALIZER(rtc_devices); =20 @@ -141,7 +172,7 @@ void qmp_rtc_reset_reinjection(Error **errp) static bool rtc_policy_slew_deliver_irq(RTCState *s) { apic_reset_irq_delivered(); - qemu_irq_raise(s->irq); + rtc_rasie_irq(s); return apic_get_irq_delivered(); } =20 @@ -277,8 +308,9 @@ static void rtc_periodic_timer(void *opaque) DPRINTF_C("cmos: coalesced irqs increased to %d\n", s->irq_coalesced); } - } else - qemu_irq_raise(s->irq); + } else { + rtc_rasie_irq(s); + } } } =20 @@ -459,7 +491,7 @@ static void rtc_update_timer(void *opaque) s->cmos_data[RTC_REG_C] |=3D irqs; if ((new_irqs & s->cmos_data[RTC_REG_B]) !=3D 0) { s->cmos_data[RTC_REG_C] |=3D REG_C_IRQF; - qemu_irq_raise(s->irq); + rtc_rasie_irq(s); } check_update_timer(s); } @@ -471,6 +503,7 @@ static void cmos_ioport_write(void *opaque, hwaddr addr, uint32_t old_period; bool update_periodic_timer; =20 + qemu_mutex_lock(&s->rtc_lock); if ((addr & 1) =3D=3D 0) { s->cmos_index =3D data & 0x7f; } else { @@ -560,10 +593,10 @@ static void cmos_ioport_write(void *opaque, hwaddr ad= dr, * becomes enabled, raise an interrupt immediately. */ if (data & s->cmos_data[RTC_REG_C] & REG_C_MASK) { s->cmos_data[RTC_REG_C] |=3D REG_C_IRQF; - qemu_irq_raise(s->irq); + rtc_rasie_irq(s); } else { s->cmos_data[RTC_REG_C] &=3D ~REG_C_IRQF; - qemu_irq_lower(s->irq); + rtc_lower_irq(s); } s->cmos_data[RTC_REG_B] =3D data; =20 @@ -583,6 +616,7 @@ static void cmos_ioport_write(void *opaque, hwaddr addr, break; } } + qemu_mutex_unlock(&s->rtc_lock); } =20 static inline int rtc_to_bcd(RTCState *s, int a) @@ -710,6 +744,7 @@ static uint64_t cmos_ioport_read(void *opaque, hwaddr a= ddr, if ((addr & 1) =3D=3D 0) { return 0xff; } else { + qemu_mutex_lock(&s->rtc_lock); switch(s->cmos_index) { case RTC_IBM_PS2_CENTURY_BYTE: s->cmos_index =3D RTC_CENTURY; @@ -737,7 +772,7 @@ static uint64_t cmos_ioport_read(void *opaque, hwaddr a= ddr, break; case RTC_REG_C: ret =3D s->cmos_data[s->cmos_index]; - qemu_irq_lower(s->irq); + rtc_lower_irq(s); s->cmos_data[RTC_REG_C] =3D 0x00; if (ret & (REG_C_UF | REG_C_AF)) { check_update_timer(s); @@ -762,6 +797,7 @@ static uint64_t cmos_ioport_read(void *opaque, hwaddr a= ddr, } CMOS_DPRINTF("cmos: read index=3D0x%02x val=3D0x%02x\n", s->cmos_index, ret); + qemu_mutex_unlock(&s->rtc_lock); return ret; } } @@ -909,7 +945,7 @@ static void rtc_reset(void *opaque) s->cmos_data[RTC_REG_C] &=3D ~(REG_C_UF | REG_C_IRQF | REG_C_PF | REG_= C_AF); check_update_timer(s); =20 - qemu_irq_lower(s->irq); + rtc_lower_irq(s); =20 if (s->lost_tick_policy =3D=3D LOST_TICK_POLICY_SLEW) { s->irq_coalesced =3D 0; @@ -960,6 +996,8 @@ static void rtc_realizefn(DeviceState *dev, Error **err= p) =20 rtc_set_date_from_host(isadev); =20 + qemu_mutex_init(&s->rtc_lock); + switch (s->lost_tick_policy) { #ifdef TARGET_I386 case LOST_TICK_POLICY_SLEW: @@ -986,6 +1024,7 @@ static void rtc_realizefn(DeviceState *dev, Error **er= rp) qemu_register_suspend_notifier(&s->suspend_notifier); =20 memory_region_init_io(&s->io, OBJECT(s), &cmos_ops, s, "rtc", 2); + memory_region_clear_global_locking(&s->io); isa_register_ioport(isadev, &s->io, base); =20 qdev_set_legacy_instance_id(dev, base, 3); --=20 1.8.3.1