gpu: nvgpu: minor cleanups in cyclestats snapshots

There are two minor cleanups of cyclestats snapshots code implemented:

1. In case of unacceptably small buffer passed as a cyclestats snapshot
   it causes a kernel panic during list element removal:
   NvRmGpuTest_Channel_Cyclestats_Snapshot_Gen for 1 clients,
	each has 4 KB mappings and 1 perfmons
   [  304.533073] Unable to handle kernel NULL .... address 00000008
   [  304.541825] pgd = ffffffc04fc9f000
   [  304.545277] [00000008] *pgd=0000000000000000
   [  304.549554] Internal error: Oops: 96000045 [#1] PREEMPT SMPa
   ....
   [  304.584978] PC is at css_gr_free_client_data+0x28/0xe4
   [  304.590105] LR is at gr_gk20a_css_attach+0x6e0/0x700

2. Also fix with improved allocation of perfmon IDs implemented.

Bug 1573150

Change-Id: I58b753434141bf573463563fdd699c11ea914943
Signed-off-by: Leonid Moiseichuk <lmoiseichuk@nvidia.com>
Reviewed-on: http://git-master/r/751385
(cherry picked from commit e9314c29df3fb708a20fff58cfa64c2ead857b0f)
Reviewed-on: http://git-master/r/753275
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Leonid Moiseichuk
2015-06-02 16:36:43 +03:00
committed by Terje Bergstrom
parent 837ceffcab
commit d5fd0689c2

View File

@@ -504,12 +504,17 @@ static u32 css_gr_allocate_perfmon_ids(struct gk20a_cs_snapshot *data,
if (!count || count > CSS_MAX_PERFMON_IDS - CSS_FIRST_PERFMON_ID)
return 0;
for (f = CSS_FIRST_PERFMON_ID; f < e; f++) {
u32 slots = 0;
for (f = CSS_FIRST_PERFMON_ID; f <= e; f++) {
u32 slots;
u32 cur;
u32 end = f + count;
u32 end;
if (CSS_PERFMON_GET(pids, f))
continue;
/* lookup for continuous hole [f, f+count) of unused bits */
slots = 0;
end = f + count;
for (cur = f; cur < end; cur++) {
if (CSS_PERFMON_GET(pids, cur))
break;
@@ -556,7 +561,9 @@ static int css_gr_free_client_data(struct gk20a_cs_snapshot *data,
{
int ret = 0;
list_del(&client->list);
if (client->list.next && client->list.prev)
list_del(&client->list);
if (client->perfmon_start && client->perfmon_count) {
if (client->perfmon_count != css_gr_release_perfmon_ids(data,
client->perfmon_start, client->perfmon_count))