Hi Christian, Am Dienstag, dem 21.06.2022 um 09:20 +0200 schrieb Christian Gmeiner: > This adds a SMA algorithm inspired by Exponentially weighted moving > average (EWMA) algorithm found in the kernel. > Still not sure about this one. I _feel_ that a simple moving average over a period of one second does not do a good job of reflecting the real GPU load for a bursty workload, where EWMA might be better suited. But then I also don't have a real informed opinion to offer on this. Regards, Lucas > Signed-off-by: Christian Gmeiner <christian.gmeiner@xxxxxxxxx> > --- > drivers/gpu/drm/etnaviv/etnaviv_sma.h | 53 +++++++++++++++++++++++++++ > 1 file changed, 53 insertions(+) > create mode 100644 drivers/gpu/drm/etnaviv/etnaviv_sma.h > > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sma.h b/drivers/gpu/drm/etnaviv/etnaviv_sma.h > new file mode 100644 > index 000000000000..81564d5cbdc3 > --- /dev/null > +++ b/drivers/gpu/drm/etnaviv/etnaviv_sma.h > @@ -0,0 +1,53 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2020 Etnaviv Project > + */ > + > +#ifndef __ETNAVIV_SMA_H__ > +#define __ETNAVIV_SMA_H__ > + > +#include <linux/bug.h> > +#include <linux/compiler.h> > + > +/* > + * Simple moving average (SMA) > + * > + * This implements a fixed-size SMA algorithm. > + * > + * The first argument to the macro is the name that will be used > + * for the struct and helper functions. > + * > + * The second argument, the samples, expresses how many samples are > + * used for the SMA algorithm. > + */ > + > +#define DECLARE_SMA(name, _samples) \ > + struct sma_##name { \ > + unsigned long pos; \ > + unsigned long sum; \ > + unsigned long samples[_samples]; \ > + }; \ > + static inline void sma_##name##_init(struct sma_##name *s) \ > + { \ > + BUILD_BUG_ON(!__builtin_constant_p(_samples)); \ > + memset(s, 0, sizeof(struct sma_##name)); \ > + } \ > + static inline unsigned long sma_##name##_read(struct sma_##name *s) \ > + { \ > + BUILD_BUG_ON(!__builtin_constant_p(_samples)); \ > + return s->sum / _samples; \ > + } \ > + static inline void sma_##name##_add(struct sma_##name *s, unsigned long val) \ > + { \ > + unsigned long pos = READ_ONCE(s->pos); \ > + unsigned long sum = READ_ONCE(s->sum); \ > + unsigned long sample = READ_ONCE(s->samples[pos]); \ > + \ > + BUILD_BUG_ON(!__builtin_constant_p(_samples)); \ > + \ > + WRITE_ONCE(s->sum, sum - sample + val); \ > + WRITE_ONCE(s->samples[pos], val); \ > + WRITE_ONCE(s->pos, pos + 1 == _samples ? 0 : pos + 1); \ > + } > + > +#endif /* __ETNAVIV_SMA_H__ */