Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757472AbcDEIAR (ORCPT ); Tue, 5 Apr 2016 04:00:17 -0400 Received: from mga04.intel.com ([192.55.52.120]:50704 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752736AbcDEIAP (ORCPT ); Tue, 5 Apr 2016 04:00:15 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,443,1455004800"; d="scan'208";a="925623741" Message-ID: <1459843262.5564.4.camel@linux.intel.com> Subject: Re: [PATCH v2 2/3] mm/vmap: Add a notifier for when we run out of vmap address space From: Joonas Lahtinen To: Chris Wilson , intel-gfx@lists.freedesktop.org Cc: Andrew Morton , David Rientjes , Roman Peniaev , Mel Gorman , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Tvrtko Ursulin Date: Tue, 05 Apr 2016 11:01:02 +0300 In-Reply-To: <1459777603-23618-3-git-send-email-chris@chris-wilson.co.uk> References: <1459777603-23618-1-git-send-email-chris@chris-wilson.co.uk> <1459777603-23618-3-git-send-email-chris@chris-wilson.co.uk> Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.18.5.2 (3.18.5.2-1.fc23) Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4150 Lines: 123 On ma, 2016-04-04 at 14:46 +0100, Chris Wilson wrote: > 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 Reviewed-by: Joonas Lahtinen > Cc: Tvrtko Ursulin > --- >  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)); -- Joonas Lahtinen Open Source Technology Center Intel Corporation