Commit e9c0ce23 authored by Sven Wegener's avatar Sven Wegener Committed by Simon Horman

ipvs: Embed user stats structure into kernel stats structure

Instead of duplicating the fields, integrate a user stats structure into
the kernel stats structure. This is more robust when the members are
changed, because they are now automatically kept in sync.
Signed-off-by: default avatarSven Wegener <sven.wegener@stealer.net>
Reviewed-by: default avatarJulius Volz <juliusv@google.com>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent 2206a3f5
...@@ -254,27 +254,10 @@ struct ip_vs_estimator { ...@@ -254,27 +254,10 @@ struct ip_vs_estimator {
struct ip_vs_stats struct ip_vs_stats
{ {
__u32 conns; /* connections scheduled */ struct ip_vs_stats_user ustats; /* statistics */
__u32 inpkts; /* incoming packets */ struct ip_vs_estimator est; /* estimator */
__u32 outpkts; /* outgoing packets */
__u64 inbytes; /* incoming bytes */
__u64 outbytes; /* outgoing bytes */
__u32 cps; /* current connection rate */
__u32 inpps; /* current in packet rate */
__u32 outpps; /* current out packet rate */
__u32 inbps; /* current in byte rate */
__u32 outbps; /* current out byte rate */
/*
* Don't add anything before the lock, because we use memcpy() to copy
* the members before the lock to struct ip_vs_stats_user in
* ip_vs_ctl.c.
*/
spinlock_t lock; /* spin lock */ spinlock_t lock; /* spin lock */
struct ip_vs_estimator est; /* estimator */
}; };
struct dst_entry; struct dst_entry;
......
...@@ -102,18 +102,18 @@ ip_vs_in_stats(struct ip_vs_conn *cp, struct sk_buff *skb) ...@@ -102,18 +102,18 @@ ip_vs_in_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
struct ip_vs_dest *dest = cp->dest; struct ip_vs_dest *dest = cp->dest;
if (dest && (dest->flags & IP_VS_DEST_F_AVAILABLE)) { if (dest && (dest->flags & IP_VS_DEST_F_AVAILABLE)) {
spin_lock(&dest->stats.lock); spin_lock(&dest->stats.lock);
dest->stats.inpkts++; dest->stats.ustats.inpkts++;
dest->stats.inbytes += skb->len; dest->stats.ustats.inbytes += skb->len;
spin_unlock(&dest->stats.lock); spin_unlock(&dest->stats.lock);
spin_lock(&dest->svc->stats.lock); spin_lock(&dest->svc->stats.lock);
dest->svc->stats.inpkts++; dest->svc->stats.ustats.inpkts++;
dest->svc->stats.inbytes += skb->len; dest->svc->stats.ustats.inbytes += skb->len;
spin_unlock(&dest->svc->stats.lock); spin_unlock(&dest->svc->stats.lock);
spin_lock(&ip_vs_stats.lock); spin_lock(&ip_vs_stats.lock);
ip_vs_stats.inpkts++; ip_vs_stats.ustats.inpkts++;
ip_vs_stats.inbytes += skb->len; ip_vs_stats.ustats.inbytes += skb->len;
spin_unlock(&ip_vs_stats.lock); spin_unlock(&ip_vs_stats.lock);
} }
} }
...@@ -125,18 +125,18 @@ ip_vs_out_stats(struct ip_vs_conn *cp, struct sk_buff *skb) ...@@ -125,18 +125,18 @@ ip_vs_out_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
struct ip_vs_dest *dest = cp->dest; struct ip_vs_dest *dest = cp->dest;
if (dest && (dest->flags & IP_VS_DEST_F_AVAILABLE)) { if (dest && (dest->flags & IP_VS_DEST_F_AVAILABLE)) {
spin_lock(&dest->stats.lock); spin_lock(&dest->stats.lock);
dest->stats.outpkts++; dest->stats.ustats.outpkts++;
dest->stats.outbytes += skb->len; dest->stats.ustats.outbytes += skb->len;
spin_unlock(&dest->stats.lock); spin_unlock(&dest->stats.lock);
spin_lock(&dest->svc->stats.lock); spin_lock(&dest->svc->stats.lock);
dest->svc->stats.outpkts++; dest->svc->stats.ustats.outpkts++;
dest->svc->stats.outbytes += skb->len; dest->svc->stats.ustats.outbytes += skb->len;
spin_unlock(&dest->svc->stats.lock); spin_unlock(&dest->svc->stats.lock);
spin_lock(&ip_vs_stats.lock); spin_lock(&ip_vs_stats.lock);
ip_vs_stats.outpkts++; ip_vs_stats.ustats.outpkts++;
ip_vs_stats.outbytes += skb->len; ip_vs_stats.ustats.outbytes += skb->len;
spin_unlock(&ip_vs_stats.lock); spin_unlock(&ip_vs_stats.lock);
} }
} }
...@@ -146,15 +146,15 @@ static inline void ...@@ -146,15 +146,15 @@ static inline void
ip_vs_conn_stats(struct ip_vs_conn *cp, struct ip_vs_service *svc) ip_vs_conn_stats(struct ip_vs_conn *cp, struct ip_vs_service *svc)
{ {
spin_lock(&cp->dest->stats.lock); spin_lock(&cp->dest->stats.lock);
cp->dest->stats.conns++; cp->dest->stats.ustats.conns++;
spin_unlock(&cp->dest->stats.lock); spin_unlock(&cp->dest->stats.lock);
spin_lock(&svc->stats.lock); spin_lock(&svc->stats.lock);
svc->stats.conns++; svc->stats.ustats.conns++;
spin_unlock(&svc->stats.lock); spin_unlock(&svc->stats.lock);
spin_lock(&ip_vs_stats.lock); spin_lock(&ip_vs_stats.lock);
ip_vs_stats.conns++; ip_vs_stats.ustats.conns++;
spin_unlock(&ip_vs_stats.lock); spin_unlock(&ip_vs_stats.lock);
} }
......
...@@ -744,18 +744,7 @@ ip_vs_zero_stats(struct ip_vs_stats *stats) ...@@ -744,18 +744,7 @@ ip_vs_zero_stats(struct ip_vs_stats *stats)
{ {
spin_lock_bh(&stats->lock); spin_lock_bh(&stats->lock);
stats->conns = 0; memset(&stats->ustats, 0, sizeof(stats->ustats));
stats->inpkts = 0;
stats->outpkts = 0;
stats->inbytes = 0;
stats->outbytes = 0;
stats->cps = 0;
stats->inpps = 0;
stats->outpps = 0;
stats->inbps = 0;
stats->outbps = 0;
ip_vs_zero_estimator(stats); ip_vs_zero_estimator(stats);
spin_unlock_bh(&stats->lock); spin_unlock_bh(&stats->lock);
...@@ -1964,20 +1953,20 @@ static int ip_vs_stats_show(struct seq_file *seq, void *v) ...@@ -1964,20 +1953,20 @@ static int ip_vs_stats_show(struct seq_file *seq, void *v)
" Conns Packets Packets Bytes Bytes\n"); " Conns Packets Packets Bytes Bytes\n");
spin_lock_bh(&ip_vs_stats.lock); spin_lock_bh(&ip_vs_stats.lock);
seq_printf(seq, "%8X %8X %8X %16LX %16LX\n\n", ip_vs_stats.conns, seq_printf(seq, "%8X %8X %8X %16LX %16LX\n\n", ip_vs_stats.ustats.conns,
ip_vs_stats.inpkts, ip_vs_stats.outpkts, ip_vs_stats.ustats.inpkts, ip_vs_stats.ustats.outpkts,
(unsigned long long) ip_vs_stats.inbytes, (unsigned long long) ip_vs_stats.ustats.inbytes,
(unsigned long long) ip_vs_stats.outbytes); (unsigned long long) ip_vs_stats.ustats.outbytes);
/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ /* 01234567 01234567 01234567 0123456701234567 0123456701234567 */
seq_puts(seq, seq_puts(seq,
" Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n"); " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n");
seq_printf(seq,"%8X %8X %8X %16X %16X\n", seq_printf(seq,"%8X %8X %8X %16X %16X\n",
ip_vs_stats.cps, ip_vs_stats.ustats.cps,
ip_vs_stats.inpps, ip_vs_stats.ustats.inpps,
ip_vs_stats.outpps, ip_vs_stats.ustats.outpps,
ip_vs_stats.inbps, ip_vs_stats.ustats.inbps,
ip_vs_stats.outbps); ip_vs_stats.ustats.outbps);
spin_unlock_bh(&ip_vs_stats.lock); spin_unlock_bh(&ip_vs_stats.lock);
return 0; return 0;
...@@ -2215,7 +2204,7 @@ static void ...@@ -2215,7 +2204,7 @@ static void
ip_vs_copy_stats(struct ip_vs_stats_user *dst, struct ip_vs_stats *src) ip_vs_copy_stats(struct ip_vs_stats_user *dst, struct ip_vs_stats *src)
{ {
spin_lock_bh(&src->lock); spin_lock_bh(&src->lock);
memcpy(dst, src, (char*)&src->lock - (char*)src); memcpy(dst, &src->ustats, sizeof(*dst));
spin_unlock_bh(&src->lock); spin_unlock_bh(&src->lock);
} }
...@@ -2591,16 +2580,16 @@ static int ip_vs_genl_fill_stats(struct sk_buff *skb, int container_type, ...@@ -2591,16 +2580,16 @@ static int ip_vs_genl_fill_stats(struct sk_buff *skb, int container_type,
spin_lock_bh(&stats->lock); spin_lock_bh(&stats->lock);
NLA_PUT_U32(skb, IPVS_STATS_ATTR_CONNS, stats->conns); NLA_PUT_U32(skb, IPVS_STATS_ATTR_CONNS, stats->ustats.conns);
NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPKTS, stats->inpkts); NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPKTS, stats->ustats.inpkts);
NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPKTS, stats->outpkts); NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPKTS, stats->ustats.outpkts);
NLA_PUT_U64(skb, IPVS_STATS_ATTR_INBYTES, stats->inbytes); NLA_PUT_U64(skb, IPVS_STATS_ATTR_INBYTES, stats->ustats.inbytes);
NLA_PUT_U64(skb, IPVS_STATS_ATTR_OUTBYTES, stats->outbytes); NLA_PUT_U64(skb, IPVS_STATS_ATTR_OUTBYTES, stats->ustats.outbytes);
NLA_PUT_U32(skb, IPVS_STATS_ATTR_CPS, stats->cps); NLA_PUT_U32(skb, IPVS_STATS_ATTR_CPS, stats->ustats.cps);
NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPPS, stats->inpps); NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPPS, stats->ustats.inpps);
NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPPS, stats->outpps); NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPPS, stats->ustats.outpps);
NLA_PUT_U32(skb, IPVS_STATS_ATTR_INBPS, stats->inbps); NLA_PUT_U32(skb, IPVS_STATS_ATTR_INBPS, stats->ustats.inbps);
NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTBPS, stats->outbps); NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTBPS, stats->ustats.outbps);
spin_unlock_bh(&stats->lock); spin_unlock_bh(&stats->lock);
......
...@@ -65,37 +65,37 @@ static void estimation_timer(unsigned long arg) ...@@ -65,37 +65,37 @@ static void estimation_timer(unsigned long arg)
s = container_of(e, struct ip_vs_stats, est); s = container_of(e, struct ip_vs_stats, est);
spin_lock(&s->lock); spin_lock(&s->lock);
n_conns = s->conns; n_conns = s->ustats.conns;
n_inpkts = s->inpkts; n_inpkts = s->ustats.inpkts;
n_outpkts = s->outpkts; n_outpkts = s->ustats.outpkts;
n_inbytes = s->inbytes; n_inbytes = s->ustats.inbytes;
n_outbytes = s->outbytes; n_outbytes = s->ustats.outbytes;
/* scaled by 2^10, but divided 2 seconds */ /* scaled by 2^10, but divided 2 seconds */
rate = (n_conns - e->last_conns)<<9; rate = (n_conns - e->last_conns)<<9;
e->last_conns = n_conns; e->last_conns = n_conns;
e->cps += ((long)rate - (long)e->cps)>>2; e->cps += ((long)rate - (long)e->cps)>>2;
s->cps = (e->cps+0x1FF)>>10; s->ustats.cps = (e->cps+0x1FF)>>10;
rate = (n_inpkts - e->last_inpkts)<<9; rate = (n_inpkts - e->last_inpkts)<<9;
e->last_inpkts = n_inpkts; e->last_inpkts = n_inpkts;
e->inpps += ((long)rate - (long)e->inpps)>>2; e->inpps += ((long)rate - (long)e->inpps)>>2;
s->inpps = (e->inpps+0x1FF)>>10; s->ustats.inpps = (e->inpps+0x1FF)>>10;
rate = (n_outpkts - e->last_outpkts)<<9; rate = (n_outpkts - e->last_outpkts)<<9;
e->last_outpkts = n_outpkts; e->last_outpkts = n_outpkts;
e->outpps += ((long)rate - (long)e->outpps)>>2; e->outpps += ((long)rate - (long)e->outpps)>>2;
s->outpps = (e->outpps+0x1FF)>>10; s->ustats.outpps = (e->outpps+0x1FF)>>10;
rate = (n_inbytes - e->last_inbytes)<<4; rate = (n_inbytes - e->last_inbytes)<<4;
e->last_inbytes = n_inbytes; e->last_inbytes = n_inbytes;
e->inbps += ((long)rate - (long)e->inbps)>>2; e->inbps += ((long)rate - (long)e->inbps)>>2;
s->inbps = (e->inbps+0xF)>>5; s->ustats.inbps = (e->inbps+0xF)>>5;
rate = (n_outbytes - e->last_outbytes)<<4; rate = (n_outbytes - e->last_outbytes)<<4;
e->last_outbytes = n_outbytes; e->last_outbytes = n_outbytes;
e->outbps += ((long)rate - (long)e->outbps)>>2; e->outbps += ((long)rate - (long)e->outbps)>>2;
s->outbps = (e->outbps+0xF)>>5; s->ustats.outbps = (e->outbps+0xF)>>5;
spin_unlock(&s->lock); spin_unlock(&s->lock);
} }
spin_unlock(&est_lock); spin_unlock(&est_lock);
...@@ -108,20 +108,20 @@ void ip_vs_new_estimator(struct ip_vs_stats *stats) ...@@ -108,20 +108,20 @@ void ip_vs_new_estimator(struct ip_vs_stats *stats)
INIT_LIST_HEAD(&est->list); INIT_LIST_HEAD(&est->list);
est->last_conns = stats->conns; est->last_conns = stats->ustats.conns;
est->cps = stats->cps<<10; est->cps = stats->ustats.cps<<10;
est->last_inpkts = stats->inpkts; est->last_inpkts = stats->ustats.inpkts;
est->inpps = stats->inpps<<10; est->inpps = stats->ustats.inpps<<10;
est->last_outpkts = stats->outpkts; est->last_outpkts = stats->ustats.outpkts;
est->outpps = stats->outpps<<10; est->outpps = stats->ustats.outpps<<10;
est->last_inbytes = stats->inbytes; est->last_inbytes = stats->ustats.inbytes;
est->inbps = stats->inbps<<5; est->inbps = stats->ustats.inbps<<5;
est->last_outbytes = stats->outbytes; est->last_outbytes = stats->ustats.outbytes;
est->outbps = stats->outbps<<5; est->outbps = stats->ustats.outbps<<5;
spin_lock_bh(&est_lock); spin_lock_bh(&est_lock);
list_add(&est->list, &est_list); list_add(&est->list, &est_list);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment