Skip to contentSkip to conversation

NFSD: fix use of setsockopt

PATCH In review Olga Kornievskaia 6 participants 12 messages Jun 19, 2008 – Jun 28, 2008 3 messages not in the archive

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 NFSD: fix use of setsockopt

The following patch fixes NFS server's use of setsockopt. For this function to take an effect it first needs be called after socket creation but before sock binding.

This patch also changes the size of the receive sock buffer to be same as the send sock buffer. Both buffers are now a multiple of maxpayload and number of nfsd threads.

This patch fixes the problem that receive window never opens beyond the default TCP receive window size set by the 2nd parameter of the net.ipv4.tcp_rmem sysctl.

net/sunrpc/svcsock.c +3 -6
index c75bffe..178b397 100644
@@ -1191,7 +1191,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
 		 */
 		svc_sock_setbufsize(svsk->sk_sock,
 				    (serv->sv_nrthreads+3) * serv->sv_max_mesg,
-				    3 * serv->sv_max_mesg);
+				    (serv->sv_nrthreads+3) * serv->sv_max_mesg);
 
 	clear_bit(SK_DATA, &svsk->sk_flags);
 
@@ -1372,11 +1372,6 @@ svc_tcp_init(struct svc_sock *svsk)
 		 * receive and respond to one request.
 		 * svc_tcp_recvfrom will re-adjust if necessary
 		 */
-		svc_sock_setbufsize(svsk->sk_sock,
-				    3 * svsk->sk_server->sv_max_mesg,
-				    3 * svsk->sk_server->sv_max_mesg);
-
-		set_bit(SK_CHNGBUF, &svsk->sk_flags);
 		set_bit(SK_DATA, &svsk->sk_flags);
 		if (sk->sk_state != TCP_ESTABLISHED)
 			set_bit(SK_CLOSE, &svsk->sk_flags);
@@ -1761,6 +1756,8 @@ static int svc_create_socket(struct svc_serv *serv, int protocol,
 
 	if (type == SOCK_STREAM)
 		sock->sk->sk_reuse = 1;		/* allow address reuse */
+	svc_sock_setbufsize(sock, (serv->sv_nrthreads+3) * serv->sv_max_mesg,
+				(serv->sv_nrthreads+3) * serv->sv_max_mesg);
 	error = kernel_bind(sock, sin, len);
 	if (error < 0)
 		goto bummer;
#1 lore raw

Hi Olga,

This makes sense, if NFSD is going to ignore global Linux TCP settings and 'go it alone', then it shouldn't be constrained by them.

At least now we can increase the rcv buffer size by increasing the number of NFSDs. I would still like to pursue my sysctl patch for the rcv and snd buffer though since we have seen situations where too many NFSDs can increase the randomness of requests to the underlying file system, reducing the effectiveness readahead/write gathering.

Dean

Quoted 7 lines · Olga Kornievskaia

The following patch fixes NFS server's use of setsockopt. For this function to take an effect it first needs be called after socket creation but before sock binding.

This patch also changes the size of the receive sock buffer to be same as the send sock buffer. Both buffers are now a multiple of maxpayload and number of nfsd threads.

This patch fixes the problem that receive window never opens beyond the default TCP receive window size set by the 2nd parameter of the net.ipv4.tcp_rmem sysctl.

------------------------------------------------------------------------

net/sunrpc/svcsock.c +0 -0
index c75bffe..178b397 100644
@@ -1191,7 +1191,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
		 */
		svc_sock_setbufsize(svsk->sk_sock,
				    (serv->sv_nrthreads+3) * serv->sv_max_mesg,

- 3 * serv->sv_max_mesg);
+ (serv->sv_nrthreads+3) * serv->sv_max_mesg);

	clear_bit(SK_DATA, &svsk->sk_flags);

@@ -1372,11 +1372,6 @@ svc_tcp_init(struct svc_sock *svsk)
* receive and respond to one request.
* svc_tcp_recvfrom will re-adjust if necessary */
- svc_sock_setbufsize(svsk->sk_sock,
- 3 * svsk->sk_server->sv_max_mesg,
- 3 * svsk->sk_server->sv_max_mesg);
-
- set_bit(SK_CHNGBUF, &svsk->sk_flags);

		set_bit(SK_DATA, &svsk->sk_flags);
		if (sk->sk_state != TCP_ESTABLISHED)
			set_bit(SK_CLOSE, &svsk->sk_flags);

@@ -1761,6 +1756,8 @@ static int svc_create_socket(struct svc_serv *serv, int protocol,

	if (type == SOCK_STREAM)
		sock->sk->sk_reuse = 1;		/* allow address reuse */
+	svc_sock_setbufsize(sock, (serv->sv_nrthreads+3) * serv->sv_max_mesg,
+				(serv->sv_nrthreads+3) * serv->sv_max_mesg);
	error = kernel_bind(sock, sin, len);
	if (error < 0)
		goto bummer;
#2 lore raw
Quoted 10 lines · Dean Hildebrand

Hi Olga,

This makes sense, if NFSD is going to ignore global Linux TCP settings and 'go it alone', then it shouldn't be constrained by them.

At least now we can increase the rcv buffer size by increasing the number of NFSDs. I would still like to pursue my sysctl patch for the rcv and snd buffer though since we have seen situations where too many NFSDs can increase the randomness of requests to the underlying file system, reducing the effectiveness readahead/write gathering.

Olga says she's also seeing some performance decrease with increasing numbers of threads in our 10 gigabit testing, and I was wondering if something like that could explain the change.

Anyone have ideas how we could measure how ordered our IO requests are? (Or how much seeking the drives in our raid array are doing?)

--b.

Quoted 61 lines

Dean

Quoted 8 lines · Olga Kornievskaia

The following patch fixes NFS server's use of setsockopt. For this function to take an effect it first needs be called after socket creation but before sock binding.

This patch also changes the size of the receive sock buffer to be same as the send sock buffer. Both buffers are now a multiple of maxpayload and number of nfsd threads.

Quoted 5 lines

This patch fixes the problem that receive window never opens beyond the default TCP receive window size set by the 2nd parameter of the net.ipv4.tcp_rmem sysctl.

------------------------------------------------------------------------

net/sunrpc/svcsock.c +1 -6
index c75bffe..178b397 100644
@@ -1191,7 +1191,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
 		 */
 		svc_sock_setbufsize(svsk->sk_sock,
 				    (serv->sv_nrthreads+3) * serv->sv_max_mesg,
-				    3 * serv->sv_max_mesg);
+				    (serv->sv_nrthreads+3) * serv->sv_max_mesg);
 
 	clear_bit(SK_DATA, &svsk->sk_flags);
 
@@ -1372,11 +1372,6 @@ svc_tcp_init(struct svc_sock *svsk)
 		 * receive and respond to one request.
 		 * svc_tcp_recvfrom will re-adjust if necessary
 		 */
-		svc_sock_setbufsize(svsk->sk_sock,
-				    3 * svsk->sk_server->sv_max_mesg,
-				    3 * svsk->sk_server->sv_max_mesg);
-
-		set_bit(SK_CHNGBUF, &svsk->sk_flags);
 
 		set_bit(SK_DATA, &svsk->sk_flags);
 		if (sk->sk_state != TCP_ESTABLISHED)
			set_bit(SK_CLOSE, &svsk->sk_flags);
net/sunrpc/svcsock.c +2 -1
@@ -1761,6 +1756,8 @@ static int svc_create_socket(struct svc_serv *serv, int protocol,
 
 	if (type == SOCK_STREAM)
 		sock->sk->sk_reuse = 1;		/* allow address reuse */
+	svc_sock_setbufsize(sock, (serv->sv_nrthreads+3) * serv->sv_max_mesg,
+				(serv->sv_nrthreads+3) * serv->sv_max_mesg);
 	error = kernel_bind(sock, sin, len);
 	if (error < 0)
 		goto bummer;
 
--

To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#3 lore raw
In reply to Olga Kornievskaia
Quoted 3 lines · Olga Kornievskaia

The following patch fixes NFS server's use of setsockopt. For this function to take an effect it first needs be called after socket creation but before sock binding.

The tcp(7) man page actually claims that it's listen() and connect() that matter (so the setsockopt is effective on (and only on) unconnected sockets), so probably this could go after the bind and before the listen? Not that it matters.

Quoted 3 lines

This patch also changes the size of the receive sock buffer to be same as the send sock buffer. Both buffers are now a multiple of maxpayload and number of nfsd threads.

It would be nice if we could get some review from someone who remembers what the justification for the smaller receive buffer size was (Neil?).

Quoted 3 lines

This patch fixes the problem that receive window never opens beyond the default TCP receive window size set by the 2nd parameter of the net.ipv4.tcp_rmem sysctl.

Do you know what it does in the udp case?

--b.

Quoted 37 lines
net/sunrpc/svcsock.c +3 -6
index c75bffe..178b397 100644
@@ -1191,7 +1191,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
 		 */
 		svc_sock_setbufsize(svsk->sk_sock,
 				    (serv->sv_nrthreads+3) * serv->sv_max_mesg,
-				    3 * serv->sv_max_mesg);
+				    (serv->sv_nrthreads+3) * serv->sv_max_mesg);
 
 	clear_bit(SK_DATA, &svsk->sk_flags);
 
@@ -1372,11 +1372,6 @@ svc_tcp_init(struct svc_sock *svsk)
 		 * receive and respond to one request.
 		 * svc_tcp_recvfrom will re-adjust if necessary
 		 */
-		svc_sock_setbufsize(svsk->sk_sock,
-				    3 * svsk->sk_server->sv_max_mesg,
-				    3 * svsk->sk_server->sv_max_mesg);
-
-		set_bit(SK_CHNGBUF, &svsk->sk_flags);
 		set_bit(SK_DATA, &svsk->sk_flags);
 		if (sk->sk_state != TCP_ESTABLISHED)
 			set_bit(SK_CLOSE, &svsk->sk_flags);
@@ -1761,6 +1756,8 @@ static int svc_create_socket(struct svc_serv *serv, int protocol,
 
 	if (type == SOCK_STREAM)
 		sock->sk->sk_reuse = 1;		/* allow address reuse */
+	svc_sock_setbufsize(sock, (serv->sv_nrthreads+3) * serv->sv_max_mesg,
+				(serv->sv_nrthreads+3) * serv->sv_max_mesg);
 	error = kernel_bind(sock, sin, len);
 	if (error < 0)
 		goto bummer;
#4 lore raw
Quoted 14 lines · J. Bruce Fields
Quoted 2 lines · Olga Kornievskaia

The following patch fixes NFS server's use of setsockopt. For this function to take an effect it first needs be called after socket creation but before sock binding.

The tcp(7) man page actually claims that it's listen() and connect() that matter (so the setsockopt is effective on (and only on) unconnected sockets), so probably this could go after the bind and before the listen? Not that it matters.

Quoted 2 lines

This patch also changes the size of the receive sock buffer to be same as the send sock buffer. Both buffers are now a multiple of maxpayload and number of nfsd threads.

Quoted 9 lines

It would be nice if we could get some review from someone who remembers what the justification for the smaller receive buffer size was (Neil?).

Quoted 2 lines

This patch fixes the problem that receive window never opens beyond the default TCP receive window size set by the 2nd parameter of the net.ipv4.tcp_rmem sysctl.

Do you know what it does in the udp case?

Looking at the kernel code, when setsockopt() is called on a UDP socket to set send/receive buffer for UPD the code will not do anything: udp_setsockopt() and udp_lib_setsockopt() will return -ENOPROTOOPT. However, we bypass the call to setsockopt() and instead set the buffer sizes directly. From what I understand sk_sndbuf/sk_rcvbuf are not used by the UDP code. We are setting the fields that are never used.

Then perhaps we can remove calls to svc_sock_setbufsize() from svc_udp_init() and svc_udp_recvfrom()?

Quoted 45 lines

--b.

Quoted 39 lines
net/sunrpc/svcsock.c +3 -6
index c75bffe..178b397 100644
@@ -1191,7 +1191,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
 		 */
 		svc_sock_setbufsize(svsk->sk_sock,
 				    (serv->sv_nrthreads+3) * serv->sv_max_mesg,
-				    3 * serv->sv_max_mesg);
+				    (serv->sv_nrthreads+3) * serv->sv_max_mesg);
 
 	clear_bit(SK_DATA, &svsk->sk_flags);
 
@@ -1372,11 +1372,6 @@ svc_tcp_init(struct svc_sock *svsk)
 		 * receive and respond to one request.
 		 * svc_tcp_recvfrom will re-adjust if necessary
 		 */
-		svc_sock_setbufsize(svsk->sk_sock,
-				    3 * svsk->sk_server->sv_max_mesg,
-				    3 * svsk->sk_server->sv_max_mesg);
-
-		set_bit(SK_CHNGBUF, &svsk->sk_flags);
 		set_bit(SK_DATA, &svsk->sk_flags);
 		if (sk->sk_state != TCP_ESTABLISHED)
 			set_bit(SK_CLOSE, &svsk->sk_flags);
@@ -1761,6 +1756,8 @@ static int svc_create_socket(struct svc_serv *serv, int protocol,
 
 	if (type == SOCK_STREAM)
 		sock->sk->sk_reuse = 1;		/* allow address reuse */
+	svc_sock_setbufsize(sock, (serv->sv_nrthreads+3) * serv->sv_max_mesg,
+				(serv->sv_nrthreads+3) * serv->sv_max_mesg);
 	error = kernel_bind(sock, sin, len);
 	if (error < 0)
 		goto bummer;
#5 lore raw
Quoted 9 lines · Olga Kornievskaia

Looking at the kernel code, when setsockopt() is called on a UDP socket to set send/receive buffer for UPD the code will not do anything:
udp_setsockopt() and udp_lib_setsockopt() will return -ENOPROTOOPT. However, we bypass the call to setsockopt() and instead set the buffer sizes directly. From what I understand sk_sndbuf/sk_rcvbuf are not used by the UDP code. We are setting the fields that are never used.

Then perhaps we can remove calls to svc_sock_setbufsize() from svc_udp_init() and svc_udp_recvfrom()?

Assuming you're correct about udp not using those fields (haven't checked myself)--yes, that'd be great.

--b.

A message that is not in the archive (sent off-list or not yet received): FC3FA7C4E1CA2348B5579A68B24556E9DA4AF2946C-KofoAzQUpSBAuK1PVaBULA@public.gmane.org

#8 lore raw

Re: Sm-notify

Quoted 4 lines · Dirk

Hi,

Does anybody know how sm-notify exactly works on a suse sles 9 system?

Yes.

Do you have a specific question about it?

NeilBrown

A message that is not in the archive (sent off-list or not yet received): 46260.192.168.1.70.1214533375.squirrel-eq65iwfR9nKIECXXMXunQA@public.gmane.org

#10 lore raw

RE: Sm-notify

Hi,
maybe I can specify Dirks question.

We are trying to set up a NFS Cluster and want to use sm-notify to info= rm the Clients if the Server has failed over.
We have found a Howto that says: sm-notify uses files under /var/lib/nf= s/sm to determine the Clients it has to inform.
Our Problem is, that ther are no files in this place even if we connet = with a client. Is there anything we have forgotten?

Mit freundlichen Gr=FC=DFen
Benjamin Oeltze
Systems Engineer
DE ISC SOP PS N/O
=46ujitsu Siemens Computers
Hildesheimer Str. 25
30880 Laatzen

Telephone:      0511-8489 1872
Mobile: 0160-96354617
Email:  mailto: benjamin.oeltze-/ixSogHR0HOS/[email protected]
Internet:       http://www.fujitsu-siemens.com

=46irmenangaben: http://www.fujitsu-siemens.de/imprint.html

-----Original Message-----
=46rom: NeilBrown [mailto:[email protected]]
Sent: Friday, June 27, 2008 4:23 AM
To: Laurenz, Dirk
Cc: [email protected]; Oeltze, Benjamin
Subject: Re: Sm-notify

Quoted 3 lines · Dirk

Hi,

Does anybody know how sm-notify exactly works on a suse sles 9 system=

?

Quoted 1 line

Yes.

Do you have a specific question about it?

NeilBrown

#11 lore raw

RE: Sm-notify

Quoted 2 lines · On Friday June 27, Benjamin.Oeltze-/ixSogHR0HOS/[email protected]…

Hi,
maybe I can specify Dirks question.

Thanks.

Quoted 4 lines

We are trying to set up a NFS Cluster and want to use sm-notify to inform the Clients if the Server has failed over. We have found a Howto that says: sm-notify uses files under /var/lib/nfs/sm to determine the Clients it has to inform. Our Problem is, that ther are no files in this place even if we connet with a client. Is there anything we have forgotten?

Files do not get created in /var/lib/nfs/sm until the client tried to get a lock on some file (or part of a file). Then the file is created.
Some minutes after the last lock is dropped, the file should be removed (though I recall there were some issues related to that, it might depend on exactly which kernel you are running).

If no file locking is involved, there is no need to inform the client of failover. They will transparently start accessing the new server through the old IP address, possible after a short timeout.

NeilBrown

A message that is not in the archive (sent off-list or not yet received): 18533.31573.855657.391140-wvvUuzkyo1EYVZTmpyfIwg@public.gmane.org

#13 lore raw

RE: Sm-notify

i, the time out is from node a to b seconds, but from node b to a 15 minutes. what I saw was, that the handle changed in /var/lib/nfs/rmtab from 0x000002 to 0x000003 although the fsid is the same on both nodes.
how can the 15minute timeout occur?

Mit freundlichem Gruss,

Dirk Laurenz
Systems Engineer
Fujitsu Siemens Computers
R DE ISC SOP PS N/O
Hildesheimer Strasse 25
30880 Laatzen
Germany

Telephone:              +49 511 84 89 18 08
Telefax:                +49 511 84 89 25 18 08
Mobile:                 +49 170 22 10 781
Email:                  mailto:dirk.laurenz-/ixSogHR0HOS/[email protected]
Internet:               http://www.fujitsu-siemens.com
Firmenangaben:  http://www.fujitsu-siemens.de/imprint.html
Quoted 33 lines

-----Original Message-----
From: Neil Brown [mailto:[email protected]]
Sent: Saturday, June 28, 2008 1:44 AM
To: Oeltze, Benjamin
Cc: Laurenz, Dirk; [email protected]
Subject: RE: Sm-notify

Quoted 2 lines · On Friday June 27, Benjamin.Oeltze-/ixSogHR0HOS/[email protected]…

Hi,
maybe I can specify Dirks question.

Thanks.

Quoted 2 lines

We are trying to set up a NFS Cluster and want to use sm-notify to inform the

Clients if the Server has failed over.

Quoted 1 line

We have found a Howto that says: sm-notify uses files under /var/lib/nfs/sm to

determine the Clients it has to inform.

Quoted 1 line

Our Problem is, that ther are no files in this place even if we connet with a client.

Is there anything we have forgotten?

Files do not get created in /var/lib/nfs/sm until the client tried to get a lock on some file (or part of a file). Then the file is created.
Some minutes after the last lock is dropped, the file should be removed (though I recall there were some issues related to that, it might depend on exactly which kernel you are running).

If no file locking is involved, there is no need to inform the client of failover. They will transparently start accessing the new server through the old IP address, possible after a short timeout.

NeilBrown

#14 lore raw

RE: Sm-notify

Quoted 4 lines · On Saturday June 28, Dirk.Laurenz-/ixSogHR0HOS/[email protected]…

i, the time out is from node a to b seconds, but from node b to a 15 minutes. what I saw was, that the handle changed in /var/lib/nfs/rmtab from 0x000002 to 0x000003 although the fsid is the same on both nodes.
how can the 15minute timeout occur?

The number is rmtab (e.g. 0x000002) is like a reference count. The fact that you sometimes see '2' and sometimes '3' is of no real interest.

I am correct in interpreting what you say as:

When you fail over from 'a' to 'b', it does so quite quickly, but when you then fail back from 'b' to 'a', you get a 15 minute timeout?

If not, please explain in more detail.
If so:
Why exactly are you doing this. It doesn't seem to make sense. Did 'b' get rebooted in the interim?
It could be that you are hitting the same issue discussed here:

    http://linux-nfs.org/pipermail/nfsv4/2008-June/008673.html

and in the surrounding thread.

However this has nothing to do with sm-notify.

NeilBrown