Skip to content

Commit

Permalink
tcp_probe: avoid modulus operation and wrap fix
Browse files Browse the repository at this point in the history
By rounding up the buffer size to power of 2, several expensive
modulus operations can be avoided.  This patch also solves a bug where
the gap need when ring gets full was not being accounted for.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Jan 25, 2010
1 parent 4f9a91c commit f81074f
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions net/ipv4/tcp_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ static int port __read_mostly = 0;
MODULE_PARM_DESC(port, "Port to match (0=all)");
module_param(port, int, 0);

static int bufsize __read_mostly = 4096;
static unsigned int bufsize __read_mostly = 4096;
MODULE_PARM_DESC(bufsize, "Log buffer size in packets (4096)");
module_param(bufsize, int, 0);
module_param(bufsize, uint, 0);

static int full __read_mostly;
MODULE_PARM_DESC(full, "Full log (1=every ack packet received, 0=only cwnd changes)");
Expand Down Expand Up @@ -75,12 +75,12 @@ static struct {

static inline int tcp_probe_used(void)
{
return (tcp_probe.head - tcp_probe.tail) % bufsize;
return (tcp_probe.head - tcp_probe.tail) & (bufsize - 1);
}

static inline int tcp_probe_avail(void)
{
return bufsize - tcp_probe_used();
return bufsize - tcp_probe_used() - 1;
}

/*
Expand Down Expand Up @@ -116,7 +116,7 @@ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb,
p->ssthresh = tcp_current_ssthresh(sk);
p->srtt = tp->srtt >> 3;

tcp_probe.head = (tcp_probe.head + 1) % bufsize;
tcp_probe.head = (tcp_probe.head + 1) & (bufsize - 1);
}
tcp_probe.lastcwnd = tp->snd_cwnd;
spin_unlock(&tcp_probe.lock);
Expand Down Expand Up @@ -149,7 +149,7 @@ static int tcpprobe_open(struct inode * inode, struct file * file)
static int tcpprobe_sprint(char *tbuf, int n)
{
const struct tcp_log *p
= tcp_probe.log + tcp_probe.tail % bufsize;
= tcp_probe.log + tcp_probe.tail;
struct timespec tv
= ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start));

Expand Down Expand Up @@ -192,7 +192,7 @@ static ssize_t tcpprobe_read(struct file *file, char __user *buf,
width = tcpprobe_sprint(tbuf, sizeof(tbuf));

if (cnt + width < len)
tcp_probe.tail = (tcp_probe.tail + 1) % bufsize;
tcp_probe.tail = (tcp_probe.tail + 1) & (bufsize - 1);

spin_unlock_bh(&tcp_probe.lock);

Expand Down Expand Up @@ -222,9 +222,10 @@ static __init int tcpprobe_init(void)
init_waitqueue_head(&tcp_probe.wait);
spin_lock_init(&tcp_probe.lock);

if (bufsize < 0)
if (bufsize == 0)
return -EINVAL;

bufsize = roundup_pow_of_two(bufsize);
tcp_probe.log = kcalloc(bufsize, sizeof(struct tcp_log), GFP_KERNEL);
if (!tcp_probe.log)
goto err0;
Expand All @@ -236,7 +237,7 @@ static __init int tcpprobe_init(void)
if (ret)
goto err1;

pr_info("TCP probe registered (port=%d)\n", port);
pr_info("TCP probe registered (port=%d) bufsize=%u\n", port, bufsize);
return 0;
err1:
proc_net_remove(&init_net, procname);
Expand Down

0 comments on commit f81074f

Please sign in to comment.