summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2014-05-29Merge branch 'master' of git.savannah.gnu.org:/srv/git/hurd/hurdSamuel Thibault
2014-05-29Disable linking when cross-compilingLudovic Courtès
* configure.ac: Call AC_NO_EXECUTABLES when cross-compiling.
2014-05-29libdiskfs: use a hash table for the name cacheJustus Winter
Previously, name cache lookup operation completed in O(n) time. This means that making the cache too large would decrease the performance. Therefore it was required to tune the size. Implement the name cache using a hash table. We use buckets of a fixed size. We approximate the least-frequently used cache algorithm by counting the number of lookups using saturating arithmetic in the two lowest bits of the pointer to the name. Using this strategy we achieve a constant worst-case lookup and insertion time. Since we are not bound by the size of the cache anymore, increase its size from 200 to 1024. * libdiskfs/name-cache.c: Implement the name cache using a hash table. (diskfs_enter_lookup_cache): Change accordingly. (diskfs_purge_lookup_cache): Likewise. (diskfs_check_lookup_cache): Likewise. Also, hard code a cache miss for the parent of the root directory and merge unlocking and releasing of node references.
2014-05-29libdiskfs: remove the statistics code from the name cacheJustus Winter
The current name cache lookup operation completes in O(n) time. This means that making the cache too large would decrease the performance. Therefore it was required to tune the size, hence the need for statistics. We will use a data structure with worst case constant lookup times in the future, removing the need to fine tune the cache size. * libdiskfs/name-cache.c: Remove the statistics code from the name cache.
2014-05-28trans/fakeroot: use netfs_node_netnode instead of np->nnJustus Winter
When using fat nodes, expressions of the form E->nn can be rewritten as netfs_node_netnode (E). This is much faster as it only involves a offset calculation. For reference, I used the following semantic patch to create the patch: @@ expression E; @@ - E->nn + netfs_node_netnode (E) * trans/fakeroot.c: Use netfs_node_netnode instead of np->nn.
2014-05-28trans/fakeroot: use fat nodes to simplify the node cacheJustus Winter
Previously, fakeroot stored netnodes in the hash table. But we are not interested in a cache for netnodes, we need a node cache. So fakeroot kept pointers to the associated node object in each netnode object. Use fat netfs nodes, which combine node and netnode objects. * trans/fakeroot.c (struct netnode): Remove np. (idport_ihash): Fix ihash location pointer offset. (new_node): Allocate fat nodes, store the node pointer in the hash table. (netfs_node_norefs): Adjust accordingly. (netfs_S_dir_lookup): Likewise.
2014-05-28libnetfs: add netfs_make_node_alloc to allocate fat nodesJustus Winter
libnetfs has two kind of nodes, struct node and struct netnode. struct node is used to store libnetfs specific data, while struct netnode contains user supplied data. Previously, both objects were allocated separatly, and a pointer from the node to the netnode provided a mapping from the former to the latter. Provide a function netfs_make_node_alloc that allocates both nodes in a contiguous region. This reduces the memory allocation overhead when creating nodes. It also makes the relation between node and netnode a simple offset calculation. Provide two functions to compute the netnode address from the node address and vice-versa. Most notably, this makes implementing a cache on top of libnetfs easier. Auxiliary data for the cache can be stored in the user-defined netnode, and the fat node can be used as the value. * libnetfs/make-node.c (init_node): Move initialization here. (netfs_make_node): Use init_node. (netfs_make_node_alloc): New function to allocate fat nodes. * libnetfs/netfs.h (netfs_make_node_alloc): New declaration. (_netfs_sizeof_struct_node): Likewise. (netfs_node_netnode): Compute netnode address from node address. (netfs_netnode_node): And vice-versa. * libnetfs/init-init.c (_netfs_sizeof_struct_node): New variable.
2014-05-28libdiskfs: add diskfs_make_node_alloc to allocate fat nodesJustus Winter
libdiskfs has two kind of nodes, struct node and struct netnode. struct node is used to store libdiskfs specific data, while struct netnode contains user supplied data. Previously, both objects were allocated separatly, and a pointer from the node to the netnode provided a mapping from the former to the latter. Provide a function diskfs_make_node_alloc that allocates both nodes in a contiguous region. This reduces the memory allocation overhead when creating nodes. It also makes the relation between node and netnode a simple offset calculation. Provide two functions to compute the netnode address from the node address and vice-versa. Most notably, this makes implementing a cache on top of libdiskfs easier. Auxiliary data for the cache can be stored in the user-defined netnode, and the fat node can be used as the value. * libdiskfs/node-make.c (init_node): Move initialization here. (diskfs_make_node): Use init_node. (diskfs_make_node_alloc): New function to allocate fat nodes. * libdiskfs/diskfs.h (diskfs_make_node_alloc): New declaration. (_diskfs_sizeof_struct_node): Likewise. (diskfs_node_disknode): Compute disknode address from node address. (diskfs_disknode_node): And vice-versa. * libdiskfs/init-init.c (_diskfs_sizeof_struct_node): New variable.
2014-05-26libtrivfs: lock-less reference counting for trivfs_peropen objectsJustus Winter
* libtrivfs/trivfs.h (struct trivfs_peropen): Use refcount_t for field refcnt. (struct trivfs_control): Remove unused field lock. * libtrivfs/cntl-create.c (trivfs_create_control): Drop the mutex initialization. * libtrivfs/io-reauthenticate.c (trivfs_S_io_reauthenticate): Adjust accordingly. * libtrivfs/io-restrict-auth.c (trivfs_S_io_restrict_auth): Likewise. * libtrivfs/open.c (trivfs_open): Initialize refcnt. * libtrivfs/protid-clean.c (trivfs_clean_protid): Likewise. * libtrivfs/protid-dup.c (trivfs_protid_dup): Likewise.
2014-05-26libihash: do not use an integer hash function by defaultJustus Winter
Recently libihash was changed to use an integer hash function on the keys in an attempt to reduce the rate of collisions (2d898893), which has long been assumed to be high. Richard Braun was kind enough to run some benchmarks. He observed: "1/ Using an extremely simple microbenchmark [1] that merely inserts keys, either random integers or sequential ones to match the way port names are managed, it seems that the previous code, despite its apparent flaws, did quite well. [1] http://darnassus.sceen.net/gitweb/rbraun/ihtest.git Using an integer hashing function actually reduces performance on the sequential integer test case. It makes sense because, considering a set of consecutive integers starting from 0, and a hash table that always has more slots than items, a modulo is a perfect hash function. Even when taking into account that only names for receive rights are normally managed with libihash, i.e. that keys aren't actually sequential, they are almost all equally distributed, leading to very few collisions. Therefore, as a third option, I've removed the hashing function, leaving only a fast modulo (an AND) and this variant provided the best raw results. 2/ I've also built hurd packages multiple times and got average build times with each variant (previous, new, new without hash function) and here are the results I obtained respectively : 52m59s, 52m31s, 52m22s." Do not use the integer hash function on the keys by default. * libihash/ihash.c (murmur3_mix32): Remove now unused function. (find_index): Use the fast division method to derive the index. (add_one): Likewise. Also, update the comment to reflect the current hashing method.
2014-05-26libdiskfs: fix node leak in the name cacheJustus Winter
* libdiskfs/name-cache.c (diskfs_check_lookup_cache): Release node reference in a special case of lookup failure.
2014-05-26trans/mtab: fix initializationJustus Winter
* trans/mtab.c (main): Fix initialization of mtab in one-shot mode.
2014-05-26ext2fs: fix diskfs_pager_usersJustus Winter
This fixes a bug introduced in 86122789. * ext2fs/pager.c (diskfs_pager_users): We count file_pager_bucket, which does not include the disk pagers. Fix condition accordingly.
2014-05-26libpager: drop unused fields from struct pagerJustus Winter
* libpager/priv.h (struct pager): Drop fields next, pprev.
2014-05-26term: fix memory leakJustus Winter
I tested this change for some days and have not experienced any problems with it. * term/users.c (pi_destroy_hook): Fix memory leak.
2014-05-26Avoid compiler warning about empty bodiesJustus Winter
Make empty bodies of control flow statements more explicit. Doing so will allow us to use stricter compiler settings. This would have cought 4ece292c. * console-client/xkb/xkb.c: Make empty bodies more explicit * libpipe/pipe.c: Likewise. * mach-defpager/default_pager.c: Likewise. * pfinet/linux-src/net/ipv4/fib_hash.c: Likewise. * pflocal/connq.c: Likewise. * pflocal/socket.c: Likewise.
2014-05-26libdiskfs: fix type of dir_cache_id, node_cache_idJustus Winter
* libdiskfs/name-cache.c (struct lookup_cache): Fix type of dir_cache_id, node_cache_id.
2014-05-26pfinet: add missing includeJustus Winter
* pfinet/linux-src/include/net/addrconf.h: Include ipv6.h.
2014-05-26exec: add missing includesJustus Winter
* exec/exec.c: Include mach/gnumach.h. * exec/main.c: Include device/device.h.
2014-05-26libdiskfs: lock-less reference counting for peropen objectsJustus Winter
* libdiskfs/diskfs.h (struct peropen): Use refcount_t for field refcnt. * libdiskfs/peropen-make.c (diskfs_make_peropen): Initialize refcnt. * libdiskfs/peropen-rele.c (diskfs_release_peropen): Adjust accordingly. * libdiskfs/protid-make.c (diskfs_start_protid): Likewise. Also, the node must no longer be locked, adjust comment accordingly. (diskfs_create_protid): Likewise.
2014-05-22include: install refcount.hJustus Winter
* include/Makefile (installhdrs): Add refcount.h.
2014-05-22trans/fakeroot: override fshelp_isownerJustus Winter
As of recently, fakeroot would fail to create symlinks: % fakeroot-hurd ln -s foo a ln: failed to create symbolic link ‘a’: Operation not permitted Fix this by overriding fshelp_isowner. Various netfs functions will call fshelp_isowner to check whether USER is allowed to do some operation. As fakeroot is not running within the fakeauth'ed environment, USER contains the real user. I have no explanation why this ever worked. * trans/fakeroot.c (fshelp_isowner): New function.
2014-05-22include: add lock-less reference counting primitivesJustus Winter
* include/refcount.h: New file.
2014-05-22libihash: add hurd_ihash_get_loadJustus Winter
* libihash/ihash.c (hurd_ihash_add): Move the code computing the load factor of the hash table... * libihash/ihash.h (hurd_ihash_get_load): ... here, together with the comment describing the method and the rationale for chosing binary percent.
2014-05-22libihash: fix typoJustus Winter
* libihash/ihash.c (hurd_ihash_add): Fix typo.
2014-05-16proc: move translation functions to mig-decls.hJustus Winter
* proc/hash.c (reqport_find): Move this function... * proc/proc.h (process_drop): ... and this... * proc/mig-decls.h: ... here and rename them. * proc/mig-mutate.h: Update accordingly.
2014-05-16trans/fakeroot: use C99-style struct initializationJustus Winter
* trans/fakeroot.c (main): Use C99-style struct initialization to initialize argp. This avoids a warning about missing field initializers.
2014-05-16trans/fakeroot: fix comparison between signed and unsignedJustus Winter
* trans/fakeroot.c (netfs_attempt_chown): Fix comparison between signed and unsigned integer expressions.
2014-05-16trans/fakeroot: remove spurious semicolonJustus Winter
A spurious semicolon caused a control flow bug in check_openmodes, leading to a port leak. * trans/fakeroot.c (check_openmodes): Remove spurious semicolon.
2014-05-13libihash: use fast binary scaling to determine the loadJustus Winter
Expressing the maximum load in binary percent (where 128b% corresponds to 100%) allows us to use fast binary scaling to determine if the maximum load has been reached without losing precision. Furthermore, the previously used expression 'ht->nr_items * 100' overflows int at 2^25 (unsigned int at 2^26). When a hash table reached that limit, it would fail to resize and fill up the table. This change fixes that. * libihash/ihash.c (hurd_ihash_set_max_load): Update the comment. (hurd_ihash_add): Use fast binary scaling to determine the current load. * libihash/ihash.h (struct hurd_ihash): Update comment for max_load. (hurd_ihash_set_max_load): Update the comment.
2014-05-13libihash: use linear probing and fast modulo operationJustus Winter
libihash uses open addressing. Previously, quadratic probing in both directions was used to resolve collisions. Quadratic probing might result in a less efficient use of caches. Also, prime numbers of the form 4 * i + 3 were used as array sizes. This was used in combination with the integer modulo operation for hashing. It has been known for some time that libihash suffers from collisions, so a integer hash function is now applied to the keys to derive the index. Use linear probing instead. Also, use powers of two for the array sizes, so a bit mask can be used for the modulo operation. * libihash/ihash.c (ihash_sizes, ihash_nsizes): Remove. (find_index): Use linear probing and fast modulo operation. (add_one): Likewise. * libihash/ihash.h (HURD_IHASH_MIN_SIZE): New macro.
2014-05-13libihash: use an integer hash function on the keysJustus Winter
Use an integer hash function to derive the index from the key. This should reduce the number of collisions. * libihash/ihash.c (hash_int32): New function. (find_index): Use hash_int32 on the key to derive the index. (add_one): Likewise.
2014-05-13libihash: fix type of max_loadJustus Winter
Previously, int was used for the field max_load of struct hurd_ihash. There is no reason for this as far as I can tell. Furthermore, hurd_ihash_set_max_load takes an unsigned int max_load. * libihash/ihash.h (struct hurd_ihash): Use unsigned int for field max_load.
2014-05-13libihash: reduce the default maximum load factor to 75%Justus Winter
The performance of hash tables depend critically on a low number of hash collisions. As the table fills up, the chance of collisions necessarily raises. Previously, libihash resized the hash table when the load exceeded 80%. This seems a bit optimistic (e. g. java.util.Hashtable uses 75% as default). * libihash/ihash.h (HURD_IHASH_MAX_LOAD_DEFAULT): Set to 75.
2014-05-13ext2fs: cache the superblockJustus Winter
Previously, the superblock was mmaped and a pointer stored in sblock by map_hypermetadata. This memory is backed by our disk pager. This is rather unfortunate, as this means that whenever we read a value from that location, we might generate a request our disk pager. This amplifies the so-called thread-storm problem. Rather than relying on a mmaped region of memory, just use the data loaded by get_hypermetadata. * ext2fs/hyper.c (get_hypermetadata): Do not free sblock. (mapped_sblock): New variable. (map_hypermetadata): Map the superblock to mapped_sblock instead. (diskfs_set_hypermetadata): Copy superblock into mapped_superblock. * ext2fs/ext2fs.h (get_hypermetadata, map_hypermetadata): Adjust comments accordingly.
2014-05-05fatfs: use two distinct pager buckets for the disk and file pagerJustus Winter
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.
2014-05-05libports: unlock _ports_lock on malloc failureJustus Winter
* libports/bucket-iterate.c (_ports_bucket_class_iterate): Unlock _ports_lock on malloc failure.
2014-05-05ext2fs: use two distinct pager buckets for the disk and file pagerJustus Winter
ext2fs 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. * ext2fs/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_disk_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.
2014-04-30tmpfs: improve diskfs_node_iterateJustus Winter
Currently, diskfs_node_iterate iterates twice over all nodes. The first time only to determine the number of nodes. Simply count them instead. * tmpfs/node.c (all_nodes_nr_items): New variable. (diskfs_free_node): Decrement all_nodes_nr_items. (diskfs_node_norefs): Likewise. (diskfs_cached_lookup): Increment all_nodes_nr_items. (diskfs_node_iterate): Fix type of sum_nodes, use all_nodes_nr_items.
2014-04-30fatfs: improve diskfs_node_iterateJustus Winter
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.
2014-04-30ext2fs: improve diskfs_node_iterateJustus Winter
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. * ext2fs/inode.c (nodehash_nr_items): New variable. (diskfs_cached_lookup): Increment nodehash_nr_items. (diskfs_node_norefs): Decrement nodehash_nr_items. (diskfs_node_iterate): Fix the type of num_nodes, use nodehash_nr_items.
2014-04-30fatfs: simplify expressionJustus Winter
* fatfs/pager.c (add_pager_max_prot): Simplify expression.
2014-04-29libports: reduce malloc overhead in _ports_bucket_class_iterateJustus Winter
_ports_bucket_class_iterate creates a snapshot of the buckets hash table. This is done so that the lock protecting the hash table can be released while we iterate over the snapshot. Formerly, a linked list was used to store the snapshot. As the maximal number of items is known, using an array is much simpler. _ports_bucket_class_iterate implements both ports_bucket_iterate and ports_class_iterate. For this change might make ports_class_iterate less efficient memory-wise if the number of ports belonging to the class is low with respect to the number of ports in the bucket. If this happens, we allocate too much. Alleviate this by releasing unused memory. On the other hand, the array representation is more compact. Furthermore a survey of the Hurd code revealed that ports_class_iterate is rarely used, while ports_bucket_iterate is used more often, most prominently in paging code. * libports/bucket-iterate.c (_ports_bucket_class_iterate): Use an array instead of a linked list.
2014-04-29ext2fs: simplify expressionJustus Winter
* ext2fs/pager.c (add_pager_max_prot): Simplify expression.
2014-04-29ext2fs: fix type of inumJustus Winter
Previously, inum was of type int, whereas dino_ref expects ino_t. On Hurd/x86 the former is 32 bit wide, the latter 64. If dino_ref is inlined, this does not seem to pose a problem, but if ext2fs is compiled with -O0, this most likely results in an invalid memory access. * ext2fs/ialloc.c (ext2_alloc_inode): Use type ino_t for inum.
2014-04-29exec: abbreviate the task name if necessaryJustus Winter
* exec/exec.c (do_exec): If the formatted task name exceeds TASK_NAME_SIZE, abbreviate it.
2014-04-29libports: work around bugs in server terminationJustus Winter
Some servers use ports_manage_port_operations_one_thread to process requests and terminate when it returns. Since many of them don't detach before shutting down, a client may receive an error if its request arrived while the server is shutting down. Prevent those spurious errors by forcing ports_manage_port_operations_one_thread not to return. This is the same change as 235491231bdd1fd93507c835767503f047e10b91 introduced for ports_manage_port_operations_multithread. * libports/manage-one-thread.c (ports_manage_port_operations_one_thread): Force timeout to 0.
2014-04-29libdiskfs: set the default sync interval to 30 secondsJustus Winter
The default sync interval has been changed in 9e55fdd7 from 30 to 5 seconds. This change was not reflected in the documentation. At least for current hardware, using 30 seconds instead of just 5 alleviates the thread-storm problem. Make 30 seconds the default again. * libdiskfs/priv.h (DEFAULT_SYNC_INTERVAL): Set to 30 seconds.
2014-04-22Add missing receiver lookup fixSamuel Thibault
following 7cb7fa6b3a0d02985b4a51f7823bc1cb631d6bfa * proc/mgt.c (S_proc_exception_raise): Do not dereference e on returning EINVAL, the translation functions does it for us.
2014-04-22Merge branch 'master' of git.savannah.gnu.org:/srv/git/hurd/hurdSamuel Thibault