From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59127) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z0tLz-0001e3-6a for qemu-devel@nongnu.org; Fri, 05 Jun 2015 11:16:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z0tLy-0007Gw-01 for qemu-devel@nongnu.org; Fri, 05 Jun 2015 11:16:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55763) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z0tLx-0007GL-RY for qemu-devel@nongnu.org; Fri, 05 Jun 2015 11:16:13 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 8FD8F2F6683 for ; Fri, 5 Jun 2015 15:16:13 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-29.ams2.redhat.com [10.36.112.29]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t55FG4kG012808 for ; Fri, 5 Jun 2015 11:16:12 -0400 From: Paolo Bonzini Date: Fri, 5 Jun 2015 17:15:05 +0200 Message-Id: <1433517363-32335-5-git-send-email-pbonzini@redhat.com> In-Reply-To: <1433517363-32335-1-git-send-email-pbonzini@redhat.com> References: <1433517363-32335-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PULL 04/62] exec: optimize phys_page_set_level List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org phys_page_set_level is writing zeroes to a struct that has just been filled in by phys_map_node_alloc. Instead, tell phys_map_node_alloc whether to fill in the page "as a leaf" or "as a non-leaf". memcpy is faster than struct assignment, which copies each bitfield individually. A compiler bug (https://gcc.gnu.org/PR66391), and small memcpys like this one are special-cased anyway, and optimized to a register move, so just use the memcpy. This cuts the cost of phys_page_set_level from 25% to 5% when booting qboot. Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini --- exec.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/exec.c b/exec.c index e19ab22..fc8d05d 100644 --- a/exec.c +++ b/exec.c @@ -173,17 +173,22 @@ static void phys_map_node_reserve(PhysPageMap *map, unsigned nodes) } } -static uint32_t phys_map_node_alloc(PhysPageMap *map) +static uint32_t phys_map_node_alloc(PhysPageMap *map, bool leaf) { unsigned i; uint32_t ret; + PhysPageEntry e; + PhysPageEntry *p; ret = map->nodes_nb++; + p = map->nodes[ret]; assert(ret != PHYS_MAP_NODE_NIL); assert(ret != map->nodes_nb_alloc); + + e.skip = leaf ? 0 : 1; + e.ptr = leaf ? PHYS_SECTION_UNASSIGNED : PHYS_MAP_NODE_NIL; for (i = 0; i < P_L2_SIZE; ++i) { - map->nodes[ret][i].skip = 1; - map->nodes[ret][i].ptr = PHYS_MAP_NODE_NIL; + memcpy(&p[i], &e, sizeof(e)); } return ret; } @@ -193,21 +198,12 @@ static void phys_page_set_level(PhysPageMap *map, PhysPageEntry *lp, int level) { PhysPageEntry *p; - int i; hwaddr step = (hwaddr)1 << (level * P_L2_BITS); if (lp->skip && lp->ptr == PHYS_MAP_NODE_NIL) { - lp->ptr = phys_map_node_alloc(map); - p = map->nodes[lp->ptr]; - if (level == 0) { - for (i = 0; i < P_L2_SIZE; i++) { - p[i].skip = 0; - p[i].ptr = PHYS_SECTION_UNASSIGNED; - } - } - } else { - p = map->nodes[lp->ptr]; + lp->ptr = phys_map_node_alloc(map, level == 0); } + p = map->nodes[lp->ptr]; lp = &p[(*index >> (level * P_L2_BITS)) & (P_L2_SIZE - 1)]; while (*nb && lp < &p[P_L2_SIZE]) { -- 2.4.1