From 3c2656c8c6ebf7cef7376d3a28451249643121c4 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Mon, 17 Oct 2016 21:26:37 +0530 Subject: gpu: nvgpu: clear events from channel/TSG while closing If User does not close the event fd created on channel/TSG, it is possible that the event stays on channel/TSG structure and reappears when channel/TSG is re-opened This causes false failure when we try to enable some event of channel/TSG since we do not allow enabling same event twice on same channel/TSG Fix this by removing all enabled events from channel/TSG while closing it Bug 200243092 Bug 1818654 Change-Id: I9d5ffc89f87cf4c44124f8015c2c2f0587ad2ef4 Signed-off-by: Deepak Nibade Reviewed-on: http://git-master/r/1237723 (cherry picked from commit 2737a5c86cf5fbfe8a04f6a87764e8ecb9b30555) Reviewed-on: http://git-master/r/1238266 GVS: Gerrit_Virtual_Submit Reviewed-by: Bharat Nihalani --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 10 ++++++++++ drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 4458430b..f60a92b4 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -1142,6 +1142,7 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g, { struct fifo_gk20a *f = &g->fifo; struct channel_gk20a *ch; + struct gk20a_event_id_data *event_id_data, *event_id_data_temp; /* compatibility with existing code */ if (!gk20a_fifo_is_valid_runlist_id(g, runlist_id)) { @@ -1182,6 +1183,15 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g, ch->pid = current->pid; ch->tgid = current->tgid; /* process granularity for FECS traces */ + /* unhook all events created on this channel */ + mutex_lock(&ch->event_id_list_lock); + list_for_each_entry_safe(event_id_data, event_id_data_temp, + &ch->event_id_list, + event_id_node) { + list_del_init(&event_id_data->event_id_node); + } + mutex_unlock(&ch->event_id_list_lock); + /* By default, channel is regular (non-TSG) channel */ ch->tsgid = NVGPU_INVALID_TSG_ID; diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c index 3e83cd06..716388ec 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c @@ -451,6 +451,7 @@ void gk20a_tsg_release(struct kref *ref) { struct tsg_gk20a *tsg = container_of(ref, struct tsg_gk20a, refcount); struct gk20a *g = tsg->g; + struct gk20a_event_id_data *event_id_data, *event_id_data_temp; if (tsg->tsg_gr_ctx) { gr_gk20a_free_tsg_gr_ctx(tsg); @@ -462,6 +463,16 @@ void gk20a_tsg_release(struct kref *ref) } gk20a_sched_ctrl_tsg_removed(g, tsg); + + /* unhook all events created on this TSG */ + mutex_lock(&tsg->event_id_list_lock); + list_for_each_entry_safe(event_id_data, event_id_data_temp, + &tsg->event_id_list, + event_id_node) { + list_del_init(&event_id_data->event_id_node); + } + mutex_unlock(&tsg->event_id_list_lock); + release_used_tsg(&g->fifo, tsg); tsg->runlist_id = ~0; -- cgit v1.2.2