1 /* 2 * Floating proportions with flexible aging period 3 * 4 * Copyright (C) 2011, SUSE, Jan Kara <[email protected]> 5 */ 6 7 #ifndef _LINUX_FLEX_PROPORTIONS_H 8 #define _LINUX_FLEX_PROPORTIONS_H 9 10 #include <linux/percpu_counter.h> 11 #include <linux/spinlock.h> 12 #include <linux/seqlock.h> 13 14 /* 15 * When maximum proportion of some event type is specified, this is the 16 * precision with which we allow limitting. Note that this creates an upper 17 * bound on the number of events per period like 18 * ULLONG_MAX >> FPROP_FRAC_SHIFT. 19 */ 20 #define FPROP_FRAC_SHIFT 10 21 #define FPROP_FRAC_BASE (1UL << FPROP_FRAC_SHIFT) 22 23 /* 24 * ---- Global proportion definitions ---- 25 */ 26 struct fprop_global { 27 /* Number of events in the current period */ 28 struct percpu_counter events; 29 /* Current period */ 30 unsigned int period; 31 /* Synchronization with period transitions */ 32 seqcount_t sequence; 33 }; 34 35 int fprop_global_init(struct fprop_global *p); 36 void fprop_global_destroy(struct fprop_global *p); 37 bool fprop_new_period(struct fprop_global *p, int periods); 38 39 /* 40 * ---- SINGLE ---- 41 */ 42 struct fprop_local_single { 43 /* the local events counter */ 44 unsigned long events; 45 /* Period in which we last updated events */ 46 unsigned int period; 47 raw_spinlock_t lock; /* Protect period and numerator */ 48 }; 49 50 #define INIT_FPROP_LOCAL_SINGLE(name) \ 51 { .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \ 52 } 53 54 int fprop_local_init_single(struct fprop_local_single *pl); 55 void fprop_local_destroy_single(struct fprop_local_single *pl); 56 void __fprop_inc_single(struct fprop_global *p, struct fprop_local_single *pl); 57 void fprop_fraction_single(struct fprop_global *p, 58 struct fprop_local_single *pl, unsigned long *numerator, 59 unsigned long *denominator); 60 61 static inline 62 void fprop_inc_single(struct fprop_global *p, struct fprop_local_single *pl) 63 { 64 unsigned long flags; 65 66 local_irq_save(flags); 67 __fprop_inc_single(p, pl); 68 local_irq_restore(flags); 69 } 70 71 /* 72 * ---- PERCPU ---- 73 */ 74 struct fprop_local_percpu { 75 /* the local events counter */ 76 struct percpu_counter events; 77 /* Period in which we last updated events */ 78 unsigned int period; 79 raw_spinlock_t lock; /* Protect period and numerator */ 80 }; 81 82 int fprop_local_init_percpu(struct fprop_local_percpu *pl); 83 void fprop_local_destroy_percpu(struct fprop_local_percpu *pl); 84 void __fprop_inc_percpu(struct fprop_global *p, struct fprop_local_percpu *pl); 85 void __fprop_inc_percpu_max(struct fprop_global *p, struct fprop_local_percpu *pl, 86 int max_frac); 87 void fprop_fraction_percpu(struct fprop_global *p, 88 struct fprop_local_percpu *pl, unsigned long *numerator, 89 unsigned long *denominator); 90 91 static inline 92 void fprop_inc_percpu(struct fprop_global *p, struct fprop_local_percpu *pl) 93 { 94 unsigned long flags; 95 96 local_irq_save(flags); 97 __fprop_inc_percpu(p, pl); 98 local_irq_restore(flags); 99 } 100 101 #endif 102