This source file includes following definitions.
- ip_vs_read_cpu_stats
- estimation_timer
- ip_vs_start_estimator
- ip_vs_stop_estimator
- ip_vs_zero_estimator
- ip_vs_read_estimator
- ip_vs_estimator_net_init
- ip_vs_estimator_net_cleanup
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 #define KMSG_COMPONENT "IPVS"
  16 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  17 
  18 #include <linux/kernel.h>
  19 #include <linux/jiffies.h>
  20 #include <linux/types.h>
  21 #include <linux/interrupt.h>
  22 #include <linux/sysctl.h>
  23 #include <linux/list.h>
  24 
  25 #include <net/ip_vs.h>
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 
  45 
  46 
  47 
  48 
  49 
  50 
  51 
  52 
  53 
  54 
  55 
  56 static void ip_vs_read_cpu_stats(struct ip_vs_kstats *sum,
  57                                  struct ip_vs_cpu_stats __percpu *stats)
  58 {
  59         int i;
  60         bool add = false;
  61 
  62         for_each_possible_cpu(i) {
  63                 struct ip_vs_cpu_stats *s = per_cpu_ptr(stats, i);
  64                 unsigned int start;
  65                 u64 conns, inpkts, outpkts, inbytes, outbytes;
  66 
  67                 if (add) {
  68                         do {
  69                                 start = u64_stats_fetch_begin(&s->syncp);
  70                                 conns = s->cnt.conns;
  71                                 inpkts = s->cnt.inpkts;
  72                                 outpkts = s->cnt.outpkts;
  73                                 inbytes = s->cnt.inbytes;
  74                                 outbytes = s->cnt.outbytes;
  75                         } while (u64_stats_fetch_retry(&s->syncp, start));
  76                         sum->conns += conns;
  77                         sum->inpkts += inpkts;
  78                         sum->outpkts += outpkts;
  79                         sum->inbytes += inbytes;
  80                         sum->outbytes += outbytes;
  81                 } else {
  82                         add = true;
  83                         do {
  84                                 start = u64_stats_fetch_begin(&s->syncp);
  85                                 sum->conns = s->cnt.conns;
  86                                 sum->inpkts = s->cnt.inpkts;
  87                                 sum->outpkts = s->cnt.outpkts;
  88                                 sum->inbytes = s->cnt.inbytes;
  89                                 sum->outbytes = s->cnt.outbytes;
  90                         } while (u64_stats_fetch_retry(&s->syncp, start));
  91                 }
  92         }
  93 }
  94 
  95 
  96 static void estimation_timer(struct timer_list *t)
  97 {
  98         struct ip_vs_estimator *e;
  99         struct ip_vs_stats *s;
 100         u64 rate;
 101         struct netns_ipvs *ipvs = from_timer(ipvs, t, est_timer);
 102 
 103         spin_lock(&ipvs->est_lock);
 104         list_for_each_entry(e, &ipvs->est_list, list) {
 105                 s = container_of(e, struct ip_vs_stats, est);
 106 
 107                 spin_lock(&s->lock);
 108                 ip_vs_read_cpu_stats(&s->kstats, s->cpustats);
 109 
 110                 
 111                 rate = (s->kstats.conns - e->last_conns) << 9;
 112                 e->last_conns = s->kstats.conns;
 113                 e->cps += ((s64)rate - (s64)e->cps) >> 2;
 114 
 115                 rate = (s->kstats.inpkts - e->last_inpkts) << 9;
 116                 e->last_inpkts = s->kstats.inpkts;
 117                 e->inpps += ((s64)rate - (s64)e->inpps) >> 2;
 118 
 119                 rate = (s->kstats.outpkts - e->last_outpkts) << 9;
 120                 e->last_outpkts = s->kstats.outpkts;
 121                 e->outpps += ((s64)rate - (s64)e->outpps) >> 2;
 122 
 123                 
 124                 rate = (s->kstats.inbytes - e->last_inbytes) << 4;
 125                 e->last_inbytes = s->kstats.inbytes;
 126                 e->inbps += ((s64)rate - (s64)e->inbps) >> 2;
 127 
 128                 rate = (s->kstats.outbytes - e->last_outbytes) << 4;
 129                 e->last_outbytes = s->kstats.outbytes;
 130                 e->outbps += ((s64)rate - (s64)e->outbps) >> 2;
 131                 spin_unlock(&s->lock);
 132         }
 133         spin_unlock(&ipvs->est_lock);
 134         mod_timer(&ipvs->est_timer, jiffies + 2*HZ);
 135 }
 136 
 137 void ip_vs_start_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats)
 138 {
 139         struct ip_vs_estimator *est = &stats->est;
 140 
 141         INIT_LIST_HEAD(&est->list);
 142 
 143         spin_lock_bh(&ipvs->est_lock);
 144         list_add(&est->list, &ipvs->est_list);
 145         spin_unlock_bh(&ipvs->est_lock);
 146 }
 147 
 148 void ip_vs_stop_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats)
 149 {
 150         struct ip_vs_estimator *est = &stats->est;
 151 
 152         spin_lock_bh(&ipvs->est_lock);
 153         list_del(&est->list);
 154         spin_unlock_bh(&ipvs->est_lock);
 155 }
 156 
 157 void ip_vs_zero_estimator(struct ip_vs_stats *stats)
 158 {
 159         struct ip_vs_estimator *est = &stats->est;
 160         struct ip_vs_kstats *k = &stats->kstats;
 161 
 162         
 163         est->last_inbytes = k->inbytes;
 164         est->last_outbytes = k->outbytes;
 165         est->last_conns = k->conns;
 166         est->last_inpkts = k->inpkts;
 167         est->last_outpkts = k->outpkts;
 168         est->cps = 0;
 169         est->inpps = 0;
 170         est->outpps = 0;
 171         est->inbps = 0;
 172         est->outbps = 0;
 173 }
 174 
 175 
 176 void ip_vs_read_estimator(struct ip_vs_kstats *dst, struct ip_vs_stats *stats)
 177 {
 178         struct ip_vs_estimator *e = &stats->est;
 179 
 180         dst->cps = (e->cps + 0x1FF) >> 10;
 181         dst->inpps = (e->inpps + 0x1FF) >> 10;
 182         dst->outpps = (e->outpps + 0x1FF) >> 10;
 183         dst->inbps = (e->inbps + 0xF) >> 5;
 184         dst->outbps = (e->outbps + 0xF) >> 5;
 185 }
 186 
 187 int __net_init ip_vs_estimator_net_init(struct netns_ipvs *ipvs)
 188 {
 189         INIT_LIST_HEAD(&ipvs->est_list);
 190         spin_lock_init(&ipvs->est_lock);
 191         timer_setup(&ipvs->est_timer, estimation_timer, 0);
 192         mod_timer(&ipvs->est_timer, jiffies + 2 * HZ);
 193         return 0;
 194 }
 195 
 196 void __net_exit ip_vs_estimator_net_cleanup(struct netns_ipvs *ipvs)
 197 {
 198         del_timer_sync(&ipvs->est_timer);
 199 }