public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Stas Sergeev <stsp@aknet.ru>
To: linux-kernel@vger.kernel.org
Subject: [patch][rfc] expandable anonymous shared mappings
Date: Wed, 16 Jun 2004 22:12:10 +0400	[thread overview]
Message-ID: <40D08D7A.9020909@aknet.ru> (raw)

[-- 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/


             reply	other threads:[~2004-06-16 18:13 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-06-16 18:12 Stas Sergeev [this message]
2004-06-18 20:46 ` [patch][rfc] expandable anonymous shared mappings 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

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=40D08D7A.9020909@aknet.ru \
    --to=stsp@aknet.ru \
    --cc=linux-kernel@vger.kernel.org \
    /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