linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH/RFC] New module refcounting for net_proto_family
@ 2002-12-26  8:11 Max Krasnyansky
  2003-01-02 11:43 ` Max Krasnyansky
  2003-01-07  9:21 ` David S. Miller
  0 siblings, 2 replies; 40+ messages in thread
From: Max Krasnyansky @ 2002-12-26  8:11 UTC (permalink / raw)
  To: davem; +Cc: linux-kernel

> Bunch of problems with this patch:
>
> 1) Module leak.  If try_module_get(npf->owner) works but sock_alloc()
>    fails, we never put the module.  It just branches to the "out"
>    label in that case, which unlocks the net_family table and returns
>    err.
Yeah, I missed that one. Fixed in the new patch.

> 2) Bigger issue, why not attach the owner to struct sock
>    instead of socket?  The sock can exist, and thus reference
>    the protocol family code, long after the socket (ie. the
>    user end) is killed off and closed.
>
>    For example, this could happen for just about any protocol family
>    due to stray device sk_buff references to the sock and thus the
>    protocol family.
Good point. Alghough generic socket code does not necessarily reference 
proto family module via struct sock. Only in case when family installed 
non default callbacks (sk->dataready, sk->destruct, etc). Some families
(af_ipx for example) don't. But I think it's a good idea to refcount 
struct sock anyway. 

Ok. Here is the new patch. 
We still need owner field in struct socket.

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.889   -> 1.890  
#	        net/socket.c	1.39    -> 1.40   
#	 include/linux/net.h	1.7     -> 1.8    
#	  include/net/sock.h	1.29    -> 1.30   
#	     net/core/sock.c	1.14    -> 1.15   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/12/25	maxk@qualcomm.com	1.890
# Convert generic socket code to the new module refcounting API.
# --------------------------------------------
#
diff -Nru a/include/linux/net.h b/include/linux/net.h
--- a/include/linux/net.h	Wed Dec 25 23:29:28 2002
+++ b/include/linux/net.h	Wed Dec 25 23:29:28 2002
@@ -76,6 +76,8 @@
 
 	short			type;
 	unsigned char		passcred;
+
+	struct module           *owner;
 };
 
 struct scm_cookie;
@@ -124,6 +126,8 @@
 	short	authentication;
 	short	encryption;
 	short	encrypt_net;
+
+	struct  module *owner;
 };
 
 struct net_proto 
diff -Nru a/include/net/sock.h b/include/net/sock.h
--- a/include/net/sock.h	Wed Dec 25 23:29:28 2002
+++ b/include/net/sock.h	Wed Dec 25 23:29:28 2002
@@ -41,6 +41,7 @@
 #include <linux/config.h>
 #include <linux/timer.h>
 #include <linux/cache.h>
+#include <linux/module.h>
 
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>	/* struct sk_buff */
@@ -196,7 +197,9 @@
 
 	/* RPC layer private data */
 	void			*user_data;
-  
+
+	struct module		*owner;
+	
 	/* Callbacks */
 	void			(*state_change)(struct sock *sk);
 	void			(*data_ready)(struct sock *sk,int bytes);
@@ -577,6 +580,9 @@
 
 static inline void sock_graft(struct sock *sk, struct socket *parent)
 {
+	try_module_get(parent->owner);
+	sk->owner = parent->owner;
+
 	write_lock_bh(&sk->callback_lock);
 	sk->sleep = &parent->wait;
 	parent->sk = sk;
diff -Nru a/net/core/sock.c b/net/core/sock.c
--- a/net/core/sock.c	Wed Dec 25 23:29:28 2002
+++ b/net/core/sock.c	Wed Dec 25 23:29:28 2002
@@ -601,6 +601,7 @@
 			sock_lock_init(sk);
 		}
 		sk->slab = slab;
+		sk->owner = NULL;
 	}
 
 	return sk;
@@ -626,6 +627,8 @@
 	if (atomic_read(&sk->omem_alloc))
 		printk(KERN_DEBUG "sk_free: optmem leakage (%d bytes) detected.\n", atomic_read(&sk->omem_alloc));
 
+	module_put(sk->owner);
+	
 	kmem_cache_free(sk->slab, sk);
 }
 
@@ -1084,10 +1087,10 @@
 	sk->zapped	=	1;
 	sk->socket	=	sock;
 
-	if(sock)
-	{
+	if (sock) {
 		sk->type	=	sock->type;
 		sk->sleep	=	&sock->wait;
+		sk->owner       =       sock->owner;
 		sock->sk	=	sk;
 	} else
 		sk->sleep	=	NULL;
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	Wed Dec 25 23:29:28 2002
+++ b/net/socket.c	Wed Dec 25 23:29:28 2002
@@ -470,6 +470,8 @@
 
 	sock = SOCKET_I(inode);
 
+	sock->owner = NULL;
+	
 	inode->i_mode = S_IFSOCK|S_IRWXUGO;
 	inode->i_sock = 1;
 	inode->i_uid = current->fsuid;
@@ -964,8 +966,9 @@
 
 int sock_create(int family, int type, int protocol, struct socket **res)
 {
-	int i;
+	struct net_proto_family *npf;
 	struct socket *sock;
+	int err;
 
 	/*
 	 *	Check protocol is in range
@@ -990,14 +993,8 @@
 	}
 		
 #if defined(CONFIG_KMOD) && defined(CONFIG_NET)
-	/* Attempt to load a protocol module if the find failed. 
-	 * 
-	 * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user 
-	 * requested real, full-featured networking support upon configuration.
-	 * Otherwise module support will break!
-	 */
-	if (net_families[family]==NULL)
-	{
+	/* Attempt to load a protocol module if the find failed. */
+	if (net_families[family]==NULL) {
 		char module_name[30];
 		sprintf(module_name,"net-pf-%d",family);
 		request_module(module_name);
@@ -1005,29 +1002,31 @@
 #endif
 
 	net_family_read_lock();
-	if (net_families[family] == NULL) {
-		i = -EAFNOSUPPORT;
-		goto out;
-	}
 
-/*
- *	Allocate the socket and allow the family to set things up. if
- *	the protocol is 0, the family is instructed to select an appropriate
- *	default.
- */
+	npf = net_families[family];
+	if (!npf || !try_module_get(npf->owner)) {
+		net_family_read_unlock();
+		return -EAFNOSUPPORT;
+	}
+	
+	/*
+	 * Allocate the socket and allow the family to set things up. if
+	 * the protocol is 0, the family is instructed to select an appropriate
+	 * default.
+ 	 */
 
-	if (!(sock = sock_alloc())) 
-	{
+	sock = sock_alloc();
+	if (!sock) {
 		printk(KERN_WARNING "socket: no more sockets\n");
-		i = -ENFILE;		/* Not exactly a match, but its the
+		err = -ENFILE;		/* Not exactly a match, but its the
 					   closest posix thing */
 		goto out;
 	}
 
 	sock->type  = type;
+	sock->owner = npf->owner;
 
-	if ((i = net_families[family]->create(sock, protocol)) < 0) 
-	{
+	if ((err = npf->create(sock, protocol)) < 0) {
 		sock_release(sock);
 		goto out;
 	}
@@ -1036,7 +1035,9 @@
 
 out:
 	net_family_read_unlock();
-	return i;
+	if (err)
+		module_put(npf->owner);
+	return err;
 }
 
 asmlinkage long sys_socket(int family, int type, int protocol)
@@ -1198,9 +1199,10 @@
 	if (!(newsock = sock_alloc())) 
 		goto out_put;
 
-	newsock->type = sock->type;
-	newsock->ops = sock->ops;
-
+	newsock->type  = sock->type;
+	newsock->ops   = sock->ops;
+	newsock->owner = sock->owner;
+	
 	err = sock->ops->accept(sock, newsock, sock->file->f_flags);
 	if (err < 0)
 		goto out_release;

--

Max



^ permalink raw reply	[flat|nested] 40+ messages in thread
* Re: [PATCH/RFC] New module refcounting for net_proto_family
@ 2003-02-20 17:52 Max Krasnyansky
  0 siblings, 0 replies; 40+ messages in thread
From: Max Krasnyansky @ 2003-02-20 17:52 UTC (permalink / raw)
  To: David S. Miller, rusty; +Cc: kuznet, jt, linux-kernel

At 11:04 PM 2/18/2003, David S. Miller wrote:
>>   From: Rusty Russell <rusty@rustcorp.com.au>
>>   Date: Wed, 19 Feb 2003 14:54:21 +1100
>>   
>>   Firstly, the owner field should probably be in struct proto_ops not
>>   struct socket, where the function pointers are.
>>
>>I think this is one of Alexey's main problems with the patch.
>This is a bit more informative than "oh it's an ugly hack" ;-)
>
>Ok. I got at least three reasons why I think owner field should be in struct 
>socket:
>        - struct proto_ops doesn't exists without struct socket.
>        It cannot be registered or otherwise used on it's own. 
>        - struct sock might inherit (when needed see my explanation about different families)
>        its owner from struct socket. In which case sk_set_owner(sk, socket->ops->owner) doesn't
>        look right.
>        - we might want to protect something else besides socket->ops.
>
>None of those reasons are critical. If you guys still feel that ->owner must be in struct 
>proto_ops be that way, I'm ok with it.
Ok. I'll take that back :).
The thing is that socket->ops is set from the protocol itself not in the generic socket code.
Here is what sock_create() does

        if (!(sock = sock_alloc())) 
        {
                printk(KERN_WARNING "socket: no more sockets\n");
                i = -ENFILE;            /* Not exactly a match, but its the
                                           closest posix thing */
                goto out;
        }

        sock->type  = type;

        if ((i = net_families[family]->create(sock, protocol)) < 0) 
        {
                sock_release(sock);
                goto out;
        }

It simply calls net_family->create() which then sets its private struct proto_ops.

So I think owner field should be in the struct socket because it needs to be 
accessible from net/socket.c:sock_create()/sock_release().

Dave, Alexey, do you guys still strongly believe that it's a hack ? 
If yes what do I need to do to convince otherwise ? ;-)

Max


^ permalink raw reply	[flat|nested] 40+ messages in thread
* Re: [PATCH/RFC] New module refcounting for net_proto_family
@ 2002-12-19 23:08 Jean Tourrilhes
  2002-12-19 23:23 ` Max Krasnyansky
  0 siblings, 1 reply; 40+ messages in thread
From: Jean Tourrilhes @ 2002-12-19 23:08 UTC (permalink / raw)
  To: Linux kernel mailing list, Max Krasnyansky

Max Krasnyansky wrote :
> Ok. Drop me a note and I'll push this stuff to BK were you can pull from. 
> In the mean time I'll go bug other folks :). I want to do same kinda changes 
> for the TTY ldisc code.
> 
> Max

	Go for it, I've got the exact same problem with IrDA (both
socket and tty ldisc). Maybe worth sending an entry for the FAQ of
Rusty and include PPP maintainer in the loop.
	Have fun...

	Jean

P.S. : Talking about it, I'm away for Chrismas & New-Year...

^ permalink raw reply	[flat|nested] 40+ messages in thread
* [PATCH/RFC] New module refcounting for net_proto_family
@ 2002-12-18 15:25 Max Krasnyansky
  2002-12-19 16:05 ` Max Krasnyansky
  0 siblings, 1 reply; 40+ messages in thread
From: Max Krasnyansky @ 2002-12-18 15:25 UTC (permalink / raw)
  To: linux-kernel

Hi Folks,

It seems that new module code is going to stay with us at least for a
while :).
So it's probably time to start fixing old interfaces to use new
refcounting scheme.

Here is a patch for sock_create() and stuff that uses net_proto_family
interface. Tested with modified af_bluetooth.c and seems to work fine.
Other families are unaffected for now because their owner field == NULL.

If people are ok with this aproach I will also fix af_unix and other
families and push all fixes into my BK tree.

(URL in case if my mailer messed up spaces
http://bluez.sourceforge.net/patches/npf_refcnt_patch-2.5.52.gz)


# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or
higher.
# This patch includes the following deltas:
#	           ChangeSet	1.888   -> 1.889  
#	        net/socket.c	1.39    -> 1.40   
#	 include/linux/net.h	1.7     -> 1.8    
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/12/17	maxk@qualcomm.com	1.889
# Convert generic socket code to new module refcounting.
# --------------------------------------------
#
diff -Nru a/include/linux/net.h b/include/linux/net.h
--- a/include/linux/net.h	Tue Dec 17 20:02:04 2002
+++ b/include/linux/net.h	Tue Dec 17 20:02:04 2002
@@ -76,6 +76,8 @@
 
 	short			type;
 	unsigned char		passcred;
+
+	struct module           *owner;
 };
 
 struct scm_cookie;
@@ -124,6 +126,8 @@
 	short	authentication;
 	short	encryption;
 	short	encrypt_net;
+
+	struct  module *owner;
 };
 
 struct net_proto 
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	Tue Dec 17 20:02:04 2002
+++ b/net/socket.c	Tue Dec 17 20:02:04 2002
@@ -470,6 +470,8 @@
 
 	sock = SOCKET_I(inode);
 
+	sock->owner = NULL;
+	
 	inode->i_mode = S_IFSOCK|S_IRWXUGO;
 	inode->i_sock = 1;
 	inode->i_uid = current->fsuid;
@@ -517,6 +519,8 @@
 		return;
 	}
 	sock->file=NULL;
+
+	module_put(sock->owner);
 }
 
 static int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, int size)
@@ -964,8 +968,9 @@
 
 int sock_create(int family, int type, int protocol, struct socket
**res)
 {
-	int i;
+	struct net_proto_family *npf;
 	struct socket *sock;
+	int err;
 
 	/*
 	 *	Check protocol is in range
@@ -990,14 +995,8 @@
 	}
 		
 #if defined(CONFIG_KMOD) && defined(CONFIG_NET)
-	/* Attempt to load a protocol module if the find failed. 
-	 * 
-	 * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user 
-	 * requested real, full-featured networking support upon
configuration.
-	 * Otherwise module support will break!
-	 */
-	if (net_families[family]==NULL)
-	{
+	/* Attempt to load a protocol module if the find failed. */
+	if (net_families[family]==NULL) {
 		char module_name[30];
 		sprintf(module_name,"net-pf-%d",family);
 		request_module(module_name);
@@ -1005,29 +1004,31 @@
 #endif
 
 	net_family_read_lock();
-	if (net_families[family] == NULL) {
-		i = -EAFNOSUPPORT;
+
+	npf = net_families[family];
+	if (!npf || !try_module_get(npf->owner)) {
+		err = -EAFNOSUPPORT;
 		goto out;
 	}
+	
+	/*
+	 * Allocate the socket and allow the family to set things up. if
+	 * the protocol is 0, the family is instructed to select an
appropriate
+	 * default.
+ 	 */
 
-/*
- *	Allocate the socket and allow the family to set things up. if
- *	the protocol is 0, the family is instructed to select an appropriate
- *	default.
- */
-
-	if (!(sock = sock_alloc())) 
-	{
+	sock = sock_alloc();
+	if (!sock) {
 		printk(KERN_WARNING "socket: no more sockets\n");
-		i = -ENFILE;		/* Not exactly a match, but its the
+		err = -ENFILE;		/* Not exactly a match, but its the
 					   closest posix thing */
 		goto out;
 	}
 
 	sock->type  = type;
+	sock->owner = npf->owner;
 
-	if ((i = net_families[family]->create(sock, protocol)) < 0) 
-	{
+	if ((err = npf->create(sock, protocol)) < 0) {
 		sock_release(sock);
 		goto out;
 	}
@@ -1036,7 +1037,7 @@
 
 out:
 	net_family_read_unlock();
-	return i;
+	return err;
 }
 
 asmlinkage long sys_socket(int family, int type, int protocol)
@@ -1201,6 +1202,9 @@
 	newsock->type = sock->type;
 	newsock->ops = sock->ops;
 
+	try_module_get(sock->owner);
+	newsock->owner = sock->owner;
+	
 	err = sock->ops->accept(sock, newsock, sock->file->f_flags);
 	if (err < 0)
 		goto out_release;

-- 
Max Krasnyansky <maxk@qualcomm.com>
Qualcomm


^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2003-02-26 20:15 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-26  8:11 [PATCH/RFC] New module refcounting for net_proto_family Max Krasnyansky
2003-01-02 11:43 ` Max Krasnyansky
2003-01-03  8:24   ` David S. Miller
2003-01-20  3:22   ` Max Krasnyansky
2003-01-21 11:03     ` David S. Miller
2003-01-21 19:42       ` Max Krasnyansky
2003-01-21 19:36         ` David S. Miller
2003-02-07  9:48     ` David S. Miller
2003-02-07 23:34       ` Max Krasnyansky
2003-02-08  8:44         ` David S. Miller
2003-02-18  3:46     ` David S. Miller
2003-02-18 18:50       ` Max Krasnyansky
2003-02-18 21:09         ` Jean Tourrilhes
2003-02-19  3:54         ` Rusty Russell
2003-02-19  7:04           ` David S. Miller
2003-02-19 18:03             ` Max Krasnyansky
2003-02-19 20:31             ` Roman Zippel
2003-02-19 17:45           ` Max Krasnyansky
2003-02-20  1:21             ` Rusty Russell
2003-02-20 17:38               ` Max Krasnyansky
2003-02-21  0:30                 ` Rusty Russell
2003-02-21  1:17                   ` Max Krasnyansky
2003-02-21  8:45                     ` Christoph Hellwig
2003-02-21 17:44                       ` Max Krasnyansky
2003-02-24  1:01                     ` Rusty Russell
2003-02-24 19:35                       ` Max Krasnyansky
2003-02-25  5:02                         ` Rusty Russell
2003-02-26 20:21                           ` Max Krasnyansky
2003-01-07  9:21 ` David S. Miller
2003-01-09 20:45   ` Max Krasnyansky
2003-01-09 23:53     ` David S. Miller
  -- strict thread matches above, loose matches on Subject: below --
2003-02-20 17:52 Max Krasnyansky
2002-12-19 23:08 Jean Tourrilhes
2002-12-19 23:23 ` Max Krasnyansky
2002-12-18 15:25 Max Krasnyansky
2002-12-19 16:05 ` Max Krasnyansky
2002-12-19 19:28   ` Alan Cox
2002-12-19 19:12     ` David S. Miller
2002-12-19 22:17       ` Max Krasnyansky
2002-12-21  6:54   ` David S. Miller

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).