diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/cde_gk20a.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c index cb8f1c1e..c4793335 100644 --- a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c | |||
@@ -91,7 +91,7 @@ __must_hold(&cde_app->mutex) | |||
91 | kfree(cde_ctx); | 91 | kfree(cde_ctx); |
92 | } | 92 | } |
93 | 93 | ||
94 | static void gk20a_cde_prepare_ctx_remove(struct gk20a_cde_ctx *cde_ctx) | 94 | static void gk20a_cde_cancel_deleter(struct gk20a_cde_ctx *cde_ctx) |
95 | __releases(&cde_app->mutex) | 95 | __releases(&cde_app->mutex) |
96 | __acquires(&cde_app->mutex) | 96 | __acquires(&cde_app->mutex) |
97 | { | 97 | { |
@@ -101,14 +101,12 @@ __acquires(&cde_app->mutex) | |||
101 | if (!cde_ctx->is_temporary) | 101 | if (!cde_ctx->is_temporary) |
102 | return; | 102 | return; |
103 | 103 | ||
104 | /* safe to go off the mutex since app is deinitialised. deleter works | ||
105 | * may be only at waiting for the mutex or before, going to abort */ | ||
106 | mutex_unlock(&cde_app->mutex); | 104 | mutex_unlock(&cde_app->mutex); |
107 | 105 | ||
108 | /* the deleter can rearm itself */ | 106 | /* the deleter can rearm itself */ |
109 | do { | 107 | while (delayed_work_pending(&cde_ctx->ctx_deleter_work)) { |
110 | cancel_delayed_work_sync(&cde_ctx->ctx_deleter_work); | 108 | cancel_delayed_work_sync(&cde_ctx->ctx_deleter_work); |
111 | } while (delayed_work_pending(&cde_ctx->ctx_deleter_work)); | 109 | } |
112 | 110 | ||
113 | mutex_lock(&cde_app->mutex); | 111 | mutex_lock(&cde_app->mutex); |
114 | } | 112 | } |
@@ -119,15 +117,19 @@ __must_hold(&cde_app->mutex) | |||
119 | struct gk20a_cde_app *cde_app = &g->cde_app; | 117 | struct gk20a_cde_app *cde_app = &g->cde_app; |
120 | struct gk20a_cde_ctx *cde_ctx, *cde_ctx_save; | 118 | struct gk20a_cde_ctx *cde_ctx, *cde_ctx_save; |
121 | 119 | ||
120 | /* safe to go off the mutex in cancel_deleter since app is | ||
121 | * deinitialised; no new jobs are started. deleter works may be only at | ||
122 | * waiting for the mutex or before, going to abort */ | ||
123 | |||
122 | list_for_each_entry_safe(cde_ctx, cde_ctx_save, | 124 | list_for_each_entry_safe(cde_ctx, cde_ctx_save, |
123 | &cde_app->free_contexts, list) { | 125 | &cde_app->free_contexts, list) { |
124 | gk20a_cde_prepare_ctx_remove(cde_ctx); | 126 | gk20a_cde_cancel_deleter(cde_ctx); |
125 | gk20a_cde_remove_ctx(cde_ctx); | 127 | gk20a_cde_remove_ctx(cde_ctx); |
126 | } | 128 | } |
127 | 129 | ||
128 | list_for_each_entry_safe(cde_ctx, cde_ctx_save, | 130 | list_for_each_entry_safe(cde_ctx, cde_ctx_save, |
129 | &cde_app->used_contexts, list) { | 131 | &cde_app->used_contexts, list) { |
130 | gk20a_cde_prepare_ctx_remove(cde_ctx); | 132 | gk20a_cde_cancel_deleter(cde_ctx); |
131 | gk20a_cde_remove_ctx(cde_ctx); | 133 | gk20a_cde_remove_ctx(cde_ctx); |
132 | } | 134 | } |
133 | } | 135 | } |
@@ -799,10 +801,15 @@ __must_hold(&cde_app->mutex) | |||
799 | cde_ctx, cde_app->ctx_count, | 801 | cde_ctx, cde_app->ctx_count, |
800 | cde_app->ctx_usecount, | 802 | cde_app->ctx_usecount, |
801 | cde_app->ctx_count_top); | 803 | cde_app->ctx_count_top); |
804 | |||
802 | /* deleter work may be scheduled, but in_use prevents it */ | 805 | /* deleter work may be scheduled, but in_use prevents it */ |
803 | cde_ctx->in_use = true; | 806 | cde_ctx->in_use = true; |
804 | list_move(&cde_ctx->list, &cde_app->used_contexts); | 807 | list_move(&cde_ctx->list, &cde_app->used_contexts); |
805 | cde_app->ctx_usecount++; | 808 | cde_app->ctx_usecount++; |
809 | |||
810 | /* cancel any deletions now that ctx is in use */ | ||
811 | if (delayed_work_pending(&cde_ctx->ctx_deleter_work)) | ||
812 | gk20a_cde_cancel_deleter(cde_ctx); | ||
806 | return cde_ctx; | 813 | return cde_ctx; |
807 | } | 814 | } |
808 | 815 | ||