From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752141AbZHLM4Y (ORCPT ); Wed, 12 Aug 2009 08:56:24 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751693AbZHLM4X (ORCPT ); Wed, 12 Aug 2009 08:56:23 -0400 Received: from mx3.mail.elte.hu ([157.181.1.138]:56653 "EHLO mx3.mail.elte.hu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751361AbZHLM4W (ORCPT ); Wed, 12 Aug 2009 08:56:22 -0400 Date: Wed, 12 Aug 2009 14:56:17 +0200 From: Ingo Molnar To: Nitin Gupta Cc: linux-kernel@vger.kernel.org, linux-mm@vger.kernel.org Subject: Re: [RFC][PATCH] swap: send callback when swap slot is freed Message-ID: <20090812125617.GA30476@elte.hu> References: <200908121817.48501.ngupta@vflare.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200908121817.48501.ngupta@vflare.org> User-Agent: Mutt/1.5.18 (2008-05-17) X-ELTE-SpamScore: -1.5 X-ELTE-SpamLevel: X-ELTE-SpamCheck: no X-ELTE-SpamVersion: ELTE 2.0 X-ELTE-SpamCheck-Details: score=-1.5 required=5.9 tests=BAYES_00 autolearn=no SpamAssassin version=3.2.5 -1.5 BAYES_00 BODY: Bayesian spam probability is 0 to 1% [score: 0.0000] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org * Nitin Gupta wrote: > (Re-sending since I didn't get any reply last time) > > Currently, we have "swap discard" mechanism which sends a discard > bio request when we find a free cluster during scan_swap_map(). > This callback can come a long time after swap slots are actually > freed. > > This delay in callback is a great problem when (compressed) RAM > [1] is used as a swap device. So, this change adds a callback > which is called as soon as a swap slot becomes free. For above > mentioned case of swapping over compressed RAM device, this is > very useful since we can immediately free memory allocated for > this swap page. > > This callback does not replace swap discard support. It is called > with swap_lock held, so it is meant to trigger action that > finishes quickly. However, swap discard is an I/O request and can > be used for taking longer actions. > > This patch is simply a quick hack but it works (tested on x86 and > x64). Can anyone please suggest a cleaner and proper way to do > this? Any feedback would be really helpful. Thanks. > > > Links: > [1] http://code.google.com/p/compcache/ > > Signed-off-by: Nitin Gupta > --- > > include/linux/swap.h | 14 ++++++++++++++ > init/Kconfig | 9 +++++++++ > mm/swapfile.c | 20 ++++++++++++++++++++ > 3 files changed, 43 insertions(+), 0 deletions(-) > > diff --git a/include/linux/swap.h b/include/linux/swap.h > index 7c15334..483d0b9 100644 > --- a/include/linux/swap.h > +++ b/include/linux/swap.h > @@ -8,6 +8,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -20,6 +21,8 @@ struct bio; > #define SWAP_FLAG_PRIO_MASK 0x7fff > #define SWAP_FLAG_PRIO_SHIFT 0 > > +typedef void (swap_free_notify_fn) (struct block_device *, unsigned long); > + > static inline int current_is_kswapd(void) > { > return current->flags & PF_KSWAPD; > @@ -155,6 +158,9 @@ struct swap_info_struct { > unsigned int max; > unsigned int inuse_pages; > unsigned int old_block_size; > +#ifdef CONFIG_SWAP_FREE_NOTIFY > + swap_free_notify_fn *swap_free_notify_fn; > +#endif > }; > > struct swap_list_t { > @@ -297,6 +303,14 @@ extern int reuse_swap_page(struct page *); > extern int try_to_free_swap(struct page *); > struct backing_dev_info; > > +#ifdef CONFIG_SWAP_FREE_NOTIFY > +extern void set_swap_free_notify(unsigned, swap_free_notify_fn *); > +#else > +void set_swap_free_notify(unsigned, swap_free_notify_fn *) > +{ > +} > +#endif > + > /* linux/mm/thrash.c */ > extern struct mm_struct *swap_token_mm; > extern void grab_swap_token(struct mm_struct *); > diff --git a/init/Kconfig b/init/Kconfig > index 3f7e609..b0112c6 100644 > --- a/init/Kconfig > +++ b/init/Kconfig > @@ -176,6 +176,15 @@ config SWAP > used to provide more virtual memory than the actual RAM present > in your computer. If unsure say Y. > > +config SWAP_FREE_NOTIFY > + bool "Enable swap free notification" > + depends on SWAP > + default y > + help > + This causes swap subsystem to send a callback to swap device when > + a swap block becomes free. This is useful in cases such as when > + compressed RAM device is used as swap disk. > + > config SYSVIPC > bool "System V IPC" > ---help--- > diff --git a/mm/swapfile.c b/mm/swapfile.c > index 8ffdc0d..25bacfd 100644 > --- a/mm/swapfile.c > +++ b/mm/swapfile.c > @@ -552,6 +552,22 @@ out: > return NULL; > } > > +#ifdef CONFIG_SWAP_FREE_NOTIFY > +/* > + * Sets callback for event when swap_map[offset] == 0 > + * i.e. page at this swap offset is not longer used. > + */ > +void set_swap_free_notify(unsigned type, swap_free_notify_fn *notify_fn) > +{ > + struct swap_info_struct *sis; > + sis = get_swap_info_struct(type); > + BUG_ON(!sis); > + sis->swap_free_notify_fn = notify_fn; > + return; > +} > +EXPORT_SYMBOL(set_swap_free_notify); > +#endif > + > static int swap_entry_free(struct swap_info_struct *p, > swp_entry_t ent, int cache) > { > @@ -583,6 +599,10 @@ static int swap_entry_free(struct swap_info_struct *p, > swap_list.next = p - swap_info; > nr_swap_pages++; > p->inuse_pages--; > +#ifdef CONFIG_SWAP_FREE_NOTIFY > + if (p->swap_free_notify_fn) > + p->swap_free_notify_fn(p->bdev, offset); > +#endif > } > if (!swap_count(count)) > mem_cgroup_uncharge_swap(ent); Shouldnt this be all be unconditional? Sounds like a reasonable VM callback. The patch would become a lot smaller as well. Ingo