PCI: EPF: tvnet: fixed the fence memory issue

1.Make the allocate_fence() thread-safe
2.Update the fence_do_work according to auto
  fix: https://nvbugs/4539983
3.Shouldn't creat fence in callback
4.There was typo which mixed ctrl with data.

Bug 4456727
Bug 4451567

Change-Id: If7676c8d77dc40bd5f77927efa7616e7970da183
Signed-off-by: Jason Mei <jianjunm@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3087944
Reviewed-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Jason Mei
2024-02-29 13:18:56 +08:00
committed by mobile promotions
parent d495adaddf
commit 396db89160

View File

@@ -960,14 +960,15 @@ allocate_fence(struct syncpt_t *syncpt)
int ret = 0; int ret = 0;
struct dma_fence *fence = NULL; struct dma_fence *fence = NULL;
mutex_lock(&syncpt->lock);
fence = host1x_fence_create(syncpt->sp, ++syncpt->threshold, false); fence = host1x_fence_create(syncpt->sp, ++syncpt->threshold, false);
if (IS_ERR_OR_NULL(fence)) { if (IS_ERR_OR_NULL(fence)) {
ret = PTR_ERR(fence); ret = PTR_ERR(fence);
pr_err("host1x_fence_create failed with: %d\n", ret); pr_err("host1x_fence_create failed with: %d\n", ret);
mutex_unlock(&syncpt->lock);
return ret; return ret;
} }
mutex_lock(&syncpt->lock);
ret = dma_fence_add_callback(fence, &syncpt->fence_cb, host1x_cb_func); ret = dma_fence_add_callback(fence, &syncpt->fence_cb, host1x_cb_func);
if (ret != 0) { if (ret != 0) {
/* If already expired. */ /* If already expired. */
@@ -999,8 +1000,10 @@ fence_do_work(struct syncpt_t *syncpt)
mutex_lock(&syncpt->lock); mutex_lock(&syncpt->lock);
/* If deinit triggered, no need to proceed. */ /* If deinit triggered, no need to proceed. */
if (syncpt->fence_release) if (syncpt->fence_release) {
mutex_unlock(&syncpt->lock);
return; return;
}
if (syncpt->fence) { if (syncpt->fence) {
dma_fence_put(syncpt->fence); dma_fence_put(syncpt->fence);
@@ -1010,7 +1013,6 @@ fence_do_work(struct syncpt_t *syncpt)
ret = allocate_fence(syncpt); ret = allocate_fence(syncpt);
if (ret != 0) { if (ret != 0) {
mutex_unlock(&syncpt->lock);
pr_err("allocate_fence failed with: %d\n", ret); pr_err("allocate_fence failed with: %d\n", ret);
return; return;
} }
@@ -1088,15 +1090,15 @@ static int tvnet_ep_poll(struct napi_struct *napi, int budget)
{ {
struct pci_epf_tvnet *tvnet = container_of(napi, struct pci_epf_tvnet, struct pci_epf_tvnet *tvnet = container_of(napi, struct pci_epf_tvnet,
napi); napi);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
struct irqsp_data *data_irqsp = tvnet->data_irqsp; struct irqsp_data *data_irqsp = tvnet->data_irqsp;
#endif
int work_done; int work_done;
work_done = tvnet_ep_process_h2ep_msg(tvnet); work_done = tvnet_ep_process_h2ep_msg(tvnet);
if (work_done < budget) { if (work_done < budget) {
napi_complete(napi); napi_complete(napi);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 14, 0)) #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
schedule_work(&data_irqsp->syncpt.work);
#else
schedule_work(&data_irqsp->reprime_work); schedule_work(&data_irqsp->reprime_work);
#endif #endif
} }
@@ -1246,8 +1248,8 @@ static int tvnet_ep_pci_epf_setup_irqsp(struct pci_epf_tvnet *tvnet)
#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 14, 0)) #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 14, 0))
syncpt_addr = get_syncpt_shim_offset(data_irqsp->syncpt.id); syncpt_addr = get_syncpt_shim_offset(data_irqsp->syncpt.id);
ctrl_irqsp->syncpt.phy_addr = syncpt_addr; data_irqsp->syncpt.phy_addr = syncpt_addr;
ctrl_irqsp->syncpt.size = PAGE_SIZE; data_irqsp->syncpt.size = PAGE_SIZE;
#else #else
syncpt_addr = nvhost_interrupt_syncpt_get_syncpt_addr(data_irqsp->is); syncpt_addr = nvhost_interrupt_syncpt_get_syncpt_addr(data_irqsp->is);
#endif #endif