diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2016-03-29 05:31:25 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2016-04-19 11:07:34 -0400 |
commit | dfac8ce70464413c0e3748634c57d49950e71933 (patch) | |
tree | 35d17f9d35aadf134bbff98ee41e8d7664f442da /drivers/gpu/nvgpu/gk20a/regops_gk20a.c | |
parent | c651adbeaacf063b856ef8126b74661b54066477 (diff) |
gpu: nvgpu: support binding multiple channels to a debug session
We currently bind only one channel to a debug session
But some use cases might need multiple channels bound
to same debug session
Add this support by adding a list of channels to debug session.
List structure is implemented as struct dbg_session_channel_data
List node dbg_s_list_node is currently defined in struct
dbg_session_gk20a. But this is inefficient when we need to
add debug session to multiple channels
Hence add new reference structure dbg_session_data to
store dbg_session pointer and list entry
For each NVGPU_DBG_GPU_IOCTL_BIND_CHANNEL call, create
two reference structure dbg_session_channel_data for channel
and dbg_session_data for debug session and bind them together
Define API nvgpu_dbg_gpu_get_session_channel() which will
get first channel in the list of debug session
Use this API wherever we refer to channel bound to debug
session
Remove dbg_sessions define in struct gk20a since it is
not being used anywhere
Add new API NVGPU_DBG_GPU_IOCTL_UNBIND_CHANNEL to support
unbinding of channel from debug sesssion
Bug 200156699
Change-Id: I3bfa6f9cd5b90e7254a75c7e64ac893739776b7f
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/1120331
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/regops_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/regops_gk20a.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/regops_gk20a.c b/drivers/gpu/nvgpu/gk20a/regops_gk20a.c index fda480cf..6e21e857 100644 --- a/drivers/gpu/nvgpu/gk20a/regops_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/regops_gk20a.c | |||
@@ -390,7 +390,7 @@ int exec_regops_gk20a(struct dbg_session_gk20a *dbg_s, | |||
390 | 390 | ||
391 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); | 391 | gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, ""); |
392 | 392 | ||
393 | ch = dbg_s->ch; | 393 | ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); |
394 | 394 | ||
395 | /* For vgpu, the regops routines need to be handled in the | 395 | /* For vgpu, the regops routines need to be handled in the |
396 | * context of the server and support for that does not exist. | 396 | * context of the server and support for that does not exist. |
@@ -559,6 +559,9 @@ static bool check_whitelists(struct dbg_session_gk20a *dbg_s, | |||
559 | { | 559 | { |
560 | struct gk20a *g = dbg_s->g; | 560 | struct gk20a *g = dbg_s->g; |
561 | bool valid = false; | 561 | bool valid = false; |
562 | struct channel_gk20a *ch; | ||
563 | |||
564 | ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); | ||
562 | 565 | ||
563 | if (op->type == REGOP(TYPE_GLOBAL)) { | 566 | if (op->type == REGOP(TYPE_GLOBAL)) { |
564 | /* search global list */ | 567 | /* search global list */ |
@@ -570,7 +573,7 @@ static bool check_whitelists(struct dbg_session_gk20a *dbg_s, | |||
570 | regop_bsearch_range_cmp); | 573 | regop_bsearch_range_cmp); |
571 | 574 | ||
572 | /* if debug session and channel is bound search context list */ | 575 | /* if debug session and channel is bound search context list */ |
573 | if ((!valid) && (!dbg_s->is_profiler && dbg_s->ch)) { | 576 | if ((!valid) && (!dbg_s->is_profiler && ch)) { |
574 | /* binary search context list */ | 577 | /* binary search context list */ |
575 | valid = g->ops.regops.get_context_whitelist_ranges && | 578 | valid = g->ops.regops.get_context_whitelist_ranges && |
576 | !!bsearch(&offset, | 579 | !!bsearch(&offset, |
@@ -581,7 +584,7 @@ static bool check_whitelists(struct dbg_session_gk20a *dbg_s, | |||
581 | } | 584 | } |
582 | 585 | ||
583 | /* if debug session and channel is bound search runcontrol list */ | 586 | /* if debug session and channel is bound search runcontrol list */ |
584 | if ((!valid) && (!dbg_s->is_profiler && dbg_s->ch)) { | 587 | if ((!valid) && (!dbg_s->is_profiler && ch)) { |
585 | valid = g->ops.regops.get_runcontrol_whitelist && | 588 | valid = g->ops.regops.get_runcontrol_whitelist && |
586 | linear_search(offset, | 589 | linear_search(offset, |
587 | g->ops.regops.get_runcontrol_whitelist(), | 590 | g->ops.regops.get_runcontrol_whitelist(), |
@@ -589,7 +592,7 @@ static bool check_whitelists(struct dbg_session_gk20a *dbg_s, | |||
589 | } | 592 | } |
590 | } else if (op->type == REGOP(TYPE_GR_CTX)) { | 593 | } else if (op->type == REGOP(TYPE_GR_CTX)) { |
591 | /* it's a context-relative op */ | 594 | /* it's a context-relative op */ |
592 | if (!dbg_s->ch) { | 595 | if (!ch) { |
593 | gk20a_err(dbg_s->dev, "can't perform ctx regop unless bound"); | 596 | gk20a_err(dbg_s->dev, "can't perform ctx regop unless bound"); |
594 | op->status = REGOP(STATUS_UNSUPPORTED_OP); | 597 | op->status = REGOP(STATUS_UNSUPPORTED_OP); |
595 | return valid; | 598 | return valid; |
@@ -604,7 +607,7 @@ static bool check_whitelists(struct dbg_session_gk20a *dbg_s, | |||
604 | regop_bsearch_range_cmp); | 607 | regop_bsearch_range_cmp); |
605 | 608 | ||
606 | /* if debug session and channel is bound search runcontrol list */ | 609 | /* if debug session and channel is bound search runcontrol list */ |
607 | if ((!valid) && (!dbg_s->is_profiler && dbg_s->ch)) { | 610 | if ((!valid) && (!dbg_s->is_profiler && ch)) { |
608 | valid = g->ops.regops.get_runcontrol_whitelist && | 611 | valid = g->ops.regops.get_runcontrol_whitelist && |
609 | linear_search(offset, | 612 | linear_search(offset, |
610 | g->ops.regops.get_runcontrol_whitelist(), | 613 | g->ops.regops.get_runcontrol_whitelist(), |