blob: 3a48fc2dcc850a692613d3b23db279d8548fd7da [file] [log] [blame]
/**
* Classfication and realization of KAIR concept using ECAVE - Elastic Capability
* Vessel - dynamic resource control abstraction theory
**/
#include <linux/sched.h>
#include <linux/bug.h>
#include <linux/list.h>
#include <linux/tfifo.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
/**
*
**/
#define KAIR_QUANT_STEP (17)
#define KAIR_QUANT_SHIFT (4)
#define KAIR_VARIANCE_SPAN (64)
#define KAIR_VARIANCE_SPAN_SHIFT (6)
#define KAIR_UNDETERMINED (0xFFFFFFFF)
#define KAIR_DIVERGING (-1)
#define KAIR_CONVERGING (0)
#define KAIR_TPDF_CUMSUM (512)
#define KAIR_TPDF_MINVAL (1)
#define KAIR_TPDF_CASCADE_LEVEL (1)
#define KAIR_ALIAS_LEN (8)
#define KAIR_INF_TPDF_WEIGHT (1)
#define KAIR_FIN_TPDF_WEIGHT (2)
#if KAIR_TPDF_CASCADE_LEVEL > 1
#define KAIR_INST_TPDF_WEIGHT (4)
#else
#define KAIR_INST_TPDF_WEIGHT (8)
#endif
/**
* Calculating Energy-Performance(EP) weight ratio, which is described
* in theory as beta / alpha * upscaler.
* where, beta is energy consuming panelty weight, alpha is bottleneck
* panelty weight, and upscaler is 1024.
**/
#define KAIR_BALANCED_EP_RATIO (1024)
/**
*
**/
#define KAIR_WINDOW_INF (0x8000000000000000UL)
#define KAIR_WINDOW_INF_MASK (0x8000000000000000UL)
#define KAIR_WINDOW_NEED_RESCALE (0x4000000000000000UL)
#define KAIR_WINDOW_SIZE_MASK (0x0FFFFFFF00000000UL)
#define KAIR_WINDOW_SIZE_SHIFT (32)
#define KAIR_WINDOW_CNT_MASK (0x000000000FFFFFFFUL)
/**
*
**/
#define KAIR_DEF_RAND_NEUTRAL (2)
#define KAIR_TRIGGER_THROTTLE (3)
#define KAIR_FASTEN_THROTTLE (-100)
/**
* 1-dimensional discrete indexing degree of randomness which correspondingly
* spans upto 64 skewness * 64 flatness long.
* randomness bitfield : | <-- skewness --> | <-- flatness(variance) --> |
**/
#define RAND_SKEW_SHIFT (8)
typedef int randomness;
/**
* Random integer variable for stochastic process
**/
struct rand_var {
int nval;
unsigned int ubound;
unsigned int lbound;
};
/**
* Random integer variable coordinators
**/
#define __RV_INITIALIZER() \
{ \
.nval = 0, \
.ubound = 0, \
.lbound = 0 \
}
#define RV_DECLARE(name) struct rand_var name = __RV_INITIALIZER()
/**
* @rv : random variable structure
* @num : signed number
* @ulimit : positive upper bound
* @llimit : positive lower bound
**/
#define RV_SET(rv, num, ulimit, llimit) \
({ \
rv.nval = (int)(num); \
rv.ubound = (unsigned int)(ulimit); \
rv.lbound = (unsigned int)(llimit); \
})
/* Stretching nval to fit given tpdf->qlvl and returning the proper index
* within >= 0 and < tpdf->qlvl.
*/
#define RV_TAILORED(pdf, rv) \
({ \
typeof((pdf) + 1) __pdf = (pdf); \
typeof((rv) + 1) __rv = (rv); \
int __nval; \
int __hscale = (int)__pdf->qlvl >> 1; \
int __ubound = (int)__rv->ubound; \
int __lbound = (int)__rv->lbound; \
__nval = (__rv->nval >= 0) ? \
(__ubound ? \
((__rv->nval * __hscale / __ubound) + __hscale) : \
__hscale) : \
(__lbound ? \
((__rv->nval * __hscale / __lbound) + __hscale) : \
__hscale); \
__nval; \
})
#define RV_SPAN(rv) \
({ \
typeof((rv) + 1) __rv = (rv); \
unsigned int __span = __rv->ubound + __rv->lbound; \
__span; \
})
/**
* TPDF(Temporal Probability Density Function) container class
**/
struct tpdf {
struct list_head pos;
unsigned int qlvl;
u64 win_size;
struct __tfifo cache;
unsigned int *qtbl;
unsigned int pc_cnt;
/**
* """ TPDF container methods list """
* @tabling : preparing qtbl
* @untabling : removing qtbl
* @rv_register : registration of corresponding rv
* @rv_unregister : moving rv
* @interpolator : calculating moderate value
* @equilibrator : rebalancing qtbl to maintain total PDF integral
* @rescaler : rescaling the whole PDF to have
**/
int (*tabling)(struct tpdf *self);
void (*untabling)(struct tpdf *self);
void (*rv_register)(struct tpdf *self, struct rand_var *rv);
void (*rv_unregister)(struct tpdf *self);
unsigned int (*interpolator)(struct tpdf *self, unsigned int tpos,
unsigned int rpos);
void (*equilibrator)(struct tpdf *self);
void (*rescaler)(struct tpdf *self);
randomness irand;
char alias[KAIR_ALIAS_LEN];
struct rand_var *rv;
unsigned int weight;
};
/**
* """ KAIR statistics """
* @choke_cnt : counting how much the event so-called bottleneck or
* momentary sluggish in ECAVE theory happened.
* @save_total : accumulating amount how much redundant capacity is saved.
* @rand_neutral : an argument used for running betting algorithm.
* @throttling : +- accumulation of continuous choke/relief events.
* 0 is neutral.
**/
struct kair_stats {
unsigned int choke_cnt;
long long save_total;
unsigned int rand_neutral;
int throttling;
};
/**
* KAIR instance kobject created per each kair_obj_creator() call by
* any client and will be used to register to sysfs.
**/
struct krinst_obj {
struct kobject obj;
struct kair_class *inst;
};
#define to_krinst_obj(x) container_of(x, struct krinst_obj, obj)
/**
* KAIR attribute customized for krinst_obj.
**/
struct krinst_attribute {
struct attribute attr;
ssize_t (*show)(struct krinst_obj *inst, struct krinst_attribute *attr, char *buf);
ssize_t (*store)(struct krinst_obj *inst, struct krinst_attribute *attr, const char *buf, size_t count);
};
#define to_krinst_attr(x) container_of(x, struct krinst_attribute, attr)
#define KRINST_ATTR_RO(__name) \
static struct krinst_attribute __name##_attr = __ATTR_RO(__name)
#define KRINST_ATTR_RW(__name) \
static struct krinst_attribute __name##_attr = __ATTR_RW(__name)
/**
* TODO: more studies may be required to apply an external training.
* Kairistics is experimentally determined, which describes the pair of integer
* ratios in consideration of the fixed scaling factor heuristically used in each
* client's legacy mechanism.
**/
struct kairistics {
unsigned int gamma_numer:8;
unsigned int gamma_denom:8;
unsigned int theta_numer:8;
unsigned int theta_denom:8;
};
#define DECLARE_KAIRISTICS(alias, gnumer, gdenum, tnumer, tdenum) \
static struct kairistics kairistic_##alias = { \
.gamma_numer = gnumer, \
.gamma_denom = gdenum, \
.theta_numer = tnumer, \
.theta_denom = tdenum, \
}
/**
* "" KAIR class description """
* Which is virtually integrating Elastic Capacity Vessel abstraction model
* applicable on arbitrary dynamic self resource control systems.
* All real numbered properties must be handled with integers through adequate
* conversion and quantization processes.
**/
struct kair_class {
struct list_head tpdf_cascade;
/**
* bit-shift representation of KAIR capacity denominator
* which is considered as the summation of each level's TPDF weight
* multiplied by maximum randomness.
**/
unsigned int capa_denom;
/**
* """ KAIR methods list """:
* @initializer : self-initializer
* @stopper : stopping to learn tpdf, cleaning up.
* @finalizer : returning all resources.
* @job_learner : learner of capacity-probability-density which is
* actually conducting exclusive on-device learning
* algorithm on the given capacity-random variable.
* @job_inferer : returns randomness index of the TPDF which is most
* resembling given TPDF.
* @cap_bettor : returns betting capacity estimated.
**/
int (*initializer)(struct kair_class *self);
void (*stopper)(struct kair_class *self);
void (*finalizer)(struct kair_class *self);
void (*job_learner)(struct kair_class *self, struct rand_var *v);
int (*job_inferer)(struct kair_class *self);
unsigned int (*cap_bettor)(struct kair_class *self, struct rand_var *v,
unsigned int cap_legecy);
struct kair_stats stats;
unsigned int df_velocity;
unsigned int resilience;
unsigned int ep_ratio;
unsigned int max_capa;
unsigned int min_capa;
unsigned int epsilon;
struct kairistics kairistic;
char alias[KAIR_ALIAS_LEN];
struct krinst_obj *extif;
};
/**
*
*
**/
extern int kair_tpdf_tabling(struct tpdf *self);
extern void kair_tpdf_untabling(struct tpdf *self);
extern void kair_tpdf_rv_register(struct tpdf *self, struct rand_var *rv);
extern void kair_tpdf_rv_unregister(struct tpdf *self);
extern unsigned int linear_interpolator(struct tpdf *self, unsigned int top_pos,
unsigned int raw_pos);
extern void kair_tpdf_equilibrator(struct tpdf *self);
extern void kair_tpdf_rescaler(struct tpdf *self);
#define tpdf_infinite_init(pdf, __tlevel) \
({ \
int __err = 0; \
typeof((pdf) + 1) __pdf = (pdf); \
sprintf(__pdf->alias, "%s_tpdf", #__tlevel); \
*__pdf = (struct tpdf) { \
.pos = LIST_HEAD_INIT(__pdf->pos), \
.qlvl = KAIR_QUANT_STEP, \
.win_size = KAIR_WINDOW_INF, \
.pc_cnt = 0, \
.irand = KAIR_DIVERGING, \
.weight = KAIR_INF_TPDF_WEIGHT, \
.cache = tfifo_init(&__pdf->cache), \
.tabling = kair_tpdf_tabling, \
.untabling = kair_tpdf_untabling, \
.rv_register = kair_tpdf_rv_register, \
.rv_unregister = kair_tpdf_rv_unregister, \
.interpolator = linear_interpolator, \
.equilibrator = kair_tpdf_equilibrator, \
.rescaler = kair_tpdf_rescaler, \
}; \
__err = __pdf->tabling(__pdf); \
__err; \
})
#define tpdf_finite_init(pdf, __tlevel, period) \
({ \
int __err = 0; \
typeof((pdf) + 1) __pdf = (pdf); \
sprintf(__pdf->alias, "%s_tpdf", #__tlevel); \
*__pdf = (struct tpdf) { \
.pos = LIST_HEAD_INIT(__pdf->pos), \
.qlvl = KAIR_QUANT_STEP, \
.win_size = ((u64)period << KAIR_WINDOW_SIZE_SHIFT) | \
KAIR_WINDOW_NEED_RESCALE, \
.pc_cnt = 0, \
.irand = KAIR_DIVERGING, \
.weight = KAIR_FIN_TPDF_WEIGHT, \
.cache = tfifo_init(&__pdf->cache), \
.tabling = kair_tpdf_tabling, \
.untabling = kair_tpdf_untabling, \
.rv_register = kair_tpdf_rv_register, \
.rv_unregister = kair_tpdf_rv_unregister, \
.interpolator = linear_interpolator, \
.equilibrator = kair_tpdf_equilibrator, \
.rescaler = kair_tpdf_rescaler, \
}; \
__err = __pdf->tabling(__pdf); \
__err; \
})
#define tpdf_instant_init(pdf, __tlevel, period) \
({ \
int __err = 0; \
typeof((pdf) + 1) __pdf = (pdf); \
sprintf(__pdf->alias, "%s_tpdf", #__tlevel); \
*__pdf = (struct tpdf) { \
.pos = LIST_HEAD_INIT(__pdf->pos), \
.qlvl = KAIR_QUANT_STEP, \
.win_size = ((u64)period << KAIR_WINDOW_SIZE_SHIFT), \
.pc_cnt = 0, \
.irand = KAIR_DIVERGING, \
.weight = KAIR_INST_TPDF_WEIGHT, \
.cache = tfifo_init(&__pdf->cache), \
.tabling = kair_tpdf_tabling, \
.untabling = kair_tpdf_untabling, \
.rv_register = kair_tpdf_rv_register, \
.rv_unregister = kair_tpdf_rv_unregister, \
.interpolator = linear_interpolator, \
.equilibrator = kair_tpdf_equilibrator, \
.rescaler = kair_tpdf_rescaler, \
}; \
__err = __pdf->tabling(__pdf); \
__err; \
})
/**
* @kair_l1_pdf_init() : instant generative TPDF covering only about past 1 second.
* @kair_l2_pdf_init() : generative TPDF convering only about past 1 minute.
* @kair_l3_pdf_init() : ever lasting generative TPDF
**/
#define kair_l1_pdf_init(pdf) tpdf_instant_init((pdf), l1, KAIR_TPDF_CUMSUM)
#define kair_l2_pdf_init(pdf) tpdf_finite_init((pdf), l2, KAIR_TPDF_CUMSUM << 1)
#define kair_l3_pdf_init(pdf) tpdf_infinite_init((pdf), l3)
/**
* KAIR window information extractors
**/
#define is_kair_window_infty(pdf) \
({ \
typeof((pdf) + 1) __pdf = (pdf); \
(__pdf->win_size & KAIR_WINDOW_INF_MASK); \
})
#define kair_window_size(pdf) \
({ \
typeof((pdf) + 1) __pdf = (pdf); \
((__pdf->win_size & KAIR_WINDOW_SIZE_MASK) >> KAIR_WINDOW_SIZE_SHIFT); \
})
#define kair_windowing_cnt(pdf) \
({ \
typeof((pdf) + 1) __pdf = (pdf); \
(__pdf->win_size & KAIR_WINDOW_CNT_MASK); \
})
#define kair_window_need_rescale(pdf) \
({ \
typeof((pdf) + 1) __pdf = (pdf); \
(__pdf->win_size & KAIR_WINDOW_NEED_RESCALE); \
})
#define kair_window_rescale_done(pdf) \
({ \
typeof((pdf) + 1) __pdf = (pdf); \
__pdf->win_size &= ~KAIR_WINDOW_NEED_RESCALE; \
})
/*.............................................................................
*.............................................................................
*................ """ KAIR Major External interfaces """ ....................
*.............................................................................
*...........................................................................*/
struct kair_class *kair_obj_creator(const char *alias,
unsigned int resilience,
unsigned int max_capa,
unsigned int min_capa,
struct kairistics *kairistic);
void kair_obj_destructor(struct kair_class *self);