From patchwork Thu Nov 29 17:12:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 152423 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp2634718ljp; Thu, 29 Nov 2018 09:13:30 -0800 (PST) X-Google-Smtp-Source: AFSGD/UAybau6Rs6CJaHgj1XCJVbtMI5eIgygCP9XR3DaavOMTODFA4jl790gfWCHVcfPLh3vnoi X-Received: by 2002:a17:902:8f83:: with SMTP id z3mr2207807plo.328.1543511609979; Thu, 29 Nov 2018 09:13:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543511609; cv=none; d=google.com; s=arc-20160816; b=A3Z7N470SWmJQO8YPvHFML6lNr4fTbHS4reAOwh5QHXN9cfOl/SJIF+eCvQ+7avDUc hbeoRhWaPLHnbEv3iDeiZR9Si0mzexDJl/EPili/orFHJ8TjDGNFgXX6+6rCFGa3Ease 0k8Cq0eh6cTIy9Qda1HrZZc45YZLzf1UPreKtBKleQ+eBMb+ETgpxf0xYIgDaqxQV347 7ZIiOQzt2FbEnTL7v/QtdFL/QUUAP2VU0xrCLA2vq0MYSVGK/dDQ2qioR+1B49tq5Wn2 OlRBlRwzV1djo9G5vD+3SYvwRrD+Mazw+HdRMZnsjy17QNqSI94C3T+j+zRFIeid60zz rKCA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Zf26VLC73KBeOMRN+TciYckaN/0BTjlAJnyTuYhXxyU=; b=D/fi6ORTEp7hjp1VJmT7n4Fu//kPNtW0Sw53JGs1KrhBVdvYo+FeHFXMlfXc3wqf2d cipkxXXWBRHMdfNsHjYcxxwH6O39zKVn2eKmupJltkgfbOrOAeqkwtROReoqk+DayRS8 h5/1Nk2X5CLvchTfpzdfDJ+j+y0Vaof7wtvju0c6kdf47py+DXyK35KEoBjdvlfDbOfs wPD4s01FVfvvyx4nZvU68ac0RgfxQiy26U/joMU6TpdKEBkefqdMhHjY6LNz4XPMmvj3 MLIw4qsYO5DPZiKsGozI2BTi0Ep5vxVwdXuUauLowTu/nxpwXqlNs3NaUTGWEV3t9P7i K7Bg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=anRe2fKf; 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=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w5si2660107pfl.279.2018.11.29.09.13.29; Thu, 29 Nov 2018 09:13:29 -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=@linaro.org header.s=google header.b=anRe2fKf; 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=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730729AbeK3ETc (ORCPT + 32 others); Thu, 29 Nov 2018 23:19:32 -0500 Received: from mail-wr1-f66.google.com ([209.85.221.66]:40473 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730634AbeK3ETK (ORCPT ); Thu, 29 Nov 2018 23:19:10 -0500 Received: by mail-wr1-f66.google.com with SMTP id p4so2674623wrt.7 for ; Thu, 29 Nov 2018 09:13:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Zf26VLC73KBeOMRN+TciYckaN/0BTjlAJnyTuYhXxyU=; b=anRe2fKfurgWjUShMpRaDkx3BLJlCKBVQ1II1d9aRyRnpxxlaZrmNwEvXXKWN8qFKR iEnqvs3yVLKmUanB444pieAbiBOvgRAszRNoulw96X2WVA8ghoeyTnNpUIAw5u+8LwTH +ULYQrOvH4vX2YYWHnLcoW3ddR8/2hwnWbmBg= 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:mime-version:content-transfer-encoding; bh=Zf26VLC73KBeOMRN+TciYckaN/0BTjlAJnyTuYhXxyU=; b=Vop0UNB+CvDKk0hWuSFzBUvSGYnbDAfXFCGNlcK4jN9GeM+GJX8AJkCjSzAPMO21t8 h282Fd4Zp2dPGISDQIu4oDPMrm8C34H7KLKWZKiyq31PVyB4FARuWx/x3AkZoYIThrA+ mSwf0z8ggNjvnm9QwxInW9/XAQgXtI1pzg33IFazNo6kqZdO6i/+TnVvn263/2FfI/Lu +bz2zwvqVFgtcuIPEEuGILO2hXTIdJBX2bFkVxtpMpfdR/ENhBygPcb90hVM0toA6wwD /lgO36AddsS0jM5QShggFSfHT/PB3UZXx5upnCB3s3C5xBQVWHzZ0865Lhqmc0IbZP0e JLBA== X-Gm-Message-State: AA+aEWbs591ZIia8a+dOJQYPcJAG8iaRDz3Fx3+lrSP+XFfrjpd6C3BY hW395rv+XOfND00kdfkdUldIvg== X-Received: by 2002:adf:9361:: with SMTP id 88mr2080952wro.204.1543511584259; Thu, 29 Nov 2018 09:13:04 -0800 (PST) Received: from harold.home ([2a01:cb1d:112:6f00:f070:d240:312e:9f99]) by smtp.gmail.com with ESMTPSA id y185sm1593882wmg.34.2018.11.29.09.13.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 29 Nov 2018 09:13:03 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, Andy Lutomirski , Arend van Spriel , Bhupesh Sharma , Borislav Petkov , Dave Hansen , Eric Snowberg , Hans de Goede , Joe Perches , Jon Hunter , Julien Thierry , Marc Zyngier , Nathan Chancellor , Peter Zijlstra , Sai Praneeth Prakhya , Sedat Dilek , YiFei Zhu Subject: [PATCH 10/11] efi: reduce the amount of memblock reservations for persistent allocations Date: Thu, 29 Nov 2018 18:12:29 +0100 Message-Id: <20181129171230.18699-11-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181129171230.18699-1-ard.biesheuvel@linaro.org> References: <20181129171230.18699-1-ard.biesheuvel@linaro.org> MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The current implementation of efi_mem_reserve_persistent() is rather naive, in the sense that for each invocation, it creates a separate linked list entry to describe the reservation. Since the linked list entries themselves need to persist across subsequent kexec reboots, every reservation created this way results in two memblock_reserve() calls at the next boot. On arm64 systems with 100s of CPUs, this may result in a excessive number of memblock reservations, and needless fragmentation. So instead, make use of the newly updated struct linux_efi_memreserve layout to put multiple reservations into a single linked list entry. This should get rid of the numerous tiny memblock reservations, and effectively cut the total number of reservations in half on arm64 systems with many CPUs. Tested-by: Marc Zyngier Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/efi.c | 20 +++++++++++++++++--- include/linux/efi.h | 3 +++ 2 files changed, 20 insertions(+), 3 deletions(-) -- 2.19.1 diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 80b11521627a..e90bc32c2670 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -998,7 +998,8 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) { struct linux_efi_memreserve *rsv; int rsvsize = EFI_MEMRESERVE_SIZE(1); - int rc; + unsigned long prsv; + int rc, index; if (efi_memreserve_root == (void *)ULONG_MAX) return -ENODEV; @@ -1009,11 +1010,24 @@ int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) return rc; } - rsv = kmalloc(rsvsize, GFP_ATOMIC); + /* first try to find a slot in an existing linked list entry */ + for (prsv = efi_memreserve_root->next; prsv; prsv = rsv->next) { + rsv = __va(prsv); + index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size); + if (index < rsv->size) { + rsv->entry[index].base = addr; + rsv->entry[index].size = size; + + return 0; + } + } + + /* no slot found - allocate a new linked list entry */ + rsv = (struct linux_efi_memreserve *)__get_free_page(GFP_ATOMIC); if (!rsv) return -ENOMEM; - rsv->size = 1; + rsv->size = EFI_MEMRESERVE_COUNT(PAGE_SIZE); atomic_set(&rsv->count, 1); rsv->entry[0].base = addr; rsv->entry[0].size = size; diff --git a/include/linux/efi.h b/include/linux/efi.h index 4f27640fdcdc..becd5d76a207 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1724,4 +1724,7 @@ struct linux_efi_memreserve { #define EFI_MEMRESERVE_SIZE(count) (sizeof(struct linux_efi_memreserve) + \ (count) * sizeof(((struct linux_efi_memreserve *)0)->entry[0])) +#define EFI_MEMRESERVE_COUNT(size) (((size) - sizeof(struct linux_efi_memreserve)) \ + / sizeof(((struct linux_efi_memreserve *)0)->entry[0])) + #endif /* _LINUX_EFI_H */