public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [patch][rfc] expandable anonymous shared mappings
@ 2004-06-16 18:12 Stas Sergeev
  2004-06-18 20:46 ` Hugh Dickins
  0 siblings, 1 reply; 14+ messages in thread
From: Stas Sergeev @ 2004-06-16 18:12 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 873 bytes --]


Hello.

It seems right now there is no way to
expand the anonymous shared mappings
(or am I missing something?)
This makes this mechanism practically
useless for many tasks, it otherwise could
suit very well, I beleive.
The attached patch implements a simple
nopage vm op for anonymous shared mappings,
which allows to expand them with mremap().
Attached is also a test-case which crashes
with bus error without the patch and works
properly with the patch (it tries to expand
the mapping, but without the patch it is
not possible).
The patch is against 2.6.7-rc3-mm2, but
should work with any 2.6.6 I beleive.

I would be glad to hear any comments on that.
I really would like to use the anonymous shared
mappings rather than those heavy-weight
alternatives like shm_open() and such, when
appropriate, but without the mremap() support,
this looks quite impossible to me.


[-- Attachment #2: anon_nopg.diff --]
[-- Type: text/x-patch, Size: 1786 bytes --]


--- linux/mm/shmem.c	2004-06-15 09:51:54.000000000 +0400
+++ linux/mm/shmem.c	2004-06-15 17:03:04.000000000 +0400
@@ -169,6 +169,7 @@
 static struct inode_operations shmem_inode_operations;
 static struct inode_operations shmem_dir_inode_operations;
 static struct vm_operations_struct shmem_vm_ops;
+static struct vm_operations_struct shmem_zero_vm_ops;
 
 static struct backing_dev_info shmem_backing_dev_info = {
 	.ra_pages	= 0,	/* No readahead */
@@ -1095,6 +1096,27 @@
 	return page;
 }
 
+struct page *shmem_zero_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
+{
+	struct inode *inode = vma->vm_file->f_dentry->d_inode;
+	loff_t vm_size = address + PAGE_SIZE - vma->vm_start;
+	loff_t i_size = i_size_read(inode);
+
+	if (i_size < vm_size) {
+		int error;
+		error = shmem_acct_size(SHMEM_I(inode)->flags, vm_size - i_size);
+		if (error)
+			return NOPAGE_SIGBUS;
+		down(&inode->i_sem);
+		error = vmtruncate(inode, vm_size);
+		up(&inode->i_sem);
+		if (error)
+			return NOPAGE_SIGBUS;
+	}
+
+	return shmem_nopage(vma, address, type);
+}
+
 static int shmem_populate(struct vm_area_struct *vma,
 	unsigned long addr, unsigned long len,
 	pgprot_t prot, unsigned long pgoff, int nonblock)
@@ -1970,6 +1992,15 @@
 #endif
 };
 
+static struct vm_operations_struct shmem_zero_vm_ops = {
+	.nopage		= shmem_zero_nopage,
+	.populate	= shmem_populate,
+#ifdef CONFIG_NUMA
+	.set_policy     = shmem_set_policy,
+	.get_policy     = shmem_get_policy,
+#endif
+};
+
 static struct super_block *shmem_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data)
 {
@@ -2101,7 +2132,7 @@
 	if (vma->vm_file)
 		fput(vma->vm_file);
 	vma->vm_file = file;
-	vma->vm_ops = &shmem_vm_ops;
+	vma->vm_ops = &shmem_zero_vm_ops;
 	return 0;
 }
 

[-- Attachment #3: shar_grow.c --]
[-- Type: text/x-csrc, Size: 998 bytes --]


#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#define NPAG 200

int main(int argc, char *argv[])
{
  char *src, *dst, *ptr, buf[255];

  if ((src = mmap(0, getpagesize(), PROT_READ | PROT_WRITE,
      MAP_SHARED | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) {
    perror("mmap()");
    return 1;
  }

  printf("mapped to %p\n", src);
  if ((dst = mremap(src, getpagesize(), NPAG * getpagesize(),
      MREMAP_MAYMOVE)) == MAP_FAILED) {
    perror("mremap()");
    return 1;
  }

  sprintf(buf, "cat /proc/%i/maps", getpid());
  system(buf);
  fflush(stdout);

  ptr = dst + (NPAG - 5) * getpagesize();
  printf("trying %p (%p)...\n", ptr, ptr-dst);
  *ptr = 20;
  printf("%#x, works!\n", *ptr);
  ptr = dst + (NPAG - 3) * getpagesize();
  printf("trying %p (%p)...\n", ptr, ptr-dst);
  *ptr = 20;
  printf("%#x, works!\n", *ptr);
  return 0;
}

[-- Attachment #4: Type: text/plain, Size: 82 bytes --]


Scanned by evaluation version of Dr.Web antivirus Daemon 
http://drweb.ru/unix/


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2004-06-29 19:03 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-06-16 18:12 [patch][rfc] expandable anonymous shared mappings Stas Sergeev
2004-06-18 20:46 ` Hugh Dickins
2004-06-19  9:07   ` Stas Sergeev
2004-06-20  0:20     ` Hugh Dickins
2004-06-20  9:46       ` Stas Sergeev
2004-06-23 11:23         ` Christoph Rohland
2004-06-23 18:45           ` Stas Sergeev
2004-06-28 14:25             ` Christoph Rohland
2004-06-28 14:22         ` Hugh Dickins
2004-06-28 18:48           ` Stas Sergeev
2004-06-28 21:44             ` Hugh Dickins
2004-06-29 17:06               ` Stas Sergeev
2004-06-29 17:41                 ` Hugh Dickins
2004-06-29 19:03                   ` Stas Sergeev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox