[prev in list] [next in list] [prev in thread] [next in thread]
List: hurd-bug
Subject: Re: [PATCH] tmpfs: keep a reference to memory objects
From: Sergio Lopez <sergio.lopez () sinrega ! org>
Date: 2010-05-19 15:02:22
Message-ID: 20100519170222.79e5e375 () sinrega ! org
[Download RAW message or body]
El Wed, 19 May 2010 10:37:21 +0200
<olafBuddenhagen@gmx.net> escribió:
> On Tue, May 18, 2010 at 04:21:14PM +0200, Sergio Lopez wrote:
>
> > This patch modifies tmpfs to keep a reference (by mapping it into
> > its own space) to each memory object created by the user, so they
> > don't get inmediately terminated at the end of the current
> > operation.
>
> Hm... Do I get it right, that when the client closes a file (or
> otherwise drops the mapping), the object holding the data was getting
> lost? Ouch...
>
Yes, but Mach is doing what we've told him, since the default pager is
creating the object with can_cache=FALSE. Anyway, if we change default
pager to create external objects with can_cache=TRUE, we'll still have
this problem when objects get expeled from cache.
The real problem is that Mach thinks that every object can be recreated
at any time. This is true for a translator like ext2fs, as we can
locate the contents of a file a provide its contents to Mach every time
we're requested to. But with the default pager, even if its contents
are currently written to swap space, if a object is terminated we lost
all our connections with actual data.
I think that, in future, in parallel with a new cache policy for memory
objects, we should implement a special treatment for named memory
objects without a backing store.
> (The comment in the code says something slightly different though. So
> it doesn't happen immediately, only when cleaning the cache?)
>
You're right, I've wrote that comment when I was testing it with a
default pager which created objects with can_cache=TRUE. I've changed
it now.
> > @@ -489,7 +491,7 @@
> > {
> > error_t err = default_pager_object_create (default_pager,
> > &np->dn->u.reg.memobj,
> > - np->allocsize);
> > + vm_page_size);
> > if (err)
> > {
> > errno = err;
>
> Hm... This change doesn't look like it's related to the issue you
> described above... Am I missing something, or did you sneak in an
> unrelated fix here? ;-)
>
Yes, it's unrelated. I've splitted it up in other patch.
> > @@ -500,6 +502,13 @@
> > past the specified size of the file. */
> > err = default_pager_object_set_size (np->dn->u.reg.memobj,
> > np->allocsize);
> > + assert_perror (err);
>
> Again, seems unrelated?...
No, this _is_ related :-). I want to make sure that the call to
default_pager_object_set_size didn't return an error before calling
vm_map().
>
> > + /* XXX we need to keep a reference to the object, or GNU Mach
> > + could try to terminate it while cleaning object cache */
>
> Why the XXX? Do you think this should be fixed another way in the
> long run?
>
Yes, as I wrote above, IMHO there should be a special treatment for
objects without a backing store.
Here is a little explanation of these patches:
- 01tmpfs_objectsize.patch: Create objects with size == vm_page_size,
since the default_pager doesn't properly support other values.
(object size will be virtually increased with successive calls to
default_pager_set_size).
- 02tmpfs_memref.patch: Keep a reference to the memory object. This
is better explained above.
[Attachment #3 (text/x-patch)]
diff -dur a/tmpfs/node.c b/tmpfs/node.c
--- a/tmpfs/node.c 2010-05-19 16:01:43.000000000 +0200
+++ b/tmpfs/node.c 2010-05-19 16:04:27.000000000 +0200
@@ -61,8 +61,10 @@
switch (np->dn->type)
{
case DT_REG:
- if (np->dn->u.reg.memobj != MACH_PORT_NULL)
+ if (np->dn->u.reg.memobj != MACH_PORT_NULL) {
+ vm_deallocate (mach_task_self (), np->dn->u.reg.memref, 4096);
mach_port_deallocate (mach_task_self (), np->dn->u.reg.memobj);
+ }
break;
case DT_DIR:
assert (np->dn->u.dir.entries == 0);
@@ -500,6 +502,13 @@
past the specified size of the file. */
err = default_pager_object_set_size (np->dn->u.reg.memobj,
np->allocsize);
+ assert_perror (err);
+
+ /* XXX we need to keep a reference to the object, or GNU Mach
+ will terminate it when we release the map. */
+ vm_map (mach_task_self (), &np->dn->u.reg.memref, 4096, 0, 1,
+ np->dn->u.reg.memobj, 0, 0, VM_PROT_NONE, VM_PROT_NONE,
+ VM_INHERIT_NONE);
}
/* XXX always writable */
diff -dur a/tmpfs/tmpfs.h b/tmpfs/tmpfs.h
--- a/tmpfs/tmpfs.h 2010-05-19 15:51:44.000000000 +0200
+++ b/tmpfs/tmpfs.h 2010-05-19 16:00:03.000000000 +0200
@@ -47,6 +47,7 @@
struct
{
mach_port_t memobj;
+ vm_address_t memref;
unsigned int allocpages; /* largest size while memobj was live */
} reg;
struct
[Attachment #4 (text/x-patch)]
diff -dur a/tmpfs/node.c b/tmpfs/node.c
--- a/tmpfs/node.c 2010-05-19 15:51:44.000000000 +0200
+++ b/tmpfs/node.c 2010-05-19 15:53:47.000000000 +0200
@@ -489,7 +489,7 @@
{
error_t err = default_pager_object_create (default_pager,
&np->dn->u.reg.memobj,
- np->allocsize);
+ vm_page_size);
if (err)
{
errno = err;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic