aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ppp_async.c
diff options
context:
space:
mode:
authorGabriele Paoloni <gabriele.paoloni@intel.com>2009-03-13 19:09:12 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-13 19:09:12 -0400
commit9c705260feea6ae329bc6b6d5f6d2ef0227eda0a (patch)
tree0c8dc286ff35bbd0c75be020bee609b771084ae3 /drivers/net/ppp_async.c
parenta2025b8b1039e5abaa38319b2eaab3b17867479a (diff)
ppp: ppp_mp_explode() redesign
I found the PPP subsystem to not work properly when connecting channels with different speeds to the same bundle. Problem Description: As the "ppp_mp_explode" function fragments the sk_buff buffer evenly among the PPP channels that are connected to a certain PPP unit to make up a bundle, if we are transmitting using an upper layer protocol that requires an Ack before sending the next packet (like TCP/IP for example), we will have a bandwidth bottleneck on the slowest channel of the bundle. Let's clarify by an example. Let's consider a scenario where we have two PPP links making up a bundle: a slow link (10KB/sec) and a fast link (1000KB/sec) working at the best (full bandwidth). On the top we have a TCP/IP stack sending a 1000 Bytes sk_buff buffer down to the PPP subsystem. The "ppp_mp_explode" function will divide the buffer in two fragments of 500B each (we are neglecting all the headers, crc, flags etc?.). Before the TCP/IP stack sends out the next buffer, it will have to wait for the ACK response from the remote peer, so it will have to wait for both fragments to have been sent over the two PPP links, received by the remote peer and reconstructed. The resulting behaviour is that, rather than having a bundle working @1010KB/sec (the sum of the channels bandwidths), we'll have a bundle working @20KB/sec (the double of the slowest channels bandwidth). Problem Solution: The problem has been solved by redesigning the "ppp_mp_explode" function in such a way to make it split the sk_buff buffer according to the speeds of the underlying PPP channels (the speeds of the serial interfaces respectively attached to the PPP channels). Referring to the above example, the redesigned "ppp_mp_explode" function will now divide the 1000 Bytes buffer into two fragments whose sizes are set according to the speeds of the channels where they are going to be sent on (e.g . 10 Byets on 10KB/sec channel and 990 Bytes on 1000KB/sec channel). The reworked function grants the same performances of the original one in optimal working conditions (i.e. a bundle made up of PPP links all working at the same speed), while greatly improving performances on the bundles made up of channels working at different speeds. Signed-off-by: Gabriele Paoloni <gabriele.paoloni@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ppp_async.c')
-rw-r--r--drivers/net/ppp_async.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 5de6fedd1d76..6de8399d6dd9 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -157,6 +157,7 @@ ppp_asynctty_open(struct tty_struct *tty)
157{ 157{
158 struct asyncppp *ap; 158 struct asyncppp *ap;
159 int err; 159 int err;
160 int speed;
160 161
161 if (tty->ops->write == NULL) 162 if (tty->ops->write == NULL)
162 return -EOPNOTSUPP; 163 return -EOPNOTSUPP;
@@ -187,6 +188,8 @@ ppp_asynctty_open(struct tty_struct *tty)
187 ap->chan.private = ap; 188 ap->chan.private = ap;
188 ap->chan.ops = &async_ops; 189 ap->chan.ops = &async_ops;
189 ap->chan.mtu = PPP_MRU; 190 ap->chan.mtu = PPP_MRU;
191 speed = tty_get_baud_rate(tty);
192 ap->chan.speed = speed;
190 err = ppp_register_channel(&ap->chan); 193 err = ppp_register_channel(&ap->chan);
191 if (err) 194 if (err)
192 goto out_free; 195 goto out_free;