linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Peter Zijlstra <a.p.zijlstra@chello.nl>
To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, netdev@vger.kernel.org
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Trond Myklebust <trond.myklebust@fys.uio.no>,
	Thomas Graf <tgraf@suug.ch>, David Miller <davem@davemloft.net>,
	James Bottomley <James.Bottomley@SteelEye.com>,
	Mike Christie <michaelc@cs.wisc.edu>,
	Andrew Morton <akpm@linux-foundation.org>,
	Daniel Phillips <phillips@google.com>
Subject: [PATCH 23/40] mm: add support for non block device backed swap files
Date: Fri, 04 May 2007 12:27:14 +0200	[thread overview]
Message-ID: <20070504103200.815617316@chello.nl> (raw)
In-Reply-To: <20070504102651.923946304@chello.nl>

[-- Attachment #1: mm-swapfile.patch --]
[-- Type: text/plain, Size: 8828 bytes --]

A new addres_space_operations method is added:
  int swapfile(struct address_space *, int)

When during sys_swapon() this method is found and returns no error the 
swapper_space.a_ops will proxy to sis->swap_file->f_mapping->a_ops.

The swapfile method will be used to communicate to the address_space that the
VM relies on it, and the address_space should take adequate measures (like 
reserving memory for mempools or the like).

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
CC: Trond Myklebust <trond.myklebust@fys.uio.no>
---
 Documentation/filesystems/Locking |    9 ++++++
 include/linux/fs.h                |    1 
 include/linux/swap.h              |    3 ++
 mm/Kconfig                        |    4 ++
 mm/page_io.c                      |   55 ++++++++++++++++++++++++++++++++++++++
 mm/swap_state.c                   |    5 +++
 mm/swapfile.c                     |   22 ++++++++++++++-
 7 files changed, 98 insertions(+), 1 deletion(-)

Index: linux-2.6-git/include/linux/swap.h
===================================================================
--- linux-2.6-git.orig/include/linux/swap.h	2007-03-26 13:40:38.000000000 +0200
+++ linux-2.6-git/include/linux/swap.h	2007-03-26 13:40:43.000000000 +0200
@@ -163,6 +163,7 @@ enum {
 	SWP_USED	= (1 << 0),	/* is slot in swap_info[] used? */
 	SWP_WRITEOK	= (1 << 1),	/* ok to write to this swap?	*/
 	SWP_ACTIVE	= (SWP_USED | SWP_WRITEOK),
+	SWP_FILE	= (1 << 2),	/* file swap area */
 					/* add others here before... */
 	SWP_SCANNING	= (1 << 8),	/* refcount in scan_swap_map */
 };
@@ -264,6 +265,8 @@ extern void swap_unplug_io_fn(struct bac
 /* linux/mm/page_io.c */
 extern int swap_readpage(struct file *, struct page *);
 extern int swap_writepage(struct page *page, struct writeback_control *wbc);
+extern void swap_sync_page(struct page *page);
+extern int swap_set_page_dirty(struct page *page);
 extern int end_swap_bio_read(struct bio *bio, unsigned int bytes_done, int err);
 
 /* linux/mm/swap_state.c */
Index: linux-2.6-git/mm/page_io.c
===================================================================
--- linux-2.6-git.orig/mm/page_io.c	2007-03-26 13:34:51.000000000 +0200
+++ linux-2.6-git/mm/page_io.c	2007-03-26 13:40:43.000000000 +0200
@@ -17,6 +17,7 @@
 #include <linux/bio.h>
 #include <linux/swapops.h>
 #include <linux/writeback.h>
+#include <linux/buffer_head.h>
 #include <asm/pgtable.h>
 
 static struct bio *get_swap_bio(gfp_t gfp_flags, pgoff_t index,
@@ -110,6 +111,18 @@ int swap_writepage(struct page *page, st
 		unlock_page(page);
 		goto out;
 	}
+#ifdef CONFIG_SWAP_FILE
+	{
+		struct swap_info_struct *sis = page_swap_info(page);
+		if (sis->flags & SWP_FILE) {
+			ret = sis->swap_file->f_mapping->
+				a_ops->writepage(page, wbc);
+			if (!ret)
+				count_vm_event(PSWPOUT);
+			return ret;
+		}
+	}
+#endif
 	bio = get_swap_bio(GFP_NOIO, page_private(page), page,
 				end_swap_bio_write);
 	if (bio == NULL) {
@@ -128,6 +141,36 @@ out:
 	return ret;
 }
 
+#ifdef CONFIG_SWAP_FILE
+void swap_sync_page(struct page *page)
+{
+	struct swap_info_struct *sis = page_swap_info(page);
+
+	if (sis->flags & SWP_FILE) {
+		const struct address_space_operations * a_ops =
+			sis->swap_file->f_mapping->a_ops;
+		if (a_ops->sync_page)
+			a_ops->sync_page(page);
+	} else
+		block_sync_page(page);
+}
+
+int swap_set_page_dirty(struct page *page)
+{
+	struct swap_info_struct *sis = page_swap_info(page);
+
+	if (sis->flags & SWP_FILE) {
+		const struct address_space_operations * a_ops =
+			sis->swap_file->f_mapping->a_ops;
+		if (a_ops->set_page_dirty)
+			return a_ops->set_page_dirty(page);
+		return __set_page_dirty_buffers(page);
+	}
+
+	return __set_page_dirty_nobuffers(page);
+}
+#endif
+
 int swap_readpage(struct file *file, struct page *page)
 {
 	struct bio *bio;
@@ -135,6 +178,18 @@ int swap_readpage(struct file *file, str
 
 	BUG_ON(!PageLocked(page));
 	ClearPageUptodate(page);
+#ifdef CONFIG_SWAP_FILE
+	{
+		struct swap_info_struct *sis = page_swap_info(page);
+		if (sis->flags & SWP_FILE) {
+			ret = sis->swap_file->f_mapping->
+				a_ops->readpage(sis->swap_file, page);
+			if (!ret)
+				count_vm_event(PSWPIN);
+			return ret;
+		}
+	}
+#endif
 	bio = get_swap_bio(GFP_KERNEL, page_private(page), page,
 				end_swap_bio_read);
 	if (bio == NULL) {
Index: linux-2.6-git/mm/swap_state.c
===================================================================
--- linux-2.6-git.orig/mm/swap_state.c	2007-03-26 13:34:51.000000000 +0200
+++ linux-2.6-git/mm/swap_state.c	2007-03-26 13:40:43.000000000 +0200
@@ -26,8 +26,13 @@
  */
 static const struct address_space_operations swap_aops = {
 	.writepage	= swap_writepage,
+#ifdef CONFIG_SWAP_FILE
+	.sync_page	= swap_sync_page,
+	.set_page_dirty	= swap_set_page_dirty,
+#else
 	.sync_page	= block_sync_page,
 	.set_page_dirty	= __set_page_dirty_nobuffers,
+#endif
 	.migratepage	= migrate_page,
 };
 
Index: linux-2.6-git/mm/swapfile.c
===================================================================
--- linux-2.6-git.orig/mm/swapfile.c	2007-03-26 13:40:38.000000000 +0200
+++ linux-2.6-git/mm/swapfile.c	2007-03-26 13:40:43.000000000 +0200
@@ -981,6 +981,13 @@ static void destroy_swap_extents(struct 
 		list_del(&se->list);
 		kfree(se);
 	}
+#ifdef CONFIG_SWAP_FILE
+	if (sis->flags & SWP_FILE) {
+		sis->flags &= ~SWP_FILE;
+		sis->swap_file->f_mapping->a_ops->
+			swapfile(sis->swap_file->f_mapping, 0);
+	}
+#endif
 }
 
 /*
@@ -1073,6 +1080,19 @@ static int setup_swap_extents(struct swa
 		goto done;
 	}
 
+#ifdef CONFIG_SWAP_FILE
+	if (sis->swap_file->f_mapping->a_ops->swapfile) {
+		ret = sis->swap_file->f_mapping->a_ops->
+			swapfile(sis->swap_file->f_mapping, 1);
+		if (!ret) {
+			sis->flags |= SWP_FILE;
+			ret = add_swap_extent(sis, 0, sis->max, 0);
+			*span = sis->pages;
+		}
+		goto done;
+	}
+#endif
+
 	blkbits = inode->i_blkbits;
 	blocks_per_page = PAGE_SIZE >> blkbits;
 
@@ -1640,7 +1660,7 @@ asmlinkage long sys_swapon(const char __
 
 	mutex_lock(&swapon_mutex);
 	spin_lock(&swap_lock);
-	p->flags = SWP_ACTIVE;
+	p->flags |= SWP_WRITEOK;
 	nr_swap_pages += nr_good_pages;
 	total_swap_pages += nr_good_pages;
 
Index: linux-2.6-git/include/linux/fs.h
===================================================================
--- linux-2.6-git.orig/include/linux/fs.h	2007-03-26 13:34:51.000000000 +0200
+++ linux-2.6-git/include/linux/fs.h	2007-03-26 13:40:43.000000000 +0200
@@ -428,6 +428,7 @@ struct address_space_operations {
 	int (*migratepage) (struct address_space *,
 			struct page *, struct page *);
 	int (*launder_page) (struct page *);
+	int (*swapfile)(struct address_space *, int);
 };
 
 struct backing_dev_info;
Index: linux-2.6-git/Documentation/filesystems/Locking
===================================================================
--- linux-2.6-git.orig/Documentation/filesystems/Locking	2007-03-26 13:34:51.000000000 +0200
+++ linux-2.6-git/Documentation/filesystems/Locking	2007-03-26 13:40:43.000000000 +0200
@@ -172,6 +172,7 @@ prototypes:
 	int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
 			loff_t offset, unsigned long nr_segs);
 	int (*launder_page) (struct page *);
+	int (*swapfile) (struct address_space *, int);
 
 locking rules:
 	All except set_page_dirty may block
@@ -190,6 +191,7 @@ invalidatepage:		no	yes
 releasepage:		no	yes
 direct_IO:		no
 launder_page:		no	yes
+swapfile		no
 
 	->prepare_write(), ->commit_write(), ->sync_page() and ->readpage()
 may be called from the request handler (/dev/loop).
@@ -289,6 +291,13 @@ cleaned, or an error value if not. Note 
 getting mapped back in and redirtied, it needs to be kept locked
 across the entire operation.
 
+	->swapfile() will be called with a non zero argument on address spaces
+backing non block device backed swapfiles. A return value of zero indicates
+success. In which case this address space can be used for backing swapspace.
+The swapspace operations will be proxied to the address space operations.
+Swapoff will call this method with a zero argument to release the address
+space.
+
 	Note: currently almost all instances of address_space methods are
 using BKL for internal serialization and that's one of the worst sources
 of contention. Normally they are calling library functions (in fs/buffer.c)
Index: linux-2.6-git/mm/Kconfig
===================================================================
--- linux-2.6-git.orig/mm/Kconfig	2007-03-26 13:36:32.000000000 +0200
+++ linux-2.6-git/mm/Kconfig	2007-03-26 13:41:22.000000000 +0200
@@ -166,3 +166,6 @@ config ZONE_DMA_FLAG
 config SLAB_FAIR
 	def_bool n
 	depends on SLAB
+
+config SWAP_FILE
+	def_bool n

--

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  parent reply	other threads:[~2007-05-04 10:27 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-04 10:26 [PATCH 00/40] Swap over Networked storage -v12 Peter Zijlstra
2007-05-04 10:26 ` [PATCH 01/40] mm: page allocation rank Peter Zijlstra
2007-05-04 10:26 ` [PATCH 02/40] mm: slab allocation fairness Peter Zijlstra
2007-05-16 20:41   ` Christoph Lameter
2007-05-04 10:26 ` [PATCH 03/40] mm: allow PF_MEMALLOC from softirq context Peter Zijlstra
2007-05-04 10:26 ` [PATCH 04/40] mm: serialize access to min_free_kbytes Peter Zijlstra
2007-05-04 10:26 ` [PATCH 05/40] mm: emergency pool Peter Zijlstra
2007-05-04 10:26 ` [PATCH 06/40] mm: __GFP_EMERGENCY Peter Zijlstra
2007-05-04 10:26 ` [PATCH 07/40] mm: allow mempool to fall back to memalloc reserves Peter Zijlstra
2007-05-04 10:26 ` [PATCH 08/40] mm: kmem_cache_objsize Peter Zijlstra
2007-05-04 10:54   ` Pekka Enberg
2007-05-04 16:09     ` Christoph Lameter
2007-05-04 16:15       ` Peter Zijlstra
2007-05-04 16:23         ` Christoph Lameter
2007-05-04 16:30           ` Peter Zijlstra
2007-05-04 16:36   ` Christoph Lameter
2007-05-04 17:59     ` Peter Zijlstra
2007-05-04 18:04       ` Christoph Lameter
2007-05-04 18:21         ` Peter Zijlstra
2007-05-04 18:30           ` Christoph Lameter
2007-05-04 18:32             ` Peter Zijlstra
2007-05-04 18:45               ` Pekka Enberg
2007-05-04 18:47                 ` Christoph Lameter
2007-05-04 18:54                   ` Pekka Enberg
2007-05-04 19:59                     ` Christoph Lameter
2007-05-05  9:00                       ` Pekka J Enberg
2007-05-04 18:41             ` Pekka Enberg
2007-05-04 18:46               ` Christoph Lameter
2007-05-04 18:53                 ` Pekka Enberg
2007-05-04 19:58                   ` Christoph Lameter
2007-05-04 10:27 ` [PATCH 09/40] mm: optimize gfp_to_rank() Peter Zijlstra
2007-05-04 10:27 ` [PATCH 10/40] selinux: tag avc cache alloc as non-critical Peter Zijlstra
2007-05-04 10:27 ` [PATCH 11/40] net: wrap sk->sk_backlog_rcv() Peter Zijlstra
2007-05-04 10:27 ` [PATCH 12/40] net: packet split receive api Peter Zijlstra
2007-05-04 10:27 ` [PATCH 13/40] net: sk_allocation() - concentrate socket related allocations Peter Zijlstra
2007-05-04 10:27 ` [PATCH 14/40] netvm: link network to vm layer Peter Zijlstra
2007-05-04 10:27 ` [PATCH 15/40] netvm: INET reserves Peter Zijlstra
2007-05-04 10:27 ` [PATCH 16/40] netvm: hook skb allocation to reserves Peter Zijlstra
2007-05-04 14:07   ` Arnaldo Carvalho de Melo
2007-05-04 10:27 ` [PATCH 17/40] netvm: filter emergency skbs Peter Zijlstra
2007-05-04 10:27 ` [PATCH 18/40] netvm: prevent a TCP specific deadlock Peter Zijlstra
2007-05-04 10:27 ` [PATCH 19/40] netfilter: notify about NF_QUEUE vs emergency skbs Peter Zijlstra
2007-05-04 10:27 ` [PATCH 20/40] netvm: skb processing Peter Zijlstra
2007-05-04 10:27 ` [PATCH 21/40] uml: rename arch/um remove_mapping() Peter Zijlstra
2007-05-04 10:27 ` [PATCH 22/40] mm: prepare swap entry methods for use in page methods Peter Zijlstra
2007-05-04 10:27 ` Peter Zijlstra [this message]
2007-05-04 10:27 ` [PATCH 24/40] mm: methods for teaching filesystems about PG_swapcache pages Peter Zijlstra
2007-05-04 10:27 ` [PATCH 25/40] nfs: remove mempools Peter Zijlstra
2007-05-04 10:27 ` [PATCH 26/40] nfs: teach the NFS client how to treat PG_swapcache pages Peter Zijlstra
2007-05-04 10:27 ` [PATCH 27/40] nfs: disable data cache revalidation for swapfiles Peter Zijlstra
2007-05-04 10:27 ` [PATCH 28/40] nfs: enable swap on NFS Peter Zijlstra
2007-05-04 10:27 ` [PATCH 29/40] nfs: fix various memory recursions possible with swap over NFS Peter Zijlstra
2007-05-04 10:27 ` [PATCH 30/40] nfs: fixup missing error code Peter Zijlstra
2007-05-04 13:10   ` Peter Staubach
2007-05-04 13:18     ` Peter Zijlstra
2007-05-04 10:27 ` [PATCH 31/40] mm: balance_dirty_pages() vs throttle_vm_writeout() deadlock Peter Zijlstra
2007-05-04 10:27 ` [PATCH 32/40] block: add a swapdev callback to the request_queue Peter Zijlstra
2007-05-04 10:27 ` [PATCH 33/40] uml: enable scsi and add iscsi config Peter Zijlstra
2007-05-04 10:27 ` [PATCH 34/40] sock: safely expose kernel sockets to userspace Peter Zijlstra
2007-05-04 10:27 ` [PATCH 35/40] From: Mike Christie <mchristi@redhat.com> Peter Zijlstra
2007-05-04 10:27 ` [PATCH 36/40] iscsi: fixup of the ep_connect patch Peter Zijlstra
2007-05-04 10:27 ` [PATCH 37/40] iscsi: ensure the iscsi kernel fd is not usable in userspace Peter Zijlstra
2007-05-04 10:27 ` [PATCH 38/40] netlink: add SOCK_VMIO support to AF_NETLINK Peter Zijlstra
2007-05-04 10:27 ` [PATCH 39/40] mm: a process flags to avoid blocking allocations Peter Zijlstra
2007-05-04 10:27 ` [PATCH 40/40] iscsi: support for swapping over iSCSI Peter Zijlstra
2007-05-04 15:22 ` [PATCH 00/40] Swap over Networked storage -v12 Daniel Walker
2007-05-04 15:38   ` Peter Zijlstra
2007-05-04 15:59     ` Daniel Walker
2007-05-04 18:09       ` Mike Snitzer
2007-05-04 19:31         ` Daniel Walker
2007-05-04 19:54         ` David Miller, Mike Snitzer
2007-05-04 21:36   ` Arnaldo Carvalho de Melo
2007-05-04 19:27 ` David Miller, Peter Zijlstra
2007-05-04 19:41   ` Peter Zijlstra
2007-05-04 20:02     ` David Miller, Peter Zijlstra
2007-05-04 20:29       ` Jeff Garzik
2007-05-05  9:43   ` Christoph Hellwig
2007-05-05  9:55     ` William Lee Irwin III

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070504103200.815617316@chello.nl \
    --to=a.p.zijlstra@chello.nl \
    --cc=James.Bottomley@SteelEye.com \
    --cc=akpm@linux-foundation.org \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=michaelc@cs.wisc.edu \
    --cc=netdev@vger.kernel.org \
    --cc=phillips@google.com \
    --cc=tgraf@suug.ch \
    --cc=trond.myklebust@fys.uio.no \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox