Hoi Lucas, Am Fr., 10. Juli 2020 um 10:19 Uhr schrieb Lucas Stach <l.stach@xxxxxxxxxxxxxx>: > > Hi Christian, > > Am Freitag, den 10.07.2020, 09:41 +0200 schrieb Christian Gmeiner: > > The GPU has an idle state register where each bit represents the idle > > state of a sub-GPU component like FE or TX. Sample this register > > every 10ms and calculate a simple moving average over the sub-GPU > > component idle states with a total observation time frame of 1s. > > > > This provides us with a percentage based load of each sub-GPU > > component. > > > > Signed-off-by: Christian Gmeiner <christian.gmeiner@xxxxxxxxx> > > --- > > drivers/gpu/drm/etnaviv/etnaviv_drv.c | 14 ++++++++++++ > > drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 32 +++++++++++++++++++++++++++ > > drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 29 ++++++++++++++++++++++++ > > 3 files changed, 75 insertions(+) > > > > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c > > index f9afe11c50f0..b31920241c86 100644 > > --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c > > +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c > > @@ -46,6 +46,19 @@ static void load_gpu(struct drm_device *dev) > > } > > } > > > > +static void unload_gpu(struct drm_device *dev) > > +{ > > + struct etnaviv_drm_private *priv = dev->dev_private; > > + unsigned int i; > > + > > + for (i = 0; i < ETNA_MAX_PIPES; i++) { > > + struct etnaviv_gpu *g = priv->gpu[i]; > > + > > + if (g) > > + etnaviv_gpu_shutdown(g); > > + } > > +} > > + > > static int etnaviv_open(struct drm_device *dev, struct drm_file *file) > > { > > struct etnaviv_drm_private *priv = dev->dev_private; > > @@ -581,6 +594,7 @@ static void etnaviv_unbind(struct device *dev) > > struct drm_device *drm = dev_get_drvdata(dev); > > struct etnaviv_drm_private *priv = drm->dev_private; > > > > + unload_gpu(drm); > > drm_dev_unregister(drm); > > > > component_unbind_all(dev, drm); > > diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c > > index a31eeff2b297..1f0eb7e00657 100644 > > --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c > > +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c > > @@ -714,6 +714,28 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu) > > gpu_write(gpu, VIVS_HI_INTR_ENBL, ~0U); > > } > > > > +static void etnaviv_loadavg_function(struct timer_list *t) > > +{ > > + struct etnaviv_gpu *gpu = from_timer(gpu, t, loadavg_timer); > > + const u32 idle = gpu_read(gpu, VIVS_HI_IDLE_STATE); > > This isn't guaranteed to work on a clock/power gated GPU. Also we > surely don't want to wake a idle system every 10ms just to sample a "no > load" value, so this needs some integration with runtime PM, to disable > the sampling when the GPU is powered down and enable when powered up. > The loadavg must be able to adapt to jumps in the sampling interval > while idle. > Oh yea.. runtime PM.. I thought I was missing something. Will tackle this in the next version. > > > + int i; > > + > > + for (i = 0; i < ARRAY_SIZE(etna_idle_module_names); i++) > > + if ((idle & etna_idle_module_names[i].bit)) > > + sma_loadavg_add(&gpu->loadavg_value[i], 0); > > + else > > + sma_loadavg_add(&gpu->loadavg_value[i], 100); > > + > > + spin_lock_bh(&gpu->loadavg_spinlock); > > + > > + for (i = 0; i < ARRAY_SIZE(etna_idle_module_names); i++) > > + gpu->loadavg_percentage[i] = sma_loadavg_read(&gpu->loadavg_value[i]); > > + > > + spin_unlock_bh(&gpu->loadavg_spinlock); > > + > > + mod_timer(t, jiffies + msecs_to_jiffies(10)); > > A jiffies based timer is much too coarse for a regular 10ms sampling. > On a typical 100Hz system 10ms is a single jiffy, so your timer will > fire anywhere in the range of ~0ms...~20ms. This won't get us a usable > measurement. > Makes sense.. will switch to hrtimers. -- greets -- Christian Gmeiner, MSc https://christian-gmeiner.info/privacypolicy _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel