/*
 * ip_vs_est.c: simple rate estimator for IPVS
 *
 * Version:     $Id: ip_vs_est.c,v 1.4 2002/11/30 01:50:35 wensong Exp $
 *
 * Authors:     Wensong Zhang <wensong@linuxvirtualserver.org>
 *
 *              This program is free software; you can redistribute it and/or
 *              modify it under the terms of the GNU General Public License
 *              as published by the Free Software Foundation; either version
 *              2 of the License, or (at your option) any later version.
 *
 * Changes:
 *
 */
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/interrupt.h>

#include <net/ip_vs.h>

/*
  This code is to estimate rate in a shorter interval (such as 8
  seconds) for virtual services and real servers. For measure rate in a
  long interval, it is easy to implement a user level daemon which
  periodically reads those statistical counters and measure rate.

  Currently, the measurement is activated by slow timer handler. Hope
  this measurement will not introduce too much load.

  We measure rate during the last 8 seconds every 2 seconds:

    avgrate = avgrate*(1-W) + rate*W

    where W = 2^(-2)

  NOTES.

  * The stored value for average bps is scaled by 2^5, so that maximal
    rate is ~2.15Gbits/s, average pps and cps are scaled by 2^10.

  * A lot code is taken from net/sched/estimator.c
 */


struct ip_vs_estimator
{
	struct ip_vs_estimator	*next;
	struct ip_vs_stats	*stats;

	u32			last_conns;
	u32			last_inpkts;
	u32			last_outpkts;
	u64			last_inbytes;
	u64			last_outbytes;

	u32			cps;
	u32			inpps;
	u32			outpps;
	u32			inbps;
	u32			outbps;
};


static struct ip_vs_estimator *est_list = NULL;
static DEFINE_RWLOCK(est_lock);
static struct timer_list est_timer;

static void estimation_timer(unsigned long arg)
{
	struct ip_vs_estimator *e;
	struct ip_vs_stats *s;
	u32 n_conns;
	u32 n_inpkts, n_outpkts;
	u64 n_inbytes, n_outbytes;
	u32 rate;

	read_lock(&est_lock);
	for (e = est_list; e; e = e->next) {
		s = e->stats;

		spin_lock(&s->lock);
		n_conns = s->conns;
		n_inpkts = s->inpkts;
		n_outpkts = s->outpkts;
		n_inbytes = s->inbytes;
		n_outbytes = s->outbytes;

		/* scaled by 2^10, but divided 2 seconds */
		rate = (n_conns - e->last_conns)<<9;
		e->last_conns = n_conns;
		e->cps += ((long)rate - (long)e->cps)>>2;
		s->cps = (e->cps+0x1FF)>>10;

		rate = (n_inpkts - e->last_inpkts)<<9;
		e->last_inpkts = n_inpkts;
		e->inpps += ((long)rate - (long)e->inpps)>>2;
		s->inpps = (e->inpps+0x1FF)>>10;

		rate = (n_outpkts - e->last_outpkts)<<9;
		e->last_outpkts = n_outpkts;
		e->outpps += ((long)rate - (long)e->outpps)>>2;
		s->outpps = (e->outpps+0x1FF)>>10;

		rate = (n_inbytes - e->last_inbytes)<<4;
		e->last_inbytes = n_inbytes;
		e->inbps += ((long)rate - (long)e->inbps)>>2;
		s->inbps = (e->inbps+0xF)>>5;

		rate = (n_outbytes - e->last_outbytes)<<4;
		e->last_outbytes = n_outbytes;
		e->outbps += ((long)rate - (long)e->outbps)>>2;
		s->outbps = (e->outbps+0xF)>>5;
		spin_unlock(&s->lock);
	}
	read_unlock(&est_lock);
	mod_timer(&est_timer, jiffies + 2*HZ);
}

int ip_vs_new_estimator(struct ip_vs_stats *stats)
{
	struct ip_vs_estimator *est;

	est = kmalloc(sizeof(*est), GFP_KERNEL);
	if (est == NULL)
		return -ENOMEM;

	memset(est, 0, sizeof(*est));
	est->stats = stats;
	est->last_conns = stats->conns;
	est->cps = stats->cps<<10;

	est->last_inpkts = stats->inpkts;
	est->inpps = stats->inpps<<10;

	est->last_outpkts = stats->outpkts;
	est->outpps = stats->outpps<<10;

	est->last_inbytes = stats->inbytes;
	est->inbps = stats->inbps<<5;

	est->last_outbytes = stats->outbytes;
	est->outbps = stats->outbps<<5;

	write_lock_bh(&est_lock);
	est->next = est_list;
	if (est->next == NULL) {
		init_timer(&est_timer);
		est_timer.expires = jiffies + 2*HZ;
		est_timer.function = estimation_timer;
		add_timer(&est_timer);
	}
	est_list = est;
	write_unlock_bh(&est_lock);
	return 0;
}

void ip_vs_kill_estimator(struct ip_vs_stats *stats)
{
	struct ip_vs_estimator *est, **pest;
	int killed = 0;

	write_lock_bh(&est_lock);
	pest = &est_list;
	while ((est=*pest) != NULL) {
		if (est->stats != stats) {
			pest = &est->next;
			continue;
		}
		*pest = est->next;
		kfree(est);
		killed++;
	}
	if (killed && est_list == NULL)
		del_timer_sync(&est_timer);
	write_unlock_bh(&est_lock);
}

void ip_vs_zero_estimator(struct ip_vs_stats *stats)
{
	struct ip_vs_estimator *e;

	write_lock_bh(&est_lock);
	for (e = est_list; e; e = e->next) {
		if (e->stats != stats)
			continue;

		/* set counters zero */
		e->last_conns = 0;
		e->last_inpkts = 0;
		e->last_outpkts = 0;
		e->last_inbytes = 0;
		e->last_outbytes = 0;
		e->cps = 0;
		e->inpps = 0;
		e->outpps = 0;
		e->inbps = 0;
		e->outbps = 0;
	}
	write_unlock_bh(&est_lock);
}
