summaryrefslogtreecommitdiff
path: root/debian/patches
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/fatfs-improve-diskfs_node_iterate.patch75
-rw-r--r--debian/patches/fatfs-simplify-expr.patch22
-rw-r--r--debian/patches/fatfs-two-pagers.patch238
-rw-r--r--debian/patches/libpager-singlethreaded.patch67
-rw-r--r--debian/patches/series4
-rw-r--r--debian/patches/tmpfs-improve-diskfs_node_iterate.patch53
6 files changed, 448 insertions, 11 deletions
diff --git a/debian/patches/fatfs-improve-diskfs_node_iterate.patch b/debian/patches/fatfs-improve-diskfs_node_iterate.patch
new file mode 100644
index 00000000..da39f92d
--- /dev/null
+++ b/debian/patches/fatfs-improve-diskfs_node_iterate.patch
@@ -0,0 +1,75 @@
+commit d54ad18d9783729ffd7a54458bb0b941f3f14f75
+Author: Justus Winter <4winter@informatik.uni-hamburg.de>
+Date: Wed Apr 30 02:04:31 2014 +0200
+
+ fatfs: improve diskfs_node_iterate
+
+ Currently, diskfs_node_iterate iterates twice over all nodes in the
+ cache. The first time only to determine the number of nodes currently
+ in the cache. Simply count them instead.
+
+ * fatfs/inode.c (nodehash_nr_items): New variable.
+ (diskfs_cached_lookup): Increment nodehash_nr_items.
+ (diskfs_cached_lookup_in_dirbuf): Likewise.
+ (diskfs_node_norefs): Decrement nodehash_nr_items.
+ (diskfs_node_iterate): Fix the type of num_nodes, use nodehash_nr_items.
+
+diff --git a/fatfs/inode.c b/fatfs/inode.c
+index 4229806..ed6f3f0 100644
+--- a/fatfs/inode.c
++++ b/fatfs/inode.c
+@@ -45,6 +45,7 @@
+ #endif
+
+ static struct node *nodehash[INOHSZ];
++static size_t nodehash_nr_items;
+
+ static error_t read_node (struct node *np, vm_address_t buf);
+
+@@ -106,6 +107,7 @@ diskfs_cached_lookup (ino64_t inum, struct node **npp)
+ dn->hnext->dn->hprevp = &dn->hnext;
+ dn->hprevp = &nodehash[INOHASH(inum)];
+ nodehash[INOHASH(inum)] = np;
++ nodehash_nr_items += 1;
+
+ pthread_spin_unlock (&diskfs_node_refcnt_lock);
+
+@@ -171,6 +173,7 @@ diskfs_cached_lookup_in_dirbuf (int inum, struct node **npp, vm_address_t buf)
+ dn->hnext->dn->hprevp = &dn->hnext;
+ dn->hprevp = &nodehash[INOHASH(inum)];
+ nodehash[INOHASH(inum)] = np;
++ nodehash_nr_items += 1;
+
+ pthread_spin_unlock (&diskfs_node_refcnt_lock);
+
+@@ -216,7 +219,8 @@ diskfs_node_norefs (struct node *np)
+ *np->dn->hprevp = np->dn->hnext;
+ if (np->dn->hnext)
+ np->dn->hnext->dn->hprevp = np->dn->hprevp;
+-
++ nodehash_nr_items -= 1;
++
+ while (last)
+ {
+ struct cluster_chain *next = last->next;
+@@ -546,7 +550,8 @@ error_t
+ diskfs_node_iterate (error_t (*fun)(struct node *))
+ {
+ error_t err = 0;
+- int n, num_nodes = 0;
++ int n;
++ size_t num_nodes;
+ struct node *node, **node_list, **p;
+
+ pthread_spin_lock (&diskfs_node_refcnt_lock);
+@@ -557,9 +562,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *))
+ diskfs_node_refcnt_lock, but we can't hold this while locking the
+ individual node locks). */
+
+- for (n = 0; n < INOHSZ; n++)
+- for (node = nodehash[n]; node; node = node->dn->hnext)
+- num_nodes++;
++ num_nodes = nodehash_nr_items;
+
+ node_list = alloca (num_nodes * sizeof (struct node *));
+ p = node_list;
diff --git a/debian/patches/fatfs-simplify-expr.patch b/debian/patches/fatfs-simplify-expr.patch
new file mode 100644
index 00000000..e0325db5
--- /dev/null
+++ b/debian/patches/fatfs-simplify-expr.patch
@@ -0,0 +1,22 @@
+commit 2dfdb4737f65a4e969f445f4b19008cf2c17895e
+Author: Justus Winter <4winter@informatik.uni-hamburg.de>
+Date: Wed Apr 30 01:13:47 2014 +0200
+
+ fatfs: simplify expression
+
+ * fatfs/pager.c (add_pager_max_prot): Simplify expression.
+
+diff --git a/fatfs/pager.c b/fatfs/pager.c
+index 8146e64..6180aac 100644
+--- a/fatfs/pager.c
++++ b/fatfs/pager.c
+@@ -1008,8 +1008,7 @@ diskfs_max_user_pager_prot ()
+ max_prot |= upi->max_prot;
+ /* Stop iterating if MAX_PROT is as filled as it is going to
+ get. */
+- return (max_prot
+- == (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE)) ? 1 : 0;
++ return max_prot == (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+ }
+
+ disable_caching (); /* Make any silly pagers go away. */
diff --git a/debian/patches/fatfs-two-pagers.patch b/debian/patches/fatfs-two-pagers.patch
new file mode 100644
index 00000000..4a9d0b9b
--- /dev/null
+++ b/debian/patches/fatfs-two-pagers.patch
@@ -0,0 +1,238 @@
+commit c32e4ca99fc266f2fe87a84ecdb604c83d1fe0cb
+Author: Justus Winter <4winter@informatik.uni-hamburg.de>
+Date: Wed Apr 30 01:10:05 2014 +0200
+
+ fatfs: use two distinct pager buckets for the disk and file pager
+
+ fatfs has two kinds of pagers. One for the files, one for the disk.
+ Previously, both were in the same port bucket.
+
+ If a request for a file pager arrives, it most likely touches some
+ metadata (like the superblock). This is in turn backed by the disk
+ pager, so another request is generated for the disk pager.
+
+ Seperate all pagers clearly by using two port buckets. This will
+ enable us to use a single thread per port bucket in the future.
+
+ * fatfs/pager.c (pager_bucket): Rename to...
+ (disk_pager_bucket): ... this to make the change explicit at every
+ occurrence.
+ (file_pager_bucket): New variable.
+ (service_paging_requests): New function.
+ (create_fat_pager): Also create the file pager.
+ (diskfs_get_filemap): Handout pagers from the file_pager_bucket.
+ (diskfs_shutdown_pager): This is only concerned with the file pager.
+ Simplify code accordingly.
+ (diskfs_sync_everything): Likewise.
+ (diskfs_pager_users): Likewise.
+ (diskfs_max_user_pager_prot): Likewise.
+ (disable_caching): Iterate over both buckets.
+ (enable_caching): Likewise.
+
+diff --git a/fatfs/pager.c b/fatfs/pager.c
+index 6180aac..f855ecf 100644
+--- a/fatfs/pager.c
++++ b/fatfs/pager.c
+@@ -18,12 +18,16 @@
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
+
++#include <error.h>
+ #include <string.h>
+ #include <hurd/store.h>
+ #include "fatfs.h"
+
+-/* A ports bucket to hold pager ports. */
+-struct port_bucket *pager_bucket;
++/* A ports bucket to hold disk pager ports. */
++struct port_bucket *disk_pager_bucket;
++
++/* A ports bucket to hold file pager ports. */
++struct port_bucket *file_pager_bucket;
+
+ /* Mapped image of the FAT. */
+ void *fat_image;
+@@ -752,16 +756,51 @@ pager_dropweak (struct user_pager_info *p __attribute__ ((unused)))
+ {
+ }
+
++/* A top-level function for the paging thread that just services paging
++ requests. */
++static void *
++service_paging_requests (void *arg)
++{
++ struct port_bucket *pager_bucket = arg;
++ ports_manage_port_operations_multithread (pager_bucket,
++ pager_demuxer,
++ 1000,
++ 0,
++ NULL);
++ /* Not reached. */
++ return NULL;
++}
++
+ /* Create the disk pager. */
+ void
+ create_fat_pager (void)
+ {
++ pthread_t thread;
++ pthread_attr_t attr;
++ error_t err;
++
++ /* The disk pager. */
+ struct user_pager_info *upi = malloc (sizeof (struct user_pager_info));
+ upi->type = FAT;
+- pager_bucket = ports_create_bucket ();
+- diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, 0,
++ disk_pager_bucket = ports_create_bucket ();
++ diskfs_start_disk_pager (upi, disk_pager_bucket, MAY_CACHE, 0,
+ bytes_per_sector * sectors_per_fat,
+ &fat_image);
++
++ /* The file pager. */
++ file_pager_bucket = ports_create_bucket ();
++
++#define STACK_SIZE (64 * 1024)
++ pthread_attr_init (&attr);
++ pthread_attr_setstacksize (&attr, STACK_SIZE);
++#undef STACK_SIZE
++
++ /* Make a thread to service file paging requests. */
++ err = pthread_create (&thread, &attr,
++ service_paging_requests, file_pager_bucket);
++ if (err)
++ error (2, err, "pthread_create");
++ pthread_detach (thread);
+ }
+
+ /* Call this to create a FILE_DATA pager and return a send right.
+@@ -800,7 +839,7 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
+ upi->max_prot = prot;
+ diskfs_nref_light (node);
+ node->dn->pager =
+- pager_create (upi, pager_bucket, MAY_CACHE,
++ pager_create (upi, file_pager_bucket, MAY_CACHE,
+ MEMORY_OBJECT_COPY_DELAY, 0);
+ if (node->dn->pager == 0)
+ {
+@@ -881,14 +920,13 @@ diskfs_shutdown_pager ()
+ error_t shutdown_one (void *v_p)
+ {
+ struct pager *p = v_p;
+- if (p != diskfs_disk_pager)
+- pager_shutdown (p);
++ pager_shutdown (p);
+ return 0;
+ }
+
+ write_all_disknodes ();
+
+- ports_bucket_iterate (pager_bucket, shutdown_one);
++ ports_bucket_iterate (file_pager_bucket, shutdown_one);
+
+ pager_sync (diskfs_disk_pager, 1);
+
+@@ -903,13 +941,12 @@ diskfs_sync_everything (int wait)
+ error_t sync_one (void *v_p)
+ {
+ struct pager *p = v_p;
+- if (p != diskfs_disk_pager)
+- pager_sync (p, wait);
++ pager_sync (p, wait);
+ return 0;
+ }
+
+ write_all_disknodes ();
+- ports_bucket_iterate (pager_bucket, sync_one);
++ ports_bucket_iterate (file_pager_bucket, sync_one);
+ pager_sync (diskfs_disk_pager, wait);
+ }
+
+@@ -926,7 +963,8 @@ disable_caching ()
+
+ /* Loop through the pagers and turn off caching one by one,
+ synchronously. That should cause termination of each pager. */
+- ports_bucket_iterate (pager_bucket, block_cache);
++ ports_bucket_iterate (disk_pager_bucket, block_cache);
++ ports_bucket_iterate (file_pager_bucket, block_cache);
+ }
+
+ static void
+@@ -954,7 +992,8 @@ enable_caching ()
+ return 0;
+ }
+
+- ports_bucket_iterate (pager_bucket, enable_cache);
++ ports_bucket_iterate (disk_pager_bucket, enable_cache);
++ ports_bucket_iterate (file_pager_bucket, enable_cache);
+ }
+
+ /* Tell diskfs if there are pagers exported, and if none, then
+@@ -962,9 +1001,9 @@ enable_caching ()
+ int
+ diskfs_pager_users ()
+ {
+- int npagers = ports_count_bucket (pager_bucket);
++ int npagers = ports_count_bucket (file_pager_bucket);
+
+- if (npagers <= 1)
++ if (npagers == 0)
+ return 0;
+
+ if (MAY_CACHE)
+@@ -975,8 +1014,8 @@ diskfs_pager_users ()
+ immediately. XXX */
+ sleep (1);
+
+- npagers = ports_count_bucket (pager_bucket);
+- if (npagers <= 1)
++ npagers = ports_count_bucket (file_pager_bucket);
++ if (npagers == 0)
+ return 0;
+
+ /* Darn, there are actual honest users. Turn caching back on,
+@@ -984,7 +1023,7 @@ diskfs_pager_users ()
+ enable_caching ();
+ }
+
+- ports_enable_bucket (pager_bucket);
++ ports_enable_bucket (file_pager_bucket);
+
+ return 1;
+ }
+@@ -995,17 +1034,15 @@ vm_prot_t
+ diskfs_max_user_pager_prot ()
+ {
+ vm_prot_t max_prot = 0;
+- int npagers = ports_count_bucket (pager_bucket);
++ int npagers = ports_count_bucket (file_pager_bucket);
+
+- if (npagers > 1)
+- /* More than just the disk pager. */
++ if (npagers > 0)
+ {
+ error_t add_pager_max_prot (void *v_p)
+ {
+ struct pager *p = v_p;
+ struct user_pager_info *upi = pager_get_upi (p);
+- if (upi->type == FILE_DATA)
+- max_prot |= upi->max_prot;
++ max_prot |= upi->max_prot;
+ /* Stop iterating if MAX_PROT is as filled as it is going to
+ get. */
+ return max_prot == (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
+@@ -1017,12 +1054,12 @@ diskfs_max_user_pager_prot ()
+ immediately. XXX */
+ sleep (1);
+
+- ports_bucket_iterate (pager_bucket, add_pager_max_prot);
++ ports_bucket_iterate (file_pager_bucket, add_pager_max_prot);
+
+ enable_caching ();
+ }
+
+- ports_enable_bucket (pager_bucket);
++ ports_enable_bucket (file_pager_bucket);
+
+ return max_prot;
+ }
diff --git a/debian/patches/libpager-singlethreaded.patch b/debian/patches/libpager-singlethreaded.patch
index b515dc51..f03ba024 100644
--- a/debian/patches/libpager-singlethreaded.patch
+++ b/debian/patches/libpager-singlethreaded.patch
@@ -1,16 +1,42 @@
-commit 840c3b15ddf9d58cff1ce458cc3fddab3e368254
+commit 18fa27d294185abc9db774f02008f484280ddb33
Author: Justus Winter <4winter@informatik.uni-hamburg.de>
Date: Sun Apr 27 09:16:40 2014 +0200
- libpager: make libpager single-threaded
+ XXX libpager: make libpager single-threaded
- * console/pager.c (
- * ext2fs/pager.c
- * libdiskfs/disk-pager.c
- * storeio/pager.c
+ Previously, libpager used multiple threads to service requests to
+ memory objects. This has proven to be problematic, as paging requests
+ often arrive in batches, resulting in the creation of many hundred
+ threads.
- * libpager/Makefile: Likewise.
- * libpager/chg-compl.c: Likewise.
+ Furthermore, the semantic of paging requests requires that the
+ requests to an object processed in the order the messages were
+ delivered. This was implemented using sequence barriers in
+ _pager_wait_for_seqno, _pager_release_seqno, and
+ _pager_update_seqno{,_p}.
+
+ Unfortunately, this means that not only do we create too many threads,
+ but worse, all but one thread processing requests to an object are
+ asleep most of the time.
+
+ Previous attempts to introduce a fixed upper bound on the number of
+ threads failed because ext2fs (fatfs) used two kinds of pagers managed
+ by the same thread pool. This has been fixed in XXX (YYY).
+
+ Use a single thread to service paging requests. This removes the need
+ for the sequence barriers, remove that code.
+
+ This prevents paging-related thread-storms. It also seems to actually
+ increase the performance of the whole system, as indicated by slightly
+ faster Hurd package builds.
+
+ * console/pager.c (service_paging_requests): Use a single thread.
+ * ext2fs/pager.c (service_paging_requests): Likewise.
+ * fatfs/pager.c (service_paging_requests): Likewise.
+ * libdiskfs/disk-pager.c (service_paging_requests): Likewise.
+ * storeio/pager.c (service_paging_requests): Likewise.
+ * libpager/chg-compl.c: Remove calls to _pager_wait_for_seqno,
+ _pager_release_seqno, _pager_update_seqno, and _pager_update_seqno_p.
* libpager/data-request.c: Likewise.
* libpager/data-return.c: Likewise.
* libpager/data-unlock.c: Likewise.
@@ -21,10 +47,10 @@ Date: Sun Apr 27 09:16:40 2014 +0200
* libpager/object-init.c: Likewise.
* libpager/object-terminate.c: Likewise.
* libpager/pager-create.c: Likewise.
- * libpager/priv.h: Likewise.
- * libpager/seqnos.c: Likewise.
* libpager/stubs.c: Likewise.
+ * libpager/priv.h (struct pager): Drop fields seqno and waitingforseqno.
* libpager/seqnos.c: Remove unused file.
+ * libpager/Makefile (SRCS): Drop seqnos.c.
diff --git a/console/pager.c b/console/pager.c
index 87c36f0..e40ae45 100644
@@ -47,7 +73,7 @@ index 87c36f0..e40ae45 100644
}
diff --git a/ext2fs/pager.c b/ext2fs/pager.c
-index f3e9489..febde8f 100644
+index 017efcc..92e9178 100644
--- a/ext2fs/pager.c
+++ b/ext2fs/pager.c
@@ -1198,11 +1198,9 @@ static void *
@@ -65,6 +91,25 @@ index f3e9489..febde8f 100644
/* Not reached. */
return NULL;
}
+diff --git a/fatfs/pager.c b/fatfs/pager.c
+index f855ecf..623b8d4 100644
+--- a/fatfs/pager.c
++++ b/fatfs/pager.c
+@@ -762,11 +762,9 @@ static void *
+ service_paging_requests (void *arg)
+ {
+ struct port_bucket *pager_bucket = arg;
+- ports_manage_port_operations_multithread (pager_bucket,
+- pager_demuxer,
+- 1000,
+- 0,
+- NULL);
++ ports_manage_port_operations_one_thread (pager_bucket,
++ pager_demuxer,
++ 0);
+ /* Not reached. */
+ return NULL;
+ }
diff --git a/libdiskfs/disk-pager.c b/libdiskfs/disk-pager.c
index 9a0d9d8..6746d4c 100644
--- a/libdiskfs/disk-pager.c
diff --git a/debian/patches/series b/debian/patches/series
index 8662284c..d984ad4e 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -42,8 +42,12 @@ xkb-compat.patch
mach-defpager-protected-payload.patch
ext2fs-two-pagers.patch
+fatfs-simplify-expr.patch
+fatfs-two-pagers.patch
#ext2fs-cache-superblock.patch
libpager-singlethreaded.patch
libpager-drop-seqnos.patch
ext2fs-improve-diskfs_node_iterate.patch
+fatfs-improve-diskfs_node_iterate.patch
+tmpfs-improve-diskfs_node_iterate.patch
xxx-fix-build-paper-over-gnumach-bug.patch
diff --git a/debian/patches/tmpfs-improve-diskfs_node_iterate.patch b/debian/patches/tmpfs-improve-diskfs_node_iterate.patch
new file mode 100644
index 00000000..fbb013bd
--- /dev/null
+++ b/debian/patches/tmpfs-improve-diskfs_node_iterate.patch
@@ -0,0 +1,53 @@
+commit 328d69406ec81b4b8248f46fafa205c6745ef083
+Author: Justus Winter <4winter@informatik.uni-hamburg.de>
+Date: Wed Apr 30 02:08:41 2014 +0200
+
+ tmpfs: improve diskfs_node_iterate
+
+ Currently, diskfs_node_iterate iterates twice over all nodes. The
+ first time only to determine the number of nodes currently in the
+ cache. Simply count them instead.
+
+ * tmpfs/node.c (all_nodes_nr_items): New variable.
+ (diskfs_node_norefs): Decrement all_nodes_nr_items.
+ (diskfs_cached_lookup): Increment all_nodes_nr_items.
+ (diskfs_node_iterate): Fix the type of num_nodes, use all_nodes_nr_items.
+
+diff --git a/tmpfs/node.c b/tmpfs/node.c
+index bc0ad64..3925d00 100644
+--- a/tmpfs/node.c
++++ b/tmpfs/node.c
+@@ -30,6 +30,7 @@ unsigned int num_files;
+ static unsigned int gen;
+
+ struct node *all_nodes;
++static size_t all_nodes_nr_items;
+
+ error_t
+ diskfs_alloc_node (struct node *dp, mode_t mode, struct node **npp)
+@@ -122,6 +123,7 @@ diskfs_node_norefs (struct node *np)
+ np->dn->hnext->dn->hprevp = np->dn->hprevp;
+ np->dn->hnext = 0;
+ np->dn->hprevp = 0;
++ all_nodes_nr_items -= 1;
+ }
+
+ free (np);
+@@ -186,6 +188,7 @@ diskfs_cached_lookup (ino_t inum, struct node **npp)
+ dn->hnext->dn->hprevp = &dn->hnext;
+ dn->hprevp = &all_nodes;
+ all_nodes = np;
++ all_nodes_nr_items += 1;
+ pthread_spin_unlock (&diskfs_node_refcnt_lock);
+
+ st = &np->dn_stat;
+@@ -233,8 +236,7 @@ diskfs_node_iterate (error_t (*fun) (struct node *))
+ diskfs_node_refcnt_lock, but we can't hold this while locking the
+ individual node locks). */
+
+- for (node = all_nodes; node != 0; node = node->dn->hnext)
+- num_nodes++;
++ num_nodes = all_nodes_nr_items;
+
+ p = node_list = alloca (num_nodes * sizeof (struct node *));
+ for (node = all_nodes; node != 0; node = node->dn->hnext)