From patchwork Mon Apr 4 13:46:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 8741111 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 8AC899F39A for ; Mon, 4 Apr 2016 13:47:05 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DC90D2028D for ; Mon, 4 Apr 2016 13:46:59 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id C6CF720272 for ; Mon, 4 Apr 2016 13:46:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 173596E5DE; Mon, 4 Apr 2016 13:46:58 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-lb0-x242.google.com (mail-lb0-x242.google.com [IPv6:2a00:1450:4010:c04::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 59A446E1F8 for ; Mon, 4 Apr 2016 13:46:56 +0000 (UTC) Received: by mail-lb0-x242.google.com with SMTP id gk8so20225476lbc.2 for ; Mon, 04 Apr 2016 06:46:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=r3htAAW9DnJ1djzN9dD+Mbp2LBnvnDWE2MAq5i87EO4=; b=vs78e3sRWsppayGyit3MqZKWdBr7O1vxpl7vCz7hcrlK20p4Tzz180fYZd7PyLT6Hd 5x71qYLCVaz/aePFX7/435wp1pLz/Wdn8Wr0en2QclF3oXeT3lbT/eEVS9y6x9cwFCYP cnqJcXiy3LnYGvD0uojcTxZ8aJJW7/RKT6AFjgkMZkI6OYGAcqs1ReqEY7DBKKh4N3wV xtr2KZrayafbtE4569mA0CqU4AYl9mZ0PQeRzTaWS41Qln3vaXGseOBaMbSvEYwozARq 0LmnVT/3aAUofMw68NCGyRwcWFNBeMy/GybuV+/A+p04EiqNcU8gPmkv32cg3UDNc5q4 EFXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=r3htAAW9DnJ1djzN9dD+Mbp2LBnvnDWE2MAq5i87EO4=; b=SZ19mho4UrvLG1brr8r//VOtvh7GYyHv1NjqoH8yBSblGeDr2IvLaVAQTX7PE6Op1E I10Ji6B2HgzzN7M7YvGCE3uKbP6b6KwdOJQgeumLZ6LPhorAgWcPTFEvkhafcY3g4I23 oiJYbV8qRxmOzYrHE33a5DvLWDvqwBngt2vBk1AdGAESB04/+PFQ4HlBe3bsSRr6slaP V1yG7kAqbD/0vMUgJlbJ3BRnTk8MihL8zAs9Vq45aHDpdxySDd5K7GTV/xFv5F6DyZJC CICYcJY3YijYNgXMgqhOnDS24DXcDXy6DEkLQH6jWPWeVM5dq++uj4J2UuZpKkIULuy7 mJDw== X-Gm-Message-State: AD7BkJIusYAk+JWJTnhqplJWdHbLFxJkpH8F7Gg6+JIRAnjbAlug33rWCp6nWHg6Wx5Hhw== X-Received: by 10.28.140.11 with SMTP id o11mr12219210wmd.81.1459777614849; Mon, 04 Apr 2016 06:46:54 -0700 (PDT) Received: from haswell.alporthouse.com ([78.156.65.138]) by smtp.gmail.com with ESMTPSA id w75sm4019533wmw.4.2016.04.04.06.46.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 04 Apr 2016 06:46:53 -0700 (PDT) From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Mon, 4 Apr 2016 14:46:42 +0100 Message-Id: <1459777603-23618-3-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.8.0.rc3 In-Reply-To: <1459777603-23618-1-git-send-email-chris@chris-wilson.co.uk> References: <1459777603-23618-1-git-send-email-chris@chris-wilson.co.uk> Cc: linux-kernel@vger.kernel.org, Roman Peniaev , linux-mm@kvack.org, David Rientjes , Andrew Morton , Mel Gorman Subject: [Intel-gfx] [PATCH v2 2/3] mm/vmap: Add a notifier for when we run out of vmap address space X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-5.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP vmaps are temporary kernel mappings that may be of long duration. Reusing a vmap on an object is preferrable for a driver as the cost of setting up the vmap can otherwise dominate the operation on the object. However, the vmap address space is rather limited on 32bit systems and so we add a notification for vmap pressure in order for the driver to release any cached vmappings. The interface is styled after the oom-notifier where the callees are passed a pointer to an unsigned long counter for them to indicate if they have freed any space. v2: Guard the blocking notifier call with gfpflags_allow_blocking() v3: Correct typo in forward declaration and move to head of file Signed-off-by: Chris Wilson Cc: Andrew Morton Cc: David Rientjes Cc: Roman Peniaev Cc: Mel Gorman Cc: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org Acked-by: Andrew Morton # for inclusion via DRM Cc: Joonas Lahtinen Cc: Tvrtko Ursulin Reviewed-by: Joonas Lahtinen --- include/linux/vmalloc.h | 4 ++++ mm/vmalloc.c | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index d1f1d338af20..8b51df3ab334 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -8,6 +8,7 @@ #include struct vm_area_struct; /* vma defining user mapping in mm_types.h */ +struct notifier_block; /* in notifier.h */ /* bits in flags of vmalloc's vm_struct below */ #define VM_IOREMAP 0x00000001 /* ioremap() and friends */ @@ -187,4 +188,7 @@ pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms) #define VMALLOC_TOTAL 0UL #endif +int register_vmap_purge_notifier(struct notifier_block *nb); +int unregister_vmap_purge_notifier(struct notifier_block *nb); + #endif /* _LINUX_VMALLOC_H */ diff --git a/mm/vmalloc.c b/mm/vmalloc.c index ae7d20b447ff..293889d7f482 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -344,6 +345,8 @@ static void __insert_vmap_area(struct vmap_area *va) static void purge_vmap_area_lazy(void); +static BLOCKING_NOTIFIER_HEAD(vmap_notify_list); + /* * Allocate a region of KVA of the specified size and alignment, within the * vstart and vend. @@ -363,6 +366,8 @@ static struct vmap_area *alloc_vmap_area(unsigned long size, BUG_ON(offset_in_page(size)); BUG_ON(!is_power_of_2(align)); + might_sleep_if(gfpflags_allow_blocking(gfp_mask)); + va = kmalloc_node(sizeof(struct vmap_area), gfp_mask & GFP_RECLAIM_MASK, node); if (unlikely(!va)) @@ -468,6 +473,16 @@ overflow: purged = 1; goto retry; } + + if (gfpflags_allow_blocking(gfp_mask)) { + unsigned long freed = 0; + blocking_notifier_call_chain(&vmap_notify_list, 0, &freed); + if (freed > 0) { + purged = 0; + goto retry; + } + } + if (printk_ratelimit()) pr_warn("vmap allocation for size %lu failed: use vmalloc= to increase size\n", size); @@ -475,6 +490,18 @@ overflow: return ERR_PTR(-EBUSY); } +int register_vmap_purge_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&vmap_notify_list, nb); +} +EXPORT_SYMBOL_GPL(register_vmap_purge_notifier); + +int unregister_vmap_purge_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&vmap_notify_list, nb); +} +EXPORT_SYMBOL_GPL(unregister_vmap_purge_notifier); + static void __free_vmap_area(struct vmap_area *va) { BUG_ON(RB_EMPTY_NODE(&va->rb_node));