mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
gpu: nvgpu: Allow channel free to be forced
Allow forced channel freeing. This is useful when the driver is being cleaned up and the gk20a_wait_until_counter_is_N() could potentially hang. Bug 1816516 Bug 1807277 Change-Id: I711f5f3f6413d0bb30b4857e785ca3b504b494ee Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: http://git-master/r/1250022 (cherry picked from commit e132d0e5ae77d758680ac708622a4883bbd69ba3) Reviewed-on: http://git-master/r/1261918 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
508ec183db
commit
c1be5105da
@@ -910,10 +910,8 @@ static void gk20a_wait_until_counter_is_N(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* call ONLY when no references to the channel exist: after the last put */
|
||||
static void gk20a_free_channel(struct channel_gk20a *ch)
|
||||
static void gk20a_free_channel(struct channel_gk20a *ch, bool force)
|
||||
{
|
||||
struct gk20a *g = ch->g;
|
||||
struct fifo_gk20a *f = &g->fifo;
|
||||
@@ -935,9 +933,10 @@ static void gk20a_free_channel(struct channel_gk20a *ch)
|
||||
gk20a_disable_channel(ch);
|
||||
|
||||
/* wait until there's only our ref to the channel */
|
||||
gk20a_wait_until_counter_is_N(
|
||||
ch, &ch->ref_count, 1, &ch->ref_count_dec_wq,
|
||||
__func__, "references");
|
||||
if (!force)
|
||||
gk20a_wait_until_counter_is_N(
|
||||
ch, &ch->ref_count, 1, &ch->ref_count_dec_wq,
|
||||
__func__, "references");
|
||||
|
||||
/* wait until all pending interrupts for recently completed
|
||||
* jobs are handled */
|
||||
@@ -959,9 +958,10 @@ static void gk20a_free_channel(struct channel_gk20a *ch)
|
||||
atomic_dec(&ch->ref_count);
|
||||
|
||||
/* wait until no more refs to the channel */
|
||||
gk20a_wait_until_counter_is_N(
|
||||
ch, &ch->ref_count, 0, &ch->ref_count_dec_wq,
|
||||
__func__, "references");
|
||||
if (!force)
|
||||
gk20a_wait_until_counter_is_N(
|
||||
ch, &ch->ref_count, 0, &ch->ref_count_dec_wq,
|
||||
__func__, "references");
|
||||
|
||||
/* if engine reset was deferred, perform it now */
|
||||
mutex_lock(&f->deferred_reset_mutex);
|
||||
@@ -1132,7 +1132,17 @@ void _gk20a_channel_put(struct channel_gk20a *ch, const char *caller)
|
||||
|
||||
void gk20a_channel_close(struct channel_gk20a *ch)
|
||||
{
|
||||
gk20a_free_channel(ch);
|
||||
gk20a_free_channel(ch, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Be careful with this - it is meant for terminating channels when we know the
|
||||
* driver is otherwise dying. Ref counts and the like are ignored by this
|
||||
* version of the cleanup.
|
||||
*/
|
||||
void __gk20a_channel_kill(struct channel_gk20a *ch)
|
||||
{
|
||||
gk20a_free_channel(ch, true);
|
||||
}
|
||||
|
||||
struct channel_gk20a *gk20a_get_channel_from_file(int fd)
|
||||
|
||||
@@ -226,6 +226,7 @@ int gk20a_init_channel_support(struct gk20a *, u32 chid);
|
||||
|
||||
/* must be inside gk20a_busy()..gk20a_idle() */
|
||||
void gk20a_channel_close(struct channel_gk20a *ch);
|
||||
void __gk20a_channel_kill(struct channel_gk20a *ch);
|
||||
|
||||
bool gk20a_channel_update_and_check_timeout(struct channel_gk20a *ch,
|
||||
u32 timeout_delta_ms, bool *progress);
|
||||
|
||||
Reference in New Issue
Block a user