Commit c8e98343 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mptcp-don-t-auto-adjust-rcvbuf-size-if-locked'



Florian Westphal says:

====================
mptcp: don't auto-adjust rcvbuf size if locked

The mptcp receive buffer is auto-sized based on the subflow receive
buffer.  Don't do this if userspace specfied a value via SO_RCVBUF
setsockopt.

Also update selftest program to provide a new option to set a fixed
size.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 37feab60 ec33916d
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -141,11 +141,13 @@ static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
	bool more_data_avail;
	struct tcp_sock *tp;
	bool done = false;
	int rcvbuf;

	rcvbuf = max(ssk->sk_rcvbuf, sk->sk_rcvbuf);
	if (!(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
		int rcvbuf = max(ssk->sk_rcvbuf, sk->sk_rcvbuf);

		if (rcvbuf > sk->sk_rcvbuf)
			sk->sk_rcvbuf = rcvbuf;
	}

	tp = tcp_sk(ssk);
	do {
+35 −10
Original line number Diff line number Diff line
@@ -34,8 +34,8 @@ extern int optind;
#define TCP_ULP 31
#endif

static int  poll_timeout = 10 * 1000;
static bool listen_mode;
static int  poll_timeout;

enum cfg_mode {
	CFG_MODE_POLL,
@@ -50,11 +50,20 @@ static int cfg_sock_proto = IPPROTO_MPTCP;
static bool tcpulp_audit;
static int pf = AF_INET;
static int cfg_sndbuf;
static int cfg_rcvbuf;

static void die_usage(void)
{
	fprintf(stderr, "Usage: mptcp_connect [-6] [-u] [-s MPTCP|TCP] [-p port] -m mode]"
		"[ -l ] [ -t timeout ] connect_address\n");
	fprintf(stderr, "Usage: mptcp_connect [-6] [-u] [-s MPTCP|TCP] [-p port] [-m mode]"
		"[-l] connect_address\n");
	fprintf(stderr, "\t-6 use ipv6\n");
	fprintf(stderr, "\t-t num -- set poll timeout to num\n");
	fprintf(stderr, "\t-S num -- set SO_SNDBUF to num\n");
	fprintf(stderr, "\t-R num -- set SO_RCVBUF to num\n");
	fprintf(stderr, "\t-p num -- use port num\n");
	fprintf(stderr, "\t-m [MPTCP|TCP] -- use tcp or mptcp sockets\n");
	fprintf(stderr, "\t-s [mmap|poll] -- use poll (default) or mmap\n");
	fprintf(stderr, "\t-u -- check mptcp ulp\n");
	exit(1);
}

@@ -97,6 +106,17 @@ static void xgetaddrinfo(const char *node, const char *service,
	}
}

static void set_rcvbuf(int fd, unsigned int size)
{
	int err;

	err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
	if (err) {
		perror("set SO_RCVBUF");
		exit(1);
	}
}

static void set_sndbuf(int fd, unsigned int size)
{
	int err;
@@ -704,6 +724,8 @@ int main_loop(void)

	check_getpeername_connect(fd);

	if (cfg_rcvbuf)
		set_rcvbuf(fd, cfg_rcvbuf);
	if (cfg_sndbuf)
		set_sndbuf(fd, cfg_sndbuf);

@@ -745,7 +767,7 @@ int parse_mode(const char *mode)
	return 0;
}

int parse_sndbuf(const char *size)
static int parse_int(const char *size)
{
	unsigned long s;

@@ -765,16 +787,14 @@ int parse_sndbuf(const char *size)
		die_usage();
	}

	cfg_sndbuf = s;

	return 0;
	return (int)s;
}

static void parse_opts(int argc, char **argv)
{
	int c;

	while ((c = getopt(argc, argv, "6lp:s:hut:m:b:")) != -1) {
	while ((c = getopt(argc, argv, "6lp:s:hut:m:S:R:")) != -1) {
		switch (c) {
		case 'l':
			listen_mode = true;
@@ -802,8 +822,11 @@ static void parse_opts(int argc, char **argv)
		case 'm':
			cfg_mode = parse_mode(optarg);
			break;
		case 'b':
			cfg_sndbuf = parse_sndbuf(optarg);
		case 'S':
			cfg_sndbuf = parse_int(optarg);
			break;
		case 'R':
			cfg_rcvbuf = parse_int(optarg);
			break;
		}
	}
@@ -831,6 +854,8 @@ int main(int argc, char *argv[])
		if (fd < 0)
			return 1;

		if (cfg_rcvbuf)
			set_rcvbuf(fd, cfg_rcvbuf);
		if (cfg_sndbuf)
			set_sndbuf(fd, cfg_sndbuf);

+19 −5
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@

time_start=$(date +%s)

optstring="b:d:e:l:r:h4cm:"
optstring="S:R:d:e:l:r:h4cm:"
ret=0
sin=""
sout=""
@@ -19,6 +19,7 @@ tc_loss=$((RANDOM%101))
tc_reorder=""
testmode=""
sndbuf=0
rcvbuf=0
options_log=true

if [ $tc_loss -eq 100 ];then
@@ -39,7 +40,8 @@ usage() {
	echo -e "\t-e: ethtool features to disable, e.g.: \"-e tso -e gso\" (default: randomly disable any of tso/gso/gro)"
	echo -e "\t-4: IPv4 only: disable IPv6 tests (default: test both IPv4 and IPv6)"
	echo -e "\t-c: capture packets for each test using tcpdump (default: no capture)"
	echo -e "\t-b: set sndbuf value (default: use kernel default)"
	echo -e "\t-S: set sndbuf value (default: use kernel default)"
	echo -e "\t-R: set rcvbuf value (default: use kernel default)"
	echo -e "\t-m: test mode (poll, sendfile; default: poll)"
}

@@ -73,11 +75,19 @@ while getopts "$optstring" option;do
	"c")
		capture=true
		;;
	"b")
	"S")
		if [ $OPTARG -ge 0 ];then
			sndbuf="$OPTARG"
		else
			echo "-s requires numeric argument, got \"$OPTARG\"" 1>&2
			echo "-S requires numeric argument, got \"$OPTARG\"" 1>&2
			exit 1
		fi
		;;
	"R")
		if [ $OPTARG -ge 0 ];then
			rcvbuf="$OPTARG"
		else
			echo "-R requires numeric argument, got \"$OPTARG\"" 1>&2
			exit 1
		fi
		;;
@@ -342,8 +352,12 @@ do_transfer()
	port=$((10000+$TEST_COUNT))
	TEST_COUNT=$((TEST_COUNT+1))

	if [ "$rcvbuf" -gt 0 ]; then
		extra_args="$extra_args -R $rcvbuf"
	fi

	if [ "$sndbuf" -gt 0 ]; then
		extra_args="$extra_args -b $sndbuf"
		extra_args="$extra_args -S $sndbuf"
	fi

	if [ -n "$testmode" ]; then