From ded7aa682cd2ffd9e7d90a8d9a8a715d11df3554 Mon Sep 17 00:00:00 2001 From: Xuan Zhuo Date: Thu, 4 Jun 2020 14:39:27 +0800 Subject: [PATCH 1728/2944] alinux: tcp_rt module: support pports_range to #27804112 remove con_num from struct tcp_rt_stats, that is not used. Add new type TCPRT_TYPE_PEER_PORT_RANG, then stats_peer also use the two-dimensional array. Signed-off-by: Xuan Zhuo Acked-by: Dust Li Reviewed-by: Ya Zhao Reviewed-by: Cambda Zhu --- net/ipv4/tcp_rt/core.c | 35 +++++++++++++++---- net/ipv4/tcp_rt/output.c | 87 ++++++++++++++++++++++++------------------------ net/ipv4/tcp_rt/tcp_rt.h | 5 ++- 3 files changed, 75 insertions(+), 52 deletions(-) diff --git a/net/ipv4/tcp_rt/core.c b/net/ipv4/tcp_rt/core.c index 47d2582..3a3eee4 100644 --- a/net/ipv4/tcp_rt/core.c +++ b/net/ipv4/tcp_rt/core.c @@ -5,10 +5,12 @@ static int lports_number; static int pports_number; static int lports_range_number; +static int pports_range_number; static int lports[PORT_MAX_NUM]; static int pports[PORT_MAX_NUM]; static int lports_range[PORT_MAX_NUM]; +static int pports_range[PORT_MAX_NUM]; static int log_buf_num = 8; static int stats_buf_num = 2; @@ -31,6 +33,9 @@ module_param_array(pports, int, &pports_number, 0644); MODULE_PARM_DESC(pports, "peer port array. config: pports=80,3306"); +module_param_array(pports_range, int, &pports_range_number, 0644); +MODULE_PARM_DESC(pports_range, "peer port range array. config: pports_range=1000,2000,3500,4000. means: 1000-2000 or 3500-4000"); + module_param(log_buf_num, int, 0644); MODULE_PARM_DESC(log_buf_num, "the num of buffers for every cpu log buffer. unit is 256k. just work when module load."); module_param(stats_buf_num, int, 0644); @@ -44,17 +49,24 @@ static void tcp_rt_timer_handler(struct timer_list *t) int i, port; for (i = 0; i < lports_number; i++) - tcp_rt_timer_output(0, lports[i], "L"); + tcp_rt_timer_output(lports[i], "L", true); for (i = 0; i < lports_range_number / 2; ++i) { for (port = lports_range[i * 2]; port <= lports_range[i * 2 + 1]; ++port) { - tcp_rt_timer_output(PORT_MAX_NUM, port, "L"); + tcp_rt_timer_output(port, "L", false); } } for (i = 0; i < pports_number; i++) - tcp_rt_timer_output(i, pports[i], "P"); + tcp_rt_timer_output(pports[i], "P", true); + + for (i = 0; i < pports_range_number / 2; ++i) { + for (port = pports_range[i * 2]; + port <= pports_range[i * 2 + 1]; ++port) { + tcp_rt_timer_output(port, "P", false); + } + } } mod_timer(&tcp_rt_timer, jiffies + stats_interval * HZ); } @@ -236,7 +248,7 @@ static void tcp_rt_sk_release(struct sock *sk) if (!rt->request_num) goto free; - if (rt->type == TCPRT_TYPE_PEER_PORT) + if (rt->type >= TCPRT_TYPE_PEER_PORT) tcp_rt_sk_release_peer(sk, rt, tp); else tcp_rt_sk_release_local(sk, rt, tp); @@ -264,7 +276,7 @@ static void tcp_rt_sk_send_data(struct sock *sk) struct tcp_sock *tp = tcp_sk(sk); struct tcp_rt *rt = TCP_SK_RT(sk); - if (rt->type == TCPRT_TYPE_PEER_PORT) + if (rt->type >= TCPRT_TYPE_PEER_PORT) return tcp_rt_sk_send_data_peer(sk, rt, tp); else return tcp_rt_sk_send_data_local(sk, rt, tp); @@ -275,7 +287,7 @@ static void tcp_rt_sk_recv_data(struct sock *sk) struct tcp_rt *rt = TCP_SK_RT(sk); struct tcp_sock *tp = tcp_sk(sk); - if (rt->type == TCPRT_TYPE_PEER_PORT) + if (rt->type >= TCPRT_TYPE_PEER_PORT) return tcp_rt_sk_recv_data_peer(sk, rt, tp); else return tcp_rt_sk_recv_data_local(sk, rt, tp); @@ -319,6 +331,17 @@ static int tcp_rt_sk_init(struct sock *sk) } } + for (i = 0; i < pports_range_number / 2; ++i) { + if (port < pports_range[i * 2]) + continue; + + if (port > pports_range[i * 2 + 1]) + continue; + + type = TCPRT_TYPE_PEER_PORT_RANG; + goto ok; + } + return -1; ok: rt = kmalloc(sizeof(*rt), GFP_ATOMIC); diff --git a/net/ipv4/tcp_rt/output.c b/net/ipv4/tcp_rt/output.c index 337875e..582ae35 100644 --- a/net/ipv4/tcp_rt/output.c +++ b/net/ipv4/tcp_rt/output.c @@ -13,18 +13,16 @@ static struct dentry *tcprt_dir; static struct tcp_rt_stats *stats_local[CHUNK_COUNT]; -static struct tcp_rt_stats stats_peer[PORT_MAX_NUM]; +static struct tcp_rt_stats *stats_peer[CHUNK_COUNT]; -#define stats_local_inc(item) atomic64_inc(&(item)) -#define stats_local_add(item, val) atomic64_add(val, &(item)) - -#define stats_peer_inc(rt, item) \ - atomic64_inc(&stats_peer[(rt)->index].item) -#define stats_peer_add(rt, item, val) \ - atomic64_add(val, &stats_peer[(rt)->index].item) +#define stats_inc(item) atomic64_inc(&(item)) +#define stats_add(item, val) atomic64_add(val, &(item)) #define tcp_rt_get_local_stats_sk(sk) \ - tcp_rt_get_local_stats(ntohs(inet_sk(sk)->inet_sport), true) + tcp_rt_get_stats(stats_local, ntohs(inet_sk(sk)->inet_sport), true) + +#define tcp_rt_get_peer_stats_sk(sk) \ + tcp_rt_get_stats(stats_peer, ntohs(inet_sk(sk)->inet_dport), true) static int64_t timespec64_dec(struct timespec64 tv1, struct timespec64 tv2) { @@ -77,14 +75,15 @@ static int ip_format2(char *buf, u32 addr, char end) return idx; } -static struct tcp_rt_stats *tcp_rt_get_local_stats(int port, bool alloc) +static struct tcp_rt_stats *tcp_rt_get_stats(struct tcp_rt_stats **stats, + int port, bool alloc) { int chunkid; struct tcp_rt_stats *p; chunkid = port / PORTS_PER_CHUNK; - p = stats_local[chunkid]; + p = stats[chunkid]; if (unlikely(!p)) { if (!alloc) @@ -96,9 +95,9 @@ static struct tcp_rt_stats *tcp_rt_get_local_stats(int port, bool alloc) memset(p, 0, CHUNK_SIZE); - if (cmpxchg(&stats_local[chunkid], NULL, p)) { + if (cmpxchg(&stats[chunkid], NULL, p)) { vfree(p); - p = READ_ONCE(stats_local[chunkid]); + p = READ_ONCE(stats[chunkid]); } } @@ -182,17 +181,16 @@ void tcp_rt_log_printk(const struct sock *sk, char flag, bool fin, bool stats) if (!r) break; - stats_local_inc(r->number); - - stats_local_add(r->rt, t_rt); - stats_local_add(r->bytes, t_seq); - stats_local_add(r->drop, t_retrans); - stats_local_add(r->packets, - t_seq / tp->mss_cache + 1); - stats_local_add(r->server_time, rt->server_time); - stats_local_add(r->upload_time, rt->upload_time); - stats_local_add(r->upload_data, rt->upload_data); - stats_local_add(r->rtt, mrtt); + stats_inc(r->number); + + stats_add(r->rt, t_rt); + stats_add(r->bytes, t_seq); + stats_add(r->drop, t_retrans); + stats_add(r->packets, t_seq / tp->mss_cache + 1); + stats_add(r->server_time, rt->server_time); + stats_add(r->upload_time, rt->upload_time); + stats_add(r->upload_data, rt->upload_data); + stats_add(r->rtt, mrtt); } break; @@ -220,7 +218,7 @@ void tcp_rt_log_printk(const struct sock *sk, char flag, bool fin, bool stats) if (!r) break; - stats_local_inc(r->fail); + stats_inc(r->fail); } break; @@ -268,12 +266,17 @@ void tcp_rt_log_printk(const struct sock *sk, char flag, bool fin, bool stats) buf[size++] = '\n'; if (stats) { - stats_peer_inc(rt, number); - stats_peer_add(rt, bytes, t_seq); - stats_peer_add(rt, rt, t_rt); - stats_peer_add(rt, packets, t_seq / tp->mss_cache + 1); - stats_peer_add(rt, drop, t_retrans); - stats_peer_add(rt, rtt, mrtt); + r = tcp_rt_get_peer_stats_sk(sk); + if (!r) + break; + + stats_inc(r->number); + + stats_add(r->bytes, t_seq); + stats_add(r->rt, t_rt); + stats_add(r->packets, t_seq / tp->mss_cache + 1); + stats_add(r->drop, t_retrans); + stats_add(r->rtt, mrtt); } break; } @@ -282,9 +285,10 @@ void tcp_rt_log_printk(const struct sock *sk, char flag, bool fin, bool stats) relay_write(relay_log, buf, size); } -void tcp_rt_timer_output(int index, int port, char *flag) +void tcp_rt_timer_output(int port, char *flag, bool alloc) { struct tcp_rt_stats *r; + struct tcp_rt_stats **stats; struct _tcp_rt_stats t; struct _tcp_rt_stats avg = {0}; int size; @@ -292,21 +296,19 @@ void tcp_rt_timer_output(int index, int port, char *flag) char buf[MAX_BUF_SIZE]; if (*flag == 'L') { - if (index == PORT_MAX_NUM) - r = tcp_rt_get_local_stats(port, false); - else - r = tcp_rt_get_local_stats(port, true); - - if (!r) - return; - flag = ""; + stats = stats_local; } else { - r = stats_peer + index; + stats = stats_peer; } + r = tcp_rt_get_stats(stats, port, alloc); + + if (!r) + return; + t.number = atomic64_xchg(&r->number, 0); - if (!t.number && index == PORT_MAX_NUM) + if (!t.number && !alloc) return; t.server_time = atomic64_xchg(&r->server_time, 0); @@ -315,7 +317,6 @@ void tcp_rt_timer_output(int index, int port, char *flag) t.drop = atomic64_xchg(&r->drop, 0); t.fail = atomic64_xchg(&r->fail, 0); t.packets = atomic64_xchg(&r->packets, 0); - t.con_num = atomic64_xchg(&r->con_num, 0); t.rtt = atomic64_xchg(&r->rtt, 0); t.upload_time = atomic64_xchg(&r->upload_time, 0); t.upload_data = atomic64_xchg(&r->upload_data, 0); diff --git a/net/ipv4/tcp_rt/tcp_rt.h b/net/ipv4/tcp_rt/tcp_rt.h index fa48820..eace38a 100644 --- a/net/ipv4/tcp_rt/tcp_rt.h +++ b/net/ipv4/tcp_rt/tcp_rt.h @@ -34,6 +34,7 @@ enum tcp_rt_type { TCPRT_TYPE_LOCAL_PORT, TCPRT_TYPE_LOCAL_PORT_RANG, TCPRT_TYPE_PEER_PORT, + TCPRT_TYPE_PEER_PORT_RANG, }; enum tcp_rt_stage { @@ -91,7 +92,6 @@ struct tcp_rt_stats { atomic64_t rtt; atomic64_t upload_time; atomic64_t upload_data; - atomic64_t con_num; }; struct _tcp_rt_stats { @@ -105,11 +105,10 @@ struct _tcp_rt_stats { u64 rtt; u64 upload_time; u64 upload_data; - u64 con_num; }; int tcp_rt_output_init(int log_buf_num, int stats_buf_num, const struct file_operations *fops); void tcp_rt_output_released(void); void tcp_rt_log_printk(const struct sock *sk, char flag, bool fin, bool check); -void tcp_rt_timer_output(int index, int port, char *flag); +void tcp_rt_timer_output(int port, char *flag, bool alloc); -- 1.8.3.1