mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 09:12:24 +03:00
gpu: nvgpu: linux/host1x: Execute fence callback in non-atomic context
Due to changes in the host1x driver, dma_fence callbacks will be executed in interrupt context instead of workqueue context as previously. To allow for that, this patch effectively moves the workqueue step into nvgpu so that the in-nvgpu fence callback gets executed in workqueue context. Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Change-Id: I7bfa294aa3b4bea9888921b79175a8fc218d8e3f Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2785968 Reviewed-by: Jonathan Hunter <jonathanh@nvidia.com> GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
e933a47bd8
commit
5c8e511e48
@@ -124,18 +124,25 @@ bool nvgpu_nvhost_syncpt_is_expired_ext(struct nvgpu_nvhost_dev *nvhost_dev,
|
|||||||
|
|
||||||
struct nvgpu_host1x_cb {
|
struct nvgpu_host1x_cb {
|
||||||
struct dma_fence_cb cb;
|
struct dma_fence_cb cb;
|
||||||
|
struct work_struct work;
|
||||||
void (*notifier)(void *, int);
|
void (*notifier)(void *, int);
|
||||||
void *notifier_data;
|
void *notifier_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void nvgpu_host1x_work_func(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct nvgpu_host1x_cb *host1x_cb = container_of(work, struct nvgpu_host1x_cb, work);
|
||||||
|
|
||||||
|
host1x_cb->notifier(host1x_cb->notifier_data, 0);
|
||||||
|
kfree_rcu(host1x_cb);
|
||||||
|
}
|
||||||
|
|
||||||
static void nvgpu_host1x_cb_func(struct dma_fence *f, struct dma_fence_cb *cb)
|
static void nvgpu_host1x_cb_func(struct dma_fence *f, struct dma_fence_cb *cb)
|
||||||
{
|
{
|
||||||
struct nvgpu_host1x_cb *host1x_cb;
|
struct nvgpu_host1x_cb *host1x_cb = container_of(cb, struct nvgpu_host1x_cb, cb);
|
||||||
|
|
||||||
host1x_cb = container_of(cb, struct nvgpu_host1x_cb, cb);
|
schedule_work(&host1x_cb->work);
|
||||||
host1x_cb->notifier(host1x_cb->notifier_data, 0);
|
|
||||||
dma_fence_put(f);
|
dma_fence_put(f);
|
||||||
kfree(host1x_cb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int nvgpu_nvhost_intr_register_notifier(struct nvgpu_nvhost_dev *nvhost_dev,
|
int nvgpu_nvhost_intr_register_notifier(struct nvgpu_nvhost_dev *nvhost_dev,
|
||||||
@@ -157,7 +164,7 @@ int nvgpu_nvhost_intr_register_notifier(struct nvgpu_nvhost_dev *nvhost_dev,
|
|||||||
if (!sp)
|
if (!sp)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
fence = host1x_fence_create(sp, thresh);
|
fence = host1x_fence_create(sp, thresh, true);
|
||||||
if (IS_ERR(fence)) {
|
if (IS_ERR(fence)) {
|
||||||
pr_err("error %d during construction of fence!",
|
pr_err("error %d during construction of fence!",
|
||||||
(int)PTR_ERR(fence));
|
(int)PTR_ERR(fence));
|
||||||
@@ -171,6 +178,8 @@ int nvgpu_nvhost_intr_register_notifier(struct nvgpu_nvhost_dev *nvhost_dev,
|
|||||||
cb->notifier = notifier;
|
cb->notifier = notifier;
|
||||||
cb->notifier_data = notifier_data;
|
cb->notifier_data = notifier_data;
|
||||||
|
|
||||||
|
INIT_WORK(&cb->work, nvgpu_host1x_work_func);
|
||||||
|
|
||||||
err = dma_fence_add_callback(fence, &cb->cb, nvgpu_host1x_cb_func);
|
err = dma_fence_add_callback(fence, &cb->cb, nvgpu_host1x_cb_func);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dma_fence_put(fence);
|
dma_fence_put(fence);
|
||||||
@@ -378,7 +387,7 @@ struct nvhost_fence *nvgpu_nvhost_fence_create(struct platform_device *pdev,
|
|||||||
if (WARN_ON(!sp))
|
if (WARN_ON(!sp))
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
return (struct nvhost_fence *)host1x_fence_create(sp, pts->thresh);
|
return (struct nvhost_fence *)host1x_fence_create(sp, pts->thresh, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nvhost_fence *nvgpu_nvhost_fence_get(int fd)
|
struct nvhost_fence *nvgpu_nvhost_fence_get(int fd)
|
||||||
|
|||||||
Reference in New Issue
Block a user