gpu: nvgpu: sync free of rpc_payload

- During driver unload, shutdown or RG path as part of
  pmu destroy, pmu sequences have to be cleaned up to
  free payload memory and allocation info which is stored
  as part of pmu_sequence.
- While doing so there can be race condition with pmu_isr
  or nvgpu_pmu_rpc_execute path where it waits for fw ack.
- This race condition can lead to freeing of payload memory
  before nvgpu_pmu_sequences_cleanup() does.
- This can lead to memory corruption or double free issue
  when the cleanup code again tries to free the payload mem.
- To resolve this add a new function nvgpu_pmu_seq_free_release()
  which will check for seq->id in pmu seq tbl before freeing the
  memory and other info from pmu_sequence.
- Use this nvgpu_pmu_seq_free_release() in non-blocking RPC calls
  and also when fw ack fails or driver is dying scenario.
- For blocking call, synchronise freeing of rpc payload memory by
  using a new boolean seq_free_status.

Bug 4019694
Bug 4059157

Change-Id: Id45a6914a2d383a654539a87861c471a77fb6850
Signed-off-by: Divya <dsinghatwari@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2882210
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com>
Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Divya
2023-03-15 04:01:45 +00:00
committed by mobile promotions
parent b2c4cdb25b
commit db9a411a06
5 changed files with 86 additions and 21 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2017-2023, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -238,7 +238,13 @@ u32 nvgpu_pmu_queue_get_size(struct pmu_queues *queues, u32 queue_id)
if (queues->queue_type == QUEUE_TYPE_FB) {
fb_queue = queues->fb_queue[queue_id];
queue_size = nvgpu_engine_fb_queue_get_element_size(fb_queue);
if (fb_queue != NULL) {
queue_size =
nvgpu_engine_fb_queue_get_element_size(fb_queue);
} else {
/* when fb is NULL return size as 0 */
return 0;
}
} else {
queue = queues->queue[queue_id];
queue_size = nvgpu_engine_mem_queue_get_size(queue);