gpu: nvgpu: reset HWPM system on reservation

Hardware HWPM system should be reset when first reservation is made
either for HWPM or PMA_STREAM resource. Support this with below changes

- Add hwpm_refcount counter to track HWPM and PMA_STREAM resource
  reservation count
- Increment counter on every HWPM/PMA resource reservation
- Decrement counter on every resource reservation release
- Reset HWPM system in MC and disable perf unit SLCG on first refcount
  increment
- Reset HWPM system in MC and re-enable perf unit SLCG after last
  refcount decrement
- Add nvgpu_cg_slcg_perf_load_enable() to manage perf unit SLCG

Bug 2510974
Jira NVGPU-5360

Change-Id: I20d2927947c3e4d8073cd3131b7733791e9c9346
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2399594
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Deepak Nibade
2020-08-17 11:29:51 +05:30
committed by Alex Waterman
parent dfd9feace6
commit d90b9a3d4e
4 changed files with 68 additions and 1 deletions

View File

@@ -262,6 +262,24 @@ done:
nvgpu_mutex_release(&g->cg_pg_lock); nvgpu_mutex_release(&g->cg_pg_lock);
} }
#ifdef CONFIG_NVGPU_PROFILER
void nvgpu_cg_slcg_perf_load_enable(struct gk20a *g, bool enable)
{
nvgpu_log_fn(g, " ");
nvgpu_mutex_acquire(&g->cg_pg_lock);
if (!g->slcg_enabled) {
goto done;
}
if (g->ops.cg.slcg_perf_load_gating_prod != NULL) {
g->ops.cg.slcg_perf_load_gating_prod(g, enable);
}
done:
nvgpu_mutex_release(&g->cg_pg_lock);
}
#endif
static void cg_init_gr_slcg_load_gating_prod(struct gk20a *g) static void cg_init_gr_slcg_load_gating_prod(struct gk20a *g)
{ {
if (g->ops.cg.slcg_bus_load_gating_prod != NULL) { if (g->ops.cg.slcg_bus_load_gating_prod != NULL) {

View File

@@ -23,9 +23,46 @@
#include <nvgpu/gk20a.h> #include <nvgpu/gk20a.h>
#include <nvgpu/pm_reservation.h> #include <nvgpu/pm_reservation.h>
#include <nvgpu/log.h> #include <nvgpu/log.h>
#include <nvgpu/mc.h>
#include <nvgpu/power_features/cg.h>
#include <nvgpu/kmem.h> #include <nvgpu/kmem.h>
#include <nvgpu/lock.h> #include <nvgpu/lock.h>
static void prepare_resource_reservation(struct gk20a *g,
enum nvgpu_profiler_pm_resource_type pm_resource, bool acquire)
{
if ((pm_resource != NVGPU_PROFILER_PM_RESOURCE_TYPE_HWPM_LEGACY) &&
(pm_resource != NVGPU_PROFILER_PM_RESOURCE_TYPE_PMA_STREAM)) {
return;
}
if (acquire) {
nvgpu_atomic_inc(&g->hwpm_refcount);
nvgpu_log(g, gpu_dbg_prof, "HWPM refcount acquired %u, resource %u",
nvgpu_atomic_read(&g->hwpm_refcount), pm_resource);
if (nvgpu_atomic_read(&g->hwpm_refcount) == 1) {
nvgpu_log(g, gpu_dbg_prof,
"Trigger HWPM system reset, disable perf SLCG");
g->ops.mc.reset(g, g->ops.mc.reset_mask(g,
NVGPU_UNIT_PERFMON));
nvgpu_cg_slcg_perf_load_enable(g, false);
}
} else {
nvgpu_atomic_dec(&g->hwpm_refcount);
nvgpu_log(g, gpu_dbg_prof, "HWPM refcount released %u, resource %u",
nvgpu_atomic_read(&g->hwpm_refcount), pm_resource);
if (nvgpu_atomic_read(&g->hwpm_refcount) == 0) {
nvgpu_log(g, gpu_dbg_prof,
"Trigger HWPM system reset, re-enable perf SLCG");
g->ops.mc.reset(g, g->ops.mc.reset_mask(g,
NVGPU_UNIT_PERFMON));
nvgpu_cg_slcg_perf_load_enable(g, true);
}
}
}
static bool check_pm_resource_existing_reservation_locked( static bool check_pm_resource_existing_reservation_locked(
struct nvgpu_pm_resource_reservations *reservations, struct nvgpu_pm_resource_reservations *reservations,
u32 reservation_id, u32 vmid) u32 reservation_id, u32 vmid)
@@ -130,6 +167,8 @@ int nvgpu_pm_reservation_acquire(struct gk20a *g, u32 reservation_id,
nvgpu_list_add(&reservation_entry->entry, &reservations->head); nvgpu_list_add(&reservation_entry->entry, &reservations->head);
reservations->count++; reservations->count++;
prepare_resource_reservation(g, pm_resource, true);
done: done:
nvgpu_mutex_release(&reservations->lock); nvgpu_mutex_release(&reservations->lock);
@@ -162,7 +201,9 @@ int nvgpu_pm_reservation_release(struct gk20a *g, u32 reservation_id,
} }
} }
if (!was_reserved) { if (was_reserved) {
prepare_resource_reservation(g, pm_resource, false);
} else {
err = -EINVAL; err = -EINVAL;
} }
@@ -189,6 +230,7 @@ void nvgpu_pm_reservation_release_all_per_vmid(struct gk20a *g, u32 vmid)
nvgpu_list_del(&reservation_entry->entry); nvgpu_list_del(&reservation_entry->entry);
reservations->count--; reservations->count--;
nvgpu_kfree(g, reservation_entry); nvgpu_kfree(g, reservation_entry);
prepare_resource_reservation(g, i, false);
} }
} }
nvgpu_mutex_release(&reservations->lock); nvgpu_mutex_release(&reservations->lock);
@@ -219,6 +261,8 @@ int nvgpu_pm_reservation_init(struct gk20a *g)
g->pm_reservations = reservations; g->pm_reservations = reservations;
nvgpu_atomic_set(&g->hwpm_refcount, 0);
nvgpu_log(g, gpu_dbg_prof, "initialized"); nvgpu_log(g, gpu_dbg_prof, "initialized");
return 0; return 0;

View File

@@ -858,6 +858,7 @@ struct gk20a {
#ifdef CONFIG_NVGPU_PROFILER #ifdef CONFIG_NVGPU_PROFILER
struct nvgpu_list_node profiler_objects; struct nvgpu_list_node profiler_objects;
struct nvgpu_pm_resource_reservations *pm_reservations; struct nvgpu_pm_resource_reservations *pm_reservations;
nvgpu_atomic_t hwpm_refcount;
#endif #endif
#ifdef CONFIG_NVGPU_FECS_TRACE #ifdef CONFIG_NVGPU_FECS_TRACE

View File

@@ -436,5 +436,9 @@ void nvgpu_cg_slcg_gr_perf_ltc_load_enable(struct gk20a *g);
void nvgpu_cg_slcg_gr_perf_ltc_load_disable(struct gk20a *g); void nvgpu_cg_slcg_gr_perf_ltc_load_disable(struct gk20a *g);
void nvgpu_cg_slcg_set_slcg_enabled(struct gk20a *g, bool enable); void nvgpu_cg_slcg_set_slcg_enabled(struct gk20a *g, bool enable);
#endif
#ifdef CONFIG_NVGPU_PROFILER
void nvgpu_cg_slcg_perf_load_enable(struct gk20a *g, bool enable);
#endif #endif
#endif /*NVGPU_POWER_FEATURES_CG_H*/ #endif /*NVGPU_POWER_FEATURES_CG_H*/