* [PATCH] fix integer overflow in H-TCP congestion control @ 2006-10-24 14:17 Gavin McCullagh 2006-10-24 22:30 ` David Miller 0 siblings, 1 reply; 15+ messages in thread From: Gavin McCullagh @ 2006-10-24 14:17 UTC (permalink / raw) To: NetDev; +Cc: Douglas Leith, Baruch Even When using H-TCP with a single flow on a 500Mbit connection (or less actually), alpha can exceed 65000, so alpha needs to be a u32. Signed-off-by: Gavin McCullagh <gavin.mccullagh@nuim.ie> Signed-off-by: Doug Leith <doug.leith@nuim.ie> diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c index 6edfe5e..8072b6d 100644 --- a/net/ipv4/tcp_htcp.c +++ b/net/ipv4/tcp_htcp.c @@ -23,7 +23,7 @@ module_param(use_bandwidth_switch, int, MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher"); struct htcp { - u16 alpha; /* Fixed point arith, << 7 */ + u32 alpha; /* Fixed point arith, << 7 */ u8 beta; /* Fixed point arith, << 7 */ u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */ u32 last_cong; /* Time since last congestion event end */ ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH] fix integer overflow in H-TCP congestion control 2006-10-24 14:17 [PATCH] fix integer overflow in H-TCP congestion control Gavin McCullagh @ 2006-10-24 22:30 ` David Miller 2006-10-25 8:47 ` Gavin McCullagh 0 siblings, 1 reply; 15+ messages in thread From: David Miller @ 2006-10-24 22:30 UTC (permalink / raw) To: gavin.mccullagh; +Cc: netdev, doug.leith, baruch Your patch doesn't apply, your email client turned the tab characters in the patch into spaces. Please fix and resubmit, thank you. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] fix integer overflow in H-TCP congestion control 2006-10-24 22:30 ` David Miller @ 2006-10-25 8:47 ` Gavin McCullagh 2006-10-26 6:06 ` David Miller 0 siblings, 1 reply; 15+ messages in thread From: Gavin McCullagh @ 2006-10-25 8:47 UTC (permalink / raw) To: David Miller; +Cc: netdev, doug.leith, baruch When using H-TCP with a single flow on a 500Mbit connection (or less actually), alpha can exceed 65000, so alpha needs to be a u32. Signed-off-by: Gavin McCullagh <gavin.mccullagh@nuim.ie> Signed-off-by: Doug Leith <doug.leith@nuim.ie> diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c index 6edfe5e..8072b6d 100644 --- a/net/ipv4/tcp_htcp.c +++ b/net/ipv4/tcp_htcp.c @@ -23,7 +23,7 @@ module_param(use_bandwidth_switch, int, MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher"); struct htcp { - u16 alpha; /* Fixed point arith, << 7 */ + u32 alpha; /* Fixed point arith, << 7 */ u8 beta; /* Fixed point arith, << 7 */ u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */ u32 last_cong; /* Time since last congestion event end */ ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH] fix integer overflow in H-TCP congestion control 2006-10-25 8:47 ` Gavin McCullagh @ 2006-10-26 6:06 ` David Miller 2006-10-31 18:48 ` [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable Eric Dumazet 0 siblings, 1 reply; 15+ messages in thread From: David Miller @ 2006-10-26 6:06 UTC (permalink / raw) To: gavin.mccullagh; +Cc: netdev, doug.leith, baruch From: Gavin McCullagh <gavin.mccullagh@nuim.ie> Date: Wed, 25 Oct 2006 09:47:26 +0100 > When using H-TCP with a single flow on a 500Mbit connection (or less > actually), alpha can exceed 65000, so alpha needs to be a u32. > > Signed-off-by: Gavin McCullagh <gavin.mccullagh@nuim.ie> > Signed-off-by: Doug Leith <doug.leith@nuim.ie> Applied, thank you. ^ permalink raw reply [flat|nested] 15+ messages in thread
* [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable. 2006-10-26 6:06 ` David Miller @ 2006-10-31 18:48 ` Eric Dumazet 2006-11-01 7:19 ` David Miller 2006-11-22 18:00 ` [PATCH] [NET] dont insert socket " Eric Dumazet 0 siblings, 2 replies; 15+ messages in thread From: Eric Dumazet @ 2006-10-31 18:48 UTC (permalink / raw) To: David Miller; +Cc: netdev, linux-kernel [-- Attachment #1: Type: text/plain, Size: 1629 bytes --] Hi David Here is the patch I cooked after our mail exchange. (was [RFC] Any strong reason why socket dentries are hashed in global dentry_hashtable ) If necessary, I could split this patch in 4 elementary patches. I chose to sent it as one patch for initial discussion. [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable. We currently insert sockets/pipes dentries into the global dentry hashtable. This is *useless* because there is currently no way these entries can be used for a lookup(). (/proc/xxx/fd/xxx uses a different mechanism) Machines with a lot of sockets/pipes might suffer from longer chains in dentry hashtable. The goals of this patch are : [0] No more insertion in hashtable of sockets/pipes dentries. [1] Introduction of a DENTRY_DELETED flag, that can distinguish dentries that were deleted and others in d_path(). (previous code was using d_unhashed()) [2] Small optimization to bypass RCU freeing in d_free() for dentries that were never hashed (like sockets and pipes). Such dentries dont have to wait a RCU grace period. [3] Plug socket code to use d_instantiate() instead of d_hash() (No more need for a private d_delete function, and dentry_operations) [4] Plug pipe code to use d_instantiate() instead of d_hash() (No more need for a private d_delete function, and dentry_operations) Another step would be to eliminate dentries for sockets/pipes, but that's another story. (Or at least allocate them from a separate kmem_cache_t as they are not reclaimable, and they might be smaller than a full dentry) Signed-off-by: Eric Dumazet <dada1@cosmosbay.com> [-- Attachment #2: dcache.patch --] [-- Type: text/plain, Size: 3652 bytes --] --- linux-2.6.19-rc4/include/linux/dcache.h 2006-10-31 17:38:09.000000000 +0100 +++ linux-2.6.19-rc4-ed/include/linux/dcache.h 2006-10-31 17:39:15.000000000 +0100 @@ -175,6 +175,7 @@ #define DCACHE_UNHASHED 0x0010 #define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched */ +#define DCACHE_DELETED 0x0040 /* dentry was deleted */ extern spinlock_t dcache_lock; --- linux-2.6.19-rc4/fs/dcache.c 2006-10-31 17:39:25.000000000 +0100 +++ linux-2.6.19-rc4-ed/fs/dcache.c 2006-10-31 18:37:26.000000000 +0100 @@ -68,15 +68,19 @@ .age_limit = 45, }; -static void d_callback(struct rcu_head *head) +static void __d_free(struct dentry *dentry) { - struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu); - if (dname_external(dentry)) kfree(dentry->d_name.name); kmem_cache_free(dentry_cache, dentry); } +static void d_callback(struct rcu_head *head) +{ + struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu); + __d_free(dentry); +} + /* * no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry * inside dcache_lock. @@ -85,7 +89,11 @@ { if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release(dentry); - call_rcu(&dentry->d_u.d_rcu, d_callback); + /* if dentry was never inserted into hash, immediate free is OK */ + if (dentry->d_hash.pprev == NULL) + __d_free(dentry); + else + call_rcu(&dentry->d_u.d_rcu, d_callback); } /* @@ -1376,6 +1384,7 @@ return; } + dentry->d_flags |= DCACHE_DELETED; if (!d_unhashed(dentry)) __d_drop(dentry); @@ -1749,7 +1758,7 @@ *--end = '\0'; buflen--; - if (!IS_ROOT(dentry) && d_unhashed(dentry)) { + if (!IS_ROOT(dentry) && (dentry->d_flags & DCACHE_DELETED)) { buflen -= 10; end -= 10; if (buflen < 0) --- linux-2.6.19-rc4/net/socket.c 2006-10-31 17:53:34.000000000 +0100 +++ linux-2.6.19-rc4-ed/net/socket.c 2006-10-31 18:39:06.000000000 +0100 @@ -304,13 +304,6 @@ .kill_sb = kill_anon_super, }; -static int sockfs_delete_dentry(struct dentry *dentry) -{ - return 1; -} -static struct dentry_operations sockfs_dentry_operations = { - .d_delete = sockfs_delete_dentry, -}; /* * Obtains the first available file descriptor and sets it up for use. @@ -360,8 +353,9 @@ if (unlikely(!file->f_dentry)) return -ENOMEM; - file->f_dentry->d_op = &sockfs_dentry_operations; - d_add(file->f_dentry, SOCK_INODE(sock)); + /* Dont insert socket dentry into global dentry hashtable */ + d_instantiate(file->f_dentry, SOCK_INODE(sock)); + file->f_vfsmnt = mntget(sock_mnt); file->f_mapping = file->f_dentry->d_inode->i_mapping; --- linux-2.6.19-rc4/fs/pipe.c 2006-10-31 18:53:21.000000000 +0100 +++ linux-2.6.19-rc4-ed/fs/pipe.c 2006-10-31 18:55:20.000000000 +0100 @@ -828,14 +828,6 @@ } static struct vfsmount *pipe_mnt __read_mostly; -static int pipefs_delete_dentry(struct dentry *dentry) -{ - return 1; -} - -static struct dentry_operations pipefs_dentry_operations = { - .d_delete = pipefs_delete_dentry, -}; static struct inode * get_pipe_inode(void) { @@ -891,17 +883,15 @@ if (!inode) goto err_file; - sprintf(name, "[%lu]", inode->i_ino); + this.len = sprintf(name, "[%lu]", inode->i_ino); this.name = name; - this.len = strlen(name); this.hash = inode->i_ino; /* will go */ err = -ENOMEM; dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); if (!dentry) goto err_inode; - - dentry->d_op = &pipefs_dentry_operations; - d_add(dentry, inode); + /* Dont insert pipe dentry into global dentry hashtable */ + d_instantiate(dentry, inode); f->f_vfsmnt = mntget(pipe_mnt); f->f_dentry = dentry; f->f_mapping = inode->i_mapping; ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable. 2006-10-31 18:48 ` [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable Eric Dumazet @ 2006-11-01 7:19 ` David Miller 2006-11-01 8:21 ` Eric Dumazet 2006-11-01 13:54 ` Eric Dumazet 2006-11-22 18:00 ` [PATCH] [NET] dont insert socket " Eric Dumazet 1 sibling, 2 replies; 15+ messages in thread From: David Miller @ 2006-11-01 7:19 UTC (permalink / raw) To: dada1; +Cc: netdev, linux-kernel From: Eric Dumazet <dada1@cosmosbay.com> Date: Tue, 31 Oct 2006 19:48:48 +0100 > We currently insert sockets/pipes dentries into the global dentry > hashtable. This is *useless* because there is currently no way > these entries can be used for a lookup(). (/proc/xxx/fd/xxx uses a > different mechanism) It turns out that while procfs uses a different "mechanism", those procfs symlinks do point to the real socket dentry, so when you readlink() on it you do d_path() on the real socket dentry. If you unhash these things, I'm pretty sure you'll see an ugly "(deleted)" at the end of the symlink string for /proc/$pid/fd/$X files that are sockets or something like that. Al Viro just suggested a way around this to me: 1) Just mark the dentry HASHED by hand in the dentry flags, but don't actually hash it. 2) Create a special dentry->d_deleted method for sockets that returns 0 and clears by hand the HASHED flag bit in the dentry (see what dput() does when this happens). It's an abuse but it will work. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable. 2006-11-01 7:19 ` David Miller @ 2006-11-01 8:21 ` Eric Dumazet 2006-11-01 8:34 ` David Miller 2006-11-01 8:38 ` Al Viro 2006-11-01 13:54 ` Eric Dumazet 1 sibling, 2 replies; 15+ messages in thread From: Eric Dumazet @ 2006-11-01 8:21 UTC (permalink / raw) To: David Miller; +Cc: netdev, linux-kernel David Miller a écrit : > From: Eric Dumazet <dada1@cosmosbay.com> > Date: Tue, 31 Oct 2006 19:48:48 +0100 > >> We currently insert sockets/pipes dentries into the global dentry >> hashtable. This is *useless* because there is currently no way >> these entries can be used for a lookup(). (/proc/xxx/fd/xxx uses a >> different mechanism) > > It turns out that while procfs uses a different "mechanism", those > procfs symlinks do point to the real socket dentry, so when you > readlink() on it you do d_path() on the real socket dentry. > > If you unhash these things, I'm pretty sure you'll see an ugly > "(deleted)" at the end of the symlink string for /proc/$pid/fd/$X > files that are sockets or something like that. No no, my patch takes care of that. You still see the right link for pipes and sockets on /proc/$pid/fd/XXX And " (deleted)" is correctly added to deleted files. > > Al Viro just suggested a way around this to me: > > 1) Just mark the dentry HASHED by hand in the dentry flags, but don't > actually hash it. > > 2) Create a special dentry->d_deleted method for sockets that returns > 0 and clears by hand the HASHED flag bit in the dentry (see what > dput() does when this happens). > > It's an abuse but it will work. > Why hack when a proper thing can be done ? ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable. 2006-11-01 8:21 ` Eric Dumazet @ 2006-11-01 8:34 ` David Miller 2006-11-01 8:38 ` Al Viro 1 sibling, 0 replies; 15+ messages in thread From: David Miller @ 2006-11-01 8:34 UTC (permalink / raw) To: dada1; +Cc: netdev, linux-kernel From: Eric Dumazet <dada1@cosmosbay.com> Date: Wed, 01 Nov 2006 09:21:06 +0100 > No no, my patch takes care of that. > > You still see the right link for pipes and sockets on /proc/$pid/fd/XXX > > And " (deleted)" is correctly added to deleted files. I see. Excellent :-) ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable. 2006-11-01 8:21 ` Eric Dumazet 2006-11-01 8:34 ` David Miller @ 2006-11-01 8:38 ` Al Viro 2006-11-01 8:42 ` Al Viro 2006-11-01 9:04 ` Eric Dumazet 1 sibling, 2 replies; 15+ messages in thread From: Al Viro @ 2006-11-01 8:38 UTC (permalink / raw) To: Eric Dumazet; +Cc: David Miller, netdev, linux-kernel On Wed, Nov 01, 2006 at 09:21:06AM +0100, Eric Dumazet wrote: > And " (deleted)" is correctly added to deleted files. The hell it will. touch a touch b exec 5<a mv b a ls -l /proc/$$/fd/5 With your patch and without it, please. PS: getting rid of socket dentries is a bad idea with the capital "Fuck, No". For those who want to see where does that path lead and are attracted to trainwrecks in general I can recommend *BSD socket handling. They have paid quite painfully for lack of proper vnodes. It's simply not worth the resulting trouble. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable. 2006-11-01 8:38 ` Al Viro @ 2006-11-01 8:42 ` Al Viro 2006-11-01 9:04 ` Eric Dumazet 1 sibling, 0 replies; 15+ messages in thread From: Al Viro @ 2006-11-01 8:42 UTC (permalink / raw) To: Eric Dumazet; +Cc: David Miller, netdev, linux-kernel On Wed, Nov 01, 2006 at 08:38:11AM +0000, Al Viro wrote: > On Wed, Nov 01, 2006 at 09:21:06AM +0100, Eric Dumazet wrote: > > > And " (deleted)" is correctly added to deleted files. > > The hell it will. > > touch a > touch b > exec 5<a > mv b a > ls -l /proc/$$/fd/5 > > With your patch and without it, please. While we are at it, touch a rm a touch a ls -l /proc/self/fd/0 <a With and without your patch. Note that you never remove DCACHE_DELETED after you've set it. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable. 2006-11-01 8:38 ` Al Viro 2006-11-01 8:42 ` Al Viro @ 2006-11-01 9:04 ` Eric Dumazet 1 sibling, 0 replies; 15+ messages in thread From: Eric Dumazet @ 2006-11-01 9:04 UTC (permalink / raw) To: Al Viro; +Cc: David Miller, netdev, linux-kernel Al Viro a écrit : > On Wed, Nov 01, 2006 at 09:21:06AM +0100, Eric Dumazet wrote: > >> And " (deleted)" is correctly added to deleted files. > > The hell it will. > > touch a > touch b > exec 5<a > mv b a > ls -l /proc/$$/fd/5 > > With your patch and without it, please. Yes I will do, thanks. > > PS: getting rid of socket dentries is a bad idea with the capital "Fuck, No". > For those who want to see where does that path lead and are attracted to > trainwrecks in general I can recommend *BSD socket handling. They have > paid quite painfully for lack of proper vnodes. It's simply not worth > the resulting trouble. I have one server with one million sockets, wasting 210 MB of ram for dentries that are only used when some guy does some /proc/$pid/fd work Socket hot path already dont use anymore dentries, thanks to file->private_data Eric ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable. 2006-11-01 7:19 ` David Miller 2006-11-01 8:21 ` Eric Dumazet @ 2006-11-01 13:54 ` Eric Dumazet 1 sibling, 0 replies; 15+ messages in thread From: Eric Dumazet @ 2006-11-01 13:54 UTC (permalink / raw) To: David Miller, Al Viro; +Cc: netdev, linux-kernel [-- Attachment #1: Type: text/plain, Size: 2052 bytes --] David Miller a écrit : > It turns out that while procfs uses a different "mechanism", those > procfs symlinks do point to the real socket dentry, so when you > readlink() on it you do d_path() on the real socket dentry. > > Al Viro just suggested a way around this to me: > > 1) Just mark the dentry HASHED by hand in the dentry flags, but don't > actually hash it. > > 2) Create a special dentry->d_deleted method for sockets that returns > 0 and clears by hand the HASHED flag bit in the dentry (see what > dput() does when this happens). > > It's an abuse but it will work. > Thank you David and Al for the feedback. Here is a new version of the patch with your suggestions included. If necessary, I could split this patch in 3 elementary patches. I chose to sent it as one patch for ease of discussion. [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable. We currently insert sockets/pipes dentries into the global dentry hashtable. This is *useless* because there is currently no way these entries can be used for a lookup(). (/proc/xxx/fd/xxx uses a different mechanism) Machines with a lot of sockets/pipes might suffer from longer chains in dentry hashtable. Since dentries an unhashed dentry means __dpath() adds a " (deleted)", the trick for socket/pipe dentries is to : - Right after d_alloc(), pretend they are hashed by clearing the DCACHE_UNHASHED bit. __dpath() & friends work as intended. - Call d_instantiate() instead of d_add() : dentry is not inserted in hash table. - Once dput() must clear the dentry, setting again DCACHE_UNHASHED bit inside the custom d_delete() function provided by socket/pipe code. [patch 1/3] Small optimization to bypass RCU freeing in d_free() for dentries that were never hashed (like sockets and pipes). Such dentries dont have to wait a RCU grace period. [patch 2/3] Change socket code to use d_instantiate() instead of d_add() [patch 3/3] Change pipe code to use d_instantiate() instead of d_add() Signed-off-by: Eric Dumazet <dada1@cosmosbay.com> [-- Attachment #2: donthash.patch --] [-- Type: text/plain, Size: 3861 bytes --] --- linux-2.6.19-rc4/fs/dcache.c 2006-11-01 12:38:23.000000000 +0100 +++ linux-2.6.19-rc4-ed/fs/dcache.c 2006-11-01 13:22:44.000000000 +0100 @@ -68,15 +68,19 @@ .age_limit = 45, }; -static void d_callback(struct rcu_head *head) +static void __d_free(struct dentry *dentry) { - struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu); - if (dname_external(dentry)) kfree(dentry->d_name.name); kmem_cache_free(dentry_cache, dentry); } +static void d_callback(struct rcu_head *head) +{ + struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu); + __d_free(dentry); +} + /* * no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry * inside dcache_lock. @@ -85,7 +89,11 @@ { if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release(dentry); - call_rcu(&dentry->d_u.d_rcu, d_callback); + /* if dentry was never inserted into hash, immediate free is OK */ + if (dentry->d_hash.pprev == NULL) + __d_free(dentry); + else + call_rcu(&dentry->d_u.d_rcu, d_callback); } /* --- linux-2.6.19-rc4/net/socket.c 2006-11-01 12:40:27.000000000 +0100 +++ linux-2.6.19-rc4-ed/net/socket.c 2006-11-01 14:33:18.000000000 +0100 @@ -306,7 +306,14 @@ static int sockfs_delete_dentry(struct dentry *dentry) { - return 1; + /* + * At creation time, we pretended this dentry was hashed + * (by clearing DCACHE_UNHASHED bit in d_flags) + * At delete time, we restore the truth : not hashed. + * (so that dput() can proceed correctly) + */ + dentry->d_flags |= DCACHE_UNHASHED; + return 0; } static struct dentry_operations sockfs_dentry_operations = { .d_delete = sockfs_delete_dentry, @@ -354,14 +361,20 @@ this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino); this.name = name; - this.hash = SOCK_INODE(sock)->i_ino; + this.hash = 0; file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); if (unlikely(!file->f_dentry)) return -ENOMEM; file->f_dentry->d_op = &sockfs_dentry_operations; - d_add(file->f_dentry, SOCK_INODE(sock)); + /* + * We dont want to push this dentry into global dentry hash table. + * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED + * This hack permits a working /proc/$pid/fd/XXX on sockets + */ + file->f_dentry->d_flags &= ~DCACHE_UNHASHED; + d_instantiate(file->f_dentry, SOCK_INODE(sock)); file->f_vfsmnt = mntget(sock_mnt); file->f_mapping = file->f_dentry->d_inode->i_mapping; --- linux-2.6.19-rc4/fs/pipe.c 2006-11-01 12:56:05.000000000 +0100 +++ linux-2.6.19-rc4-ed/fs/pipe.c 2006-11-01 14:33:18.000000000 +0100 @@ -830,7 +830,14 @@ static struct vfsmount *pipe_mnt __read_mostly; static int pipefs_delete_dentry(struct dentry *dentry) { - return 1; + /* + * At creation time, we pretended this dentry was hashed + * (by clearing DCACHE_UNHASHED bit in d_flags) + * At delete time, we restore the truth : not hashed. + * (so that dput() can proceed correctly) + */ + dentry->d_flags |= DCACHE_UNHASHED; + return 0; } static struct dentry_operations pipefs_dentry_operations = { @@ -891,17 +898,22 @@ if (!inode) goto err_file; - sprintf(name, "[%lu]", inode->i_ino); + this.len = sprintf(name, "[%lu]", inode->i_ino); this.name = name; - this.len = strlen(name); - this.hash = inode->i_ino; /* will go */ + this.hash = 0; err = -ENOMEM; dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); if (!dentry) goto err_inode; dentry->d_op = &pipefs_dentry_operations; - d_add(dentry, inode); + /* + * We dont want to push this dentry into global dentry hash table. + * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED + * This hack permits a working /proc/$pid/fd/XXX on pipes + */ + dentry->d_flags &= ~DCACHE_UNHASHED; + d_instantiate(dentry, inode); f->f_vfsmnt = mntget(pipe_mnt); f->f_dentry = dentry; f->f_mapping = inode->i_mapping; ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH] [NET] dont insert socket dentries into dentry_hashtable. 2006-10-31 18:48 ` [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable Eric Dumazet 2006-11-01 7:19 ` David Miller @ 2006-11-22 18:00 ` Eric Dumazet 2006-11-28 23:35 ` David Miller 1 sibling, 1 reply; 15+ messages in thread From: Eric Dumazet @ 2006-11-22 18:00 UTC (permalink / raw) To: David Miller; +Cc: netdev, linux-kernel, Al Viro, Andrew Morton [-- Attachment #1: Type: text/plain, Size: 847 bytes --] We currently insert socket dentries into the global dentry hashtable. This is *suboptimal* because there is currently no way these entries can be used for a lookup(). (/proc/xxx/fd/xxx uses a different mechanism). Inserting them in dentry hashtable slow dcache lookups. To let __dpath() still work correctly (ie not adding a " (deleted)") after dentry name, we do : - Right after d_alloc(), pretend they are hashed by clearing the DCACHE_UNHASHED bit. - Call d_instantiate() instead of d_add() : dentry is not inserted in hash table. __dpath() & friends work as intended during dentry lifetime. - At dismantle time, once dput() must clear the dentry, setting again DCACHE_UNHASHED bit inside the custom d_delete() function provided by socket code, so that dput() can just kill_it. Signed-off-by: Eric Dumazet <dada1@cosmosbay.com> [-- Attachment #2: socket_nohash_dentry.patch --] [-- Type: text/plain, Size: 1466 bytes --] --- linux-2.6.19-rc6/net/socket.c 2006-11-22 17:33:41.000000000 +0100 +++ linux-2.6.19-rc6-ed/net/socket.c 2006-11-22 18:28:12.000000000 +0100 @@ -306,7 +306,14 @@ static struct file_system_type sock_fs_t static int sockfs_delete_dentry(struct dentry *dentry) { - return 1; + /* + * At creation time, we pretended this dentry was hashed + * (by clearing DCACHE_UNHASHED bit in d_flags) + * At delete time, we restore the truth : not hashed. + * (so that dput() can proceed correctly) + */ + dentry->d_flags |= DCACHE_UNHASHED; + return 0; } static struct dentry_operations sockfs_dentry_operations = { .d_delete = sockfs_delete_dentry, @@ -354,14 +361,20 @@ static int sock_attach_fd(struct socket this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino); this.name = name; - this.hash = SOCK_INODE(sock)->i_ino; + this.hash = 0; file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); if (unlikely(!file->f_dentry)) return -ENOMEM; file->f_dentry->d_op = &sockfs_dentry_operations; - d_add(file->f_dentry, SOCK_INODE(sock)); + /* + * We dont want to push this dentry into global dentry hash table. + * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED + * This permits a working /proc/$pid/fd/XXX on sockets + */ + file->f_dentry->d_flags &= ~DCACHE_UNHASHED; + d_instantiate(file->f_dentry, SOCK_INODE(sock)); file->f_vfsmnt = mntget(sock_mnt); file->f_mapping = file->f_dentry->d_inode->i_mapping; ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] [NET] dont insert socket dentries into dentry_hashtable. 2006-11-22 18:00 ` [PATCH] [NET] dont insert socket " Eric Dumazet @ 2006-11-28 23:35 ` David Miller 2006-11-29 0:13 ` Andrew Morton 0 siblings, 1 reply; 15+ messages in thread From: David Miller @ 2006-11-28 23:35 UTC (permalink / raw) To: dada1; +Cc: netdev, linux-kernel, viro, akpm Andrew, I'm fine with these three patches, specifically: [PATCH] dont insert pipe dentries into dentry_hashtable. [PATCH] [DCACHE] : avoid RCU for never hashed dentries [PATCH] [NET] dont insert socket dentries into dentry_hashtable. Could you toss them into -mm if you haven't already? This makes better sense then me putting it into net-2.6.20 since it touches FS stuff. Thanks! ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] [NET] dont insert socket dentries into dentry_hashtable. 2006-11-28 23:35 ` David Miller @ 2006-11-29 0:13 ` Andrew Morton 0 siblings, 0 replies; 15+ messages in thread From: Andrew Morton @ 2006-11-29 0:13 UTC (permalink / raw) To: David Miller; +Cc: dada1, netdev, linux-kernel, viro On Tue, 28 Nov 2006 15:35:31 -0800 (PST) David Miller <davem@davemloft.net> wrote: > > Andrew, I'm fine with these three patches, specifically: > > [PATCH] dont insert pipe dentries into dentry_hashtable. > [PATCH] [DCACHE] : avoid RCU for never hashed dentries > [PATCH] [NET] dont insert socket dentries into dentry_hashtable. > > Could you toss them into -mm if you haven't already? They were in rc6-mm2. > This > makes better sense then me putting it into net-2.6.20 since > it touches FS stuff. > No probs, they're all lined up and ready to go, thanks. ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2006-11-29 0:13 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-10-24 14:17 [PATCH] fix integer overflow in H-TCP congestion control Gavin McCullagh 2006-10-24 22:30 ` David Miller 2006-10-25 8:47 ` Gavin McCullagh 2006-10-26 6:06 ` David Miller 2006-10-31 18:48 ` [RFC, PATCH] dont insert sockets/pipes dentries into dentry_hashtable Eric Dumazet 2006-11-01 7:19 ` David Miller 2006-11-01 8:21 ` Eric Dumazet 2006-11-01 8:34 ` David Miller 2006-11-01 8:38 ` Al Viro 2006-11-01 8:42 ` Al Viro 2006-11-01 9:04 ` Eric Dumazet 2006-11-01 13:54 ` Eric Dumazet 2006-11-22 18:00 ` [PATCH] [NET] dont insert socket " Eric Dumazet 2006-11-28 23:35 ` David Miller 2006-11-29 0:13 ` Andrew Morton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).