xref: /freebsd/sys/sys/tim_filter.h (revision 95ee2897)
135c7bb34SRandall Stewart #ifndef __tim_filter_h__
235c7bb34SRandall Stewart #define __tim_filter_h__
335c7bb34SRandall Stewart /*-
435c7bb34SRandall Stewart  * Copyright (c) 2016-9 Netflix, Inc.
535c7bb34SRandall Stewart  * All rights reserved.
635c7bb34SRandall Stewart  *
735c7bb34SRandall Stewart  * Redistribution and use in source and binary forms, with or without
835c7bb34SRandall Stewart  * modification, are permitted provided that the following conditions
935c7bb34SRandall Stewart  * are met:
1035c7bb34SRandall Stewart  * 1. Redistributions of source code must retain the above copyright
1135c7bb34SRandall Stewart  *    notice, this list of conditions and the following disclaimer.
1235c7bb34SRandall Stewart  * 2. Redistributions in binary form must reproduce the above copyright
1335c7bb34SRandall Stewart  *    notice, this list of conditions and the following disclaimer in the
1435c7bb34SRandall Stewart  *    documentation and/or other materials provided with the distribution.
1535c7bb34SRandall Stewart  *
1635c7bb34SRandall Stewart  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1735c7bb34SRandall Stewart  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1835c7bb34SRandall Stewart  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1935c7bb34SRandall Stewart  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2035c7bb34SRandall Stewart  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2135c7bb34SRandall Stewart  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2235c7bb34SRandall Stewart  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2335c7bb34SRandall Stewart  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2435c7bb34SRandall Stewart  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2535c7bb34SRandall Stewart  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2635c7bb34SRandall Stewart  * SUCH DAMAGE.
2735c7bb34SRandall Stewart  */
2835c7bb34SRandall Stewart /*
2935c7bb34SRandall Stewart  * Author: Randall Stewart <rrs@netflix.com>
3035c7bb34SRandall Stewart  */
3135c7bb34SRandall Stewart 
3235c7bb34SRandall Stewart #include <sys/types.h>
3335c7bb34SRandall Stewart #include <machine/param.h>
3435c7bb34SRandall Stewart /*
3535c7bb34SRandall Stewart  * Do not change the size unless you know what you are
3635c7bb34SRandall Stewart  * doing, the current size of 5 is designed around
3735c7bb34SRandall Stewart  * the cache-line size for an amd64 processor. Other processors
3835c7bb34SRandall Stewart  * may need other sizes.
3935c7bb34SRandall Stewart  */
4035c7bb34SRandall Stewart #define NUM_FILTER_ENTRIES 3
4135c7bb34SRandall Stewart 
4235c7bb34SRandall Stewart struct filter_entry {
4335c7bb34SRandall Stewart 	uint64_t value;		/* Value */
4435c7bb34SRandall Stewart 	uint32_t time_up;	/* Time updated */
4535c7bb34SRandall Stewart } __packed ;
4635c7bb34SRandall Stewart 
4735c7bb34SRandall Stewart struct filter_entry_small {
4835c7bb34SRandall Stewart 	uint32_t value;		/* Value */
4935c7bb34SRandall Stewart 	uint32_t time_up;	/* Time updated */
5035c7bb34SRandall Stewart };
5135c7bb34SRandall Stewart 
5235c7bb34SRandall Stewart struct time_filter {
5335c7bb34SRandall Stewart 	uint32_t cur_time_limit;
5435c7bb34SRandall Stewart 	struct filter_entry entries[NUM_FILTER_ENTRIES];
5535c7bb34SRandall Stewart #ifdef _KERNEL
5635c7bb34SRandall Stewart } __aligned(CACHE_LINE_SIZE);
5735c7bb34SRandall Stewart #else
5835c7bb34SRandall Stewart };
5935c7bb34SRandall Stewart #endif
6035c7bb34SRandall Stewart struct time_filter_small {
6135c7bb34SRandall Stewart 	uint32_t cur_time_limit;
6235c7bb34SRandall Stewart 	struct filter_entry_small entries[NUM_FILTER_ENTRIES];
6335c7bb34SRandall Stewart };
6435c7bb34SRandall Stewart 
6535c7bb34SRandall Stewart /*
6635c7bb34SRandall Stewart  * To conserve on space there is a code duplication here (this
6735c7bb34SRandall Stewart  * is where polymophism would be nice in the kernel). Everything
6835c7bb34SRandall Stewart  * is duplicated to have a filter with a value of uint32_t instead
6935c7bb34SRandall Stewart  * of a uint64_t. This saves 20 bytes and the structure size
7035c7bb34SRandall Stewart  * drops to 44 from 64. The bad part about this is you end
7135c7bb34SRandall Stewart  * up with two sets of functions. The xxx_small() access
7235c7bb34SRandall Stewart  * the uint32_t value's where the xxx() the uint64_t values.
7335c7bb34SRandall Stewart  * This forces the user to keep straight which type of structure
7435c7bb34SRandall Stewart  * they allocated and which call they need to make. crossing
7535c7bb34SRandall Stewart  * over calls will create either invalid memory references or
7635c7bb34SRandall Stewart  * very bad results :)
7735c7bb34SRandall Stewart  */
7835c7bb34SRandall Stewart 
7935c7bb34SRandall Stewart #define FILTER_TYPE_MIN 1
8035c7bb34SRandall Stewart #define FILTER_TYPE_MAX 2
8135c7bb34SRandall Stewart 
8235c7bb34SRandall Stewart #ifdef _KERNEL
8335c7bb34SRandall Stewart int setup_time_filter(struct time_filter *tf, int fil_type, uint32_t time_len);
8435c7bb34SRandall Stewart void reset_time(struct time_filter *tf, uint32_t time_len);
8535c7bb34SRandall Stewart void forward_filter_clock(struct time_filter *tf, uint32_t ticks_forward);
8635c7bb34SRandall Stewart void tick_filter_clock(struct time_filter *tf, uint32_t now);
8735c7bb34SRandall Stewart uint32_t apply_filter_min(struct time_filter *tf, uint64_t value, uint32_t now);
8835c7bb34SRandall Stewart uint32_t apply_filter_max(struct time_filter *tf, uint64_t value, uint32_t now);
8935c7bb34SRandall Stewart void filter_reduce_by(struct time_filter *tf, uint64_t reduce_by, uint32_t now);
9035c7bb34SRandall Stewart void filter_increase_by(struct time_filter *tf, uint64_t incr_by, uint32_t now);
9135c7bb34SRandall Stewart static uint64_t inline
get_filter_value(struct time_filter * tf)9235c7bb34SRandall Stewart get_filter_value(struct time_filter *tf)
9335c7bb34SRandall Stewart {
9435c7bb34SRandall Stewart 	return(tf->entries[0].value);
9535c7bb34SRandall Stewart }
9635c7bb34SRandall Stewart 
9735c7bb34SRandall Stewart static uint32_t inline
get_cur_timelim(struct time_filter * tf)9835c7bb34SRandall Stewart get_cur_timelim(struct time_filter *tf)
9935c7bb34SRandall Stewart {
10035c7bb34SRandall Stewart 	return(tf->cur_time_limit);
10135c7bb34SRandall Stewart }
10235c7bb34SRandall Stewart 
10335c7bb34SRandall Stewart int setup_time_filter_small(struct time_filter_small *tf,
10435c7bb34SRandall Stewart 			    int fil_type, uint32_t time_len);
10535c7bb34SRandall Stewart void reset_time_small(struct time_filter_small *tf, uint32_t time_len);
10635c7bb34SRandall Stewart void forward_filter_clock_small(struct time_filter_small *tf,
10735c7bb34SRandall Stewart 				uint32_t ticks_forward);
10835c7bb34SRandall Stewart void tick_filter_clock_small(struct time_filter_small *tf, uint32_t now);
10935c7bb34SRandall Stewart uint32_t apply_filter_min_small(struct time_filter_small *tf,
11035c7bb34SRandall Stewart 				uint32_t value, uint32_t now);
11135c7bb34SRandall Stewart uint32_t apply_filter_max_small(struct time_filter_small *tf,
11235c7bb34SRandall Stewart 				uint32_t value, uint32_t now);
11335c7bb34SRandall Stewart void filter_reduce_by_small(struct time_filter_small *tf,
11435c7bb34SRandall Stewart 			    uint32_t reduce_by, uint32_t now);
11535c7bb34SRandall Stewart void filter_increase_by_small(struct time_filter_small *tf,
11635c7bb34SRandall Stewart 			      uint32_t incr_by, uint32_t now);
11735c7bb34SRandall Stewart static uint64_t inline
get_filter_value_small(struct time_filter_small * tf)11835c7bb34SRandall Stewart get_filter_value_small(struct time_filter_small *tf)
11935c7bb34SRandall Stewart {
12035c7bb34SRandall Stewart 	return(tf->entries[0].value);
12135c7bb34SRandall Stewart }
12235c7bb34SRandall Stewart 
12335c7bb34SRandall Stewart static uint32_t inline
get_cur_timelim_small(struct time_filter_small * tf)12435c7bb34SRandall Stewart get_cur_timelim_small(struct time_filter_small *tf)
12535c7bb34SRandall Stewart {
12635c7bb34SRandall Stewart 	return(tf->cur_time_limit);
12735c7bb34SRandall Stewart }
12835c7bb34SRandall Stewart 
12935c7bb34SRandall Stewart #endif
13035c7bb34SRandall Stewart #endif
131