From dfac8ce70464413c0e3748634c57d49950e71933 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Tue, 29 Mar 2016 15:01:25 +0530 Subject: 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 Reviewed-on: http://git-master/r/1120331 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index b7bccd07..e0beefb1 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -857,6 +857,8 @@ static void gk20a_free_channel(struct channel_gk20a *ch) struct vm_gk20a *ch_vm = ch->vm; unsigned long timeout = gk20a_get_gr_idle_timeout(g); struct dbg_session_gk20a *dbg_s; + struct dbg_session_data *session_data, *tmp_s; + struct dbg_session_channel_data *ch_data, *tmp; bool was_reset; gk20a_dbg_fn(""); @@ -992,14 +994,21 @@ unbind: WARN_ON(ch->sync); /* unlink all debug sessions */ - mutex_lock(&ch->dbg_s_lock); - - list_for_each_entry(dbg_s, &ch->dbg_s_list, dbg_s_list_node) { - dbg_s->ch = NULL; - list_del_init(&dbg_s->dbg_s_list_node); + mutex_lock(&g->dbg_sessions_lock); + + list_for_each_entry_safe(session_data, tmp_s, + &ch->dbg_s_list, dbg_s_entry) { + dbg_s = session_data->dbg_s; + mutex_lock(&dbg_s->ch_list_lock); + list_for_each_entry_safe(ch_data, tmp, + &dbg_s->ch_list, ch_entry) { + if (ch_data->chid == ch->hw_chid) + dbg_unbind_single_channel_gk20a(dbg_s, ch_data); + } + mutex_unlock(&dbg_s->ch_list_lock); } - mutex_unlock(&ch->dbg_s_lock); + mutex_unlock(&g->dbg_sessions_lock); release: /* make sure we catch accesses of unopened channels in case -- cgit v1.2.2