Received: by 10.223.185.116 with SMTP id b49csp2036757wrg; Sun, 4 Mar 2018 16:39:25 -0800 (PST) X-Google-Smtp-Source: AG47ELvlrbzowwYf55tPSbi+Liyax5CmtpyDP+452oVrlPK7Gm1OnFm7QR0g+lnp0sVeqPPwOMXr X-Received: by 2002:a17:902:6ac2:: with SMTP id i2-v6mr11220642plt.368.1520210364879; Sun, 04 Mar 2018 16:39:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520210364; cv=none; d=google.com; s=arc-20160816; b=vZG93vlKTGaFAzOnfKVXr6yztJUFfINEXm9s3grkV97YgDHv6sfmZN09/34aDCOzih RtGLdtaEG08Aqw3aosmL5joqaiWkRef6OLGevN+myjO5km1g9hlwhOk0g+hmk3+wAsXF NHVRKl4Uy7JjC9lH95xCeB1Z+s9JhIyqwF7NMoCw+5VeiFiuYbvbIizImtoqRWEiGOmN GWIv7FbFbaDz+3LvGrfBWjoib5PAxZ0GIuMz8/wr76iq6SeWlDncXpcWmhnYLgWNE90r fv5PbdwPYwm6EWHRvGikIdIsLwwlM461f7DYw85qhPVsXq8P4bB6TuVEcSAZKN9PwNIq 5bZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=i+n/+G18VE5i6RUP07unCAgOBLmwPgroXhk6WnG/alc=; b=JmiltGemSIFBVT2j/21a37Af6ScIJjsWh/bcN4dwgtKtCqlO3eUjkQfB/xwM7CVGsd AoDyECM2D5zpCBiJyZmFzi9wwfeD8QwKUWCPxNb2kFM7y7zvAEzAKTi+Kx7hu5/CCguw zhHRzlSdMNCw9gWK3S/5nTgIkc/eP/aagMPP9WxygzS3s2HzXrJ5bxTNwER1F/rrho2c EefTQ6z0U6xBT/vZXm+U9+m4mC0D+16w4a7SWmANlIq+es4WCnOOOWZHfqbdUEwjYsCv rvhC/JhzWtY3iPj4GhjMK6LTEKzmXX5s2uzj+GHSPaEHtQ59hpHe4oGmGyoDL9zPtk7+ X8DA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=X8WXe+tn; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z8-v6si8439899plh.379.2018.03.04.16.38.56; Sun, 04 Mar 2018 16:39:24 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=X8WXe+tn; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932538AbeCEAPn (ORCPT + 99 others); Sun, 4 Mar 2018 19:15:43 -0500 Received: from mail-pf0-f196.google.com ([209.85.192.196]:42707 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932350AbeCEAPk (ORCPT ); Sun, 4 Mar 2018 19:15:40 -0500 Received: by mail-pf0-f196.google.com with SMTP id a16so6472774pfn.9; Sun, 04 Mar 2018 16:15:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=i+n/+G18VE5i6RUP07unCAgOBLmwPgroXhk6WnG/alc=; b=X8WXe+tnI9rYiYuvjxWxjhLP+PM6HoV6mYLn88FJFydERHr/nsXsXimkSPNVSv3a0Y rVqP1tSKSt6EMk/jTrbmqXRP1m4pMYFHyHhmxih210q2DxqDbGvWsAcIOEn/RGqAtykS DUjjNH2DWBqLfsNbKnWfA6TgnLCvkYqv6a6XL9RUhZxKcCb8HJJVQtdzYNRAo5exwIVE u65wPEZpikYxppgB2v9ymbMrnhf1yI14rXgOQ9MRgTibJX8+ncBX/2u5W8trPZWKNIOX mjl9cVgm5Izry4WDpzaicqnGXK3D4MDQxqtkYZyxO2pGYb3BEYqn4oOv68dkfRZYH/pK Fciw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=i+n/+G18VE5i6RUP07unCAgOBLmwPgroXhk6WnG/alc=; b=nuxIIuHXV/W/eFko38B4wetXBy2P8o+9WIIH4Iqkkj5rBsK+v9dE2ESNk9J3J78Duw kviKbwmvwFHQ6SGMthvdF0ULMevjBhcho0fLDzeyxdzACurL242ZeqVczTJ9Zl9V/PJj 582Ry5bLuGmVUp3wLhCvPm6cINR3Jt4fHWnCFDW74C5uR6FkQbvK+kNNDpcEbL8SMrQ+ Ew6Z18tMz/xNfc4cn685KfZ9SR/ZDU4ZdLLcpmnUiEZGtflqWdk9gS26492jTC9KnmrJ l5ezYSevdQusrIxxhGawG0ygizIfbQKgQcB7NM0v/TuHnhxQ9MYKtvkK6yyRhHHh1iq3 1Flw== X-Gm-Message-State: APf1xPBgsmB43dh4+jb87yOp2348GaJQ55AeTb2zDvs1UNhtqA5Ja5PU LTtIeO1zuOFPuEN3nOL+lrA= X-Received: by 10.99.120.193 with SMTP id t184mr10932108pgc.348.1520208939481; Sun, 04 Mar 2018 16:15:39 -0800 (PST) Received: from localhost.localdomain (c-73-93-215-6.hsd1.ca.comcast.net. [73.93.215.6]) by smtp.gmail.com with ESMTPSA id c7sm23113891pfg.36.2018.03.04.16.15.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 04 Mar 2018 16:15:38 -0800 (PST) From: frowand.list@gmail.com To: Rob Herring , cpandya@codeaurora.org Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 3/3] of: add early boot allocation of of_find_node_by_phandle() cache Date: Sun, 4 Mar 2018 16:14:49 -0800 Message-Id: <1520208889-3908-4-git-send-email-frowand.list@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1520208889-3908-1-git-send-email-frowand.list@gmail.com> References: <1520208889-3908-1-git-send-email-frowand.list@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Frank Rowand The initial implementation of the of_find_node_by_phandle() cache allocates the cache using kcalloc(). Add an early boot allocation of the cache so it will be usable during early boot. Switch over to the kcalloc() based cache once normal memory allocation becomes available. Signed-off-by: Frank Rowand --- Changes from v4: - Add checks for memblock_virt_alloc() returning zero. Changes from previous versions: - no changes Version 5 adds checks for memblock_virt_alloc() returning zero. kernel test robot reports 10 out of 10 boot failures on qemu-system-x86_64 with "[PATCH v4 2/2] of: add early boot allocation of of_find_node_by_phandle() cache" applied. The failure appears to me to be due to memblock_virt_alloc() returning zero. kernel BUG at arch/x86/mm/physaddr.c:27 invalid opcode: 0000 [#1] PREEMPT PTI CPU: 0 PID: 1 Comm: swapper Not tainted 4.16.0-rc1-00008-gb013aa4 #1 RIP: 0010:__phys_addr+0x39/0x50 RSP: 0000:ffff880018de3ee0 EFLAGS: 00010087 RAX: 0000780000000000 RBX: 0000000000000001 RCX: 0000000000000002 RDX: 0000000080000000 RSI: ffffffff82e77239 RDI: 0000000000000000 RBP: ffff880018de3ee0 R08: 0000000000000000 R09: 0000000000000001 R10: 00000000000029cb R11: 63561fc2891644ad R12: 0000000000000286 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffffffff8309b000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000ffffffff CR3: 0000000003074000 CR4: 00000000000006f0 Call Trace: of_core_init+0x30/0x21f driver_init+0x36/0x38 kernel_init_freeable+0x82/0x19f ? rest_init+0x220/0x220 kernel_init+0xe/0x100 ret_from_fork+0x24/0x30 I'm not conversent in the x86 dialect of assembly, but it looks like phandle_cache has the value zero, when calling __phys_addr(): ==== the call from of_core_init() to __pa(phandle_cache) aka __physaddr(): 186 size = (phandle_cache_mask + 1) * sizeof(*phandle_cache); 0xffffffff83334d35 <+27>: mov 0x1771e1d(%rip),%eax # 0xffffffff84aa6b58 0xffffffff83334d42 <+40>: lea 0x1(%rax),%r12d 0xffffffff83334d4b <+49>: shl $0x3,%r12 187 memblock_free(__pa(phandle_cache), size); 0xffffffff83334d3b <+33>: mov 0x1771e1e(%rip),%rdi # 0xffffffff84aa6b60 0xffffffff83334d46 <+44>: callq 0xffffffff81049ad0 <__phys_addr> 0xffffffff83334d4f <+53>: mov %rax,%rdi 0xffffffff83334d52 <+56>: mov %r12,%rsi 0xffffffff83334d55 <+59>: callq 0xffffffff8334e45b 188 phandle_cache = NULL; 0xffffffff83334d64 <+74>: movq $0x0,0x1771df1(%rip) # 0xffffffff84aa6b60 ==== __pa(): (gdb) disass /m __phys_addr Dump of assembler code for function __phys_addr: 15 { 0xffffffff81049ad0 <+0>: callq 0xffffffff822018e0 <__fentry__> 0xffffffff81049ad5 <+5>: push %rbp 0xffffffff81049ade <+14>: mov %rsp,%rbp 16 unsigned long y = x - __START_KERNEL_map; 0xffffffff81049ad6 <+6>: mov $0x80000000,%eax 17 18 /* use the carry flag to determine if x was < __START_KERNEL_map */ 19 if (unlikely(x > y)) { 0xffffffff81049adb <+11>: add %rdi,%rax 0xffffffff81049ae1 <+17>: mov %rax,%rdx 0xffffffff81049ae4 <+20>: jae 0xffffffff81049af8 <__phys_addr+40> 20 x = y + phys_base; 0xffffffff81049ae6 <+22>: add 0x1e30523(%rip),%rax # 0xffffffff82e7a010 21 22 VIRTUAL_BUG_ON(y >= KERNEL_IMAGE_SIZE); 0xffffffff81049aed <+29>: cmp $0x1fffffff,%rdx 0xffffffff81049af4 <+36>: jbe 0xffffffff81049b1e <__phys_addr+78> 0xffffffff81049af6 <+38>: ud2 23 } else { 24 x = y + (__START_KERNEL_map - PAGE_OFFSET); 0xffffffff81049af8 <+40>: movabs $0x780000000000,%rax 0xffffffff81049b02 <+50>: add %rdi,%rax 25 26 /* carry flag will be set if starting x was >= PAGE_OFFSET */ 27 VIRTUAL_BUG_ON((x > y) || !phys_addr_valid(x)); 0xffffffff81049b05 <+53>: cmp %rax,%rdx 0xffffffff81049b08 <+56>: jb 0xffffffff81049b1c <__phys_addr+76> 0xffffffff81049b17 <+71>: test %rdx,%rdx 0xffffffff81049b1a <+74>: je 0xffffffff81049b1e <__phys_addr+78> 0xffffffff81049b1c <+76>: ud2 28 } 29 30 return x; 31 } 0xffffffff81049b1e <+78>: pop %rbp 0xffffffff81049b1f <+79>: retq drivers/of/base.c | 38 ++++++++++++++++++++++++++++++++++++++ drivers/of/fdt.c | 2 ++ drivers/of/of_private.h | 2 ++ 3 files changed, 42 insertions(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index e71d157d7149..48714d8e0bc9 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -16,9 +16,11 @@ #define pr_fmt(fmt) "OF: " fmt +#include #include #include #include +#include #include #include #include @@ -134,6 +136,32 @@ static void of_populate_phandle_cache(void) raw_spin_unlock_irqrestore(&devtree_lock, flags); } +void __init of_populate_phandle_cache_early(void) +{ + u32 cache_entries; + struct device_node *np; + u32 phandles = 0; + size_t size; + + for_each_of_allnodes(np) + if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL) + phandles++; + + cache_entries = roundup_pow_of_two(phandles); + phandle_cache_mask = cache_entries - 1; + + size = cache_entries * sizeof(*phandle_cache); + phandle_cache = memblock_virt_alloc(size, 4); + if (!phandle_cache) + return; + + memset(phandle_cache, 0, size); + + for_each_of_allnodes(np) + if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL) + phandle_cache[np->phandle & phandle_cache_mask] = np; +} + #ifndef CONFIG_MODULES static int __init of_free_phandle_cache(void) { @@ -153,7 +181,17 @@ static int __init of_free_phandle_cache(void) void __init of_core_init(void) { + unsigned long flags; struct device_node *np; + phys_addr_t size; + + if (phandle_cache) { + raw_spin_lock_irqsave(&devtree_lock, flags); + size = (phandle_cache_mask + 1) * sizeof(*phandle_cache); + memblock_free(__pa(phandle_cache), size); + phandle_cache = NULL; + raw_spin_unlock_irqrestore(&devtree_lock, flags); + } of_populate_phandle_cache(); diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 84aa9d676375..cb320df23f26 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -1264,6 +1264,8 @@ void __init unflatten_device_tree(void) of_alias_scan(early_init_dt_alloc_memory_arch); unittest_unflatten_overlay_base(); + + of_populate_phandle_cache_early(); } /** diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index fa70650136b4..6720448c84cc 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -134,6 +134,8 @@ extern void __of_sysfs_remove_bin_file(struct device_node *np, /* illegal phandle value (set when unresolved) */ #define OF_PHANDLE_ILLEGAL 0xdeadbeef +extern void __init of_populate_phandle_cache_early(void); + /* iterators for transactions, used for overlays */ /* forward iterator */ #define for_each_transaction_entry(_oft, _te) \ -- Frank Rowand