diff options
| author | spkal01 <kalligeross@gmail.com> | 2021-05-17 02:37:28 +0530 |
|---|---|---|
| committer | spkal01 <kalligeross@gmail.com> | 2021-05-17 02:37:28 +0530 |
| commit | 93b265ae2eba8d93d0ffa406958547232f3114c8 (patch) | |
| tree | c2f093aa144f732b5cf7bd8a0b45bf35eda42e1c /drivers/gpu/drm/msm/msm_atomic.c | |
| parent | 0a82617b8fce8994076b518064e7d420af290ea8 (diff) | |
| parent | 016f4ba70bffb6d02725e778c3989fa542e6d12a (diff) | |
Diffstat (limited to 'drivers/gpu/drm/msm/msm_atomic.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_atomic.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index c1e6cb5b4718..c19f9e22e75d 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -33,7 +33,10 @@ struct msm_commit { uint32_t crtc_mask; uint32_t plane_mask; bool nonblock; - struct kthread_work commit_work; + union { + struct kthread_work commit_work; + struct work_struct clean_work; + }; }; static BLOCKING_NOTIFIER_HEAD(msm_drm_notifier_list); @@ -117,7 +120,6 @@ static void end_atomic(struct msm_drm_private *priv, uint32_t crtc_mask, static void commit_destroy(struct msm_commit *c) { - end_atomic(c->dev->dev_private, c->crtc_mask, c->plane_mask); if (c->nonblock) kfree(c); } @@ -528,6 +530,16 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev, SDE_ATRACE_END("msm_enable"); } +static void complete_commit_cleanup(struct work_struct *work) +{ + struct msm_commit *c = container_of(work, typeof(*c), clean_work); + struct drm_atomic_state *state = c->state; + + drm_atomic_state_put(state); + + commit_destroy(c); +} + /* The (potentially) asynchronous part of the commit. At this point * nothing can fail short of armageddon. */ @@ -567,25 +579,24 @@ static void complete_commit(struct msm_commit *c) kms->funcs->complete_commit(kms, state); - drm_atomic_state_put(state); - - commit_destroy(c); + end_atomic(priv, c->crtc_mask, c->plane_mask); } static void _msm_drm_commit_work_cb(struct kthread_work *work) { - struct msm_commit *commit = NULL; - - if (!work) { - DRM_ERROR("%s: Invalid commit work data!\n", __func__); - return; - } - - commit = container_of(work, struct msm_commit, commit_work); + struct msm_commit *c = container_of(work, typeof(*c), commit_work); SDE_ATRACE_BEGIN("complete_commit"); - complete_commit(commit); + complete_commit(c); SDE_ATRACE_END("complete_commit"); + + if (c->nonblock) { + /* Offload the cleanup onto little CPUs (an unbound wq) */ + INIT_WORK(&c->clean_work, complete_commit_cleanup); + queue_work(system_unbound_wq, &c->clean_work); + } else { + complete_commit_cleanup(&c->clean_work); + } } static struct msm_commit *commit_init(struct drm_atomic_state *state, @@ -656,6 +667,7 @@ static void msm_atomic_commit_dispatch(struct drm_device *dev, */ DRM_ERROR("failed to dispatch commit to any CRTC\n"); complete_commit(commit); + complete_commit_cleanup(&commit->clean_work); } else if (!nonblock) { kthread_flush_work(&commit->commit_work); } |
