nvscic2c-pcie: Fix edma error reporting issue

pci_client abstraction supports notification to application.
Each endpoint has to register with pci_client for notification which
return link_event_id after registration.
link_event_id is index in lookup table with total size as MAX_ENDPOINT.
This link_event_id is allocated sequential and does not match with ep_id
which is endpoint index with max as MAX_ENDPOINT.

stream-extension is not aware about link_event_id and uses ep_id for
notification which leads to mismatch in look up table finally dropping
notification.

Registering for link event in sequential manner does not help much as
registration against ep_id will make lookup table and endpoint database
one-to-one mapping.

Update endpoint registration for link event based on ep_id and use ep_id
in lookup table for notification purpose.

Bug 4913236

Change-Id: I75bfdbf0e8e5b7b11b0cca7dc266f01f492362f6
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3233789
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com>
Tested-by: Janardhan Reddy AnnapuReddy <jreddya@nvidia.com>
This commit is contained in:
Janardhan Reddy
2024-10-21 07:50:12 +00:00
committed by Jon Hunter
parent 9c40df022c
commit 1fb5a4f931
3 changed files with 17 additions and 23 deletions

View File

@@ -125,8 +125,6 @@ struct endpoint_t {
*/
atomic_t event_count;
u32 linkevent_id;
/* propagate events when endpoint was initialized.*/
atomic_t event_handling;
@@ -939,7 +937,7 @@ remove_endpoint_device(struct endpoint_drv_ctx_t *eps_ctx,
return ret;
pci_client_unregister_for_link_event(endpoint->pci_client_h,
endpoint->linkevent_id);
endpoint->minor);
free_syncpoint(eps_ctx, endpoint);
free_memory(eps_ctx, endpoint);
if (endpoint->device) {
@@ -1010,8 +1008,7 @@ create_endpoint_device(struct endpoint_drv_ctx_t *eps_ctx,
/* Register for link events.*/
ops.callback = &(event_callback);
ops.ctx = (void *)(endpoint);
ret = pci_client_register_for_link_event(endpoint->pci_client_h, &ops,
&endpoint->linkevent_id);
ret = pci_client_register_for_link_event(endpoint->pci_client_h, &ops, endpoint->minor);
if (ret) {
pr_err("(%s): Failed to register for PCIe link events\n",
endpoint->name);

View File

@@ -550,7 +550,7 @@ pci_client_set_edma_error(void *pci_client_h, u32 ep_id, u32 err)
if (WARN_ON(!ctx))
return -EINVAL;
if (WARN_ON(ep_id > MAX_LINK_EVENT_USERS ||
if (WARN_ON(ep_id >= MAX_LINK_EVENT_USERS ||
err != NVSCIC2C_PCIE_EDMA_XFER_ERROR))
return -EINVAL;
@@ -588,9 +588,8 @@ pci_client_query_link_status(void *pci_client_h)
*/
int
pci_client_register_for_link_event(void *pci_client_h,
struct callback_ops *ops, u32 *id)
struct callback_ops *ops, u32 id)
{
u32 i = 0;
int ret = 0;
struct event_t *event = NULL;
struct pci_client_t *ctx = (struct pci_client_t *)pci_client_h;
@@ -598,23 +597,18 @@ pci_client_register_for_link_event(void *pci_client_h,
if (WARN_ON(!ctx))
return -EINVAL;
if (WARN_ON(!id || !ops || !ops->callback))
if (WARN_ON((id >= MAX_LINK_EVENT_USERS) || !ops || !ops->callback))
return -EINVAL;
mutex_lock(&ctx->event_tbl_lock);
for (i = 0; i < MAX_LINK_EVENT_USERS; i++) {
event = &ctx->event_tbl[i];
if (!atomic_read(&event->in_use)) {
event->cb_ops.callback = ops->callback;
event->cb_ops.ctx = ops->ctx;
atomic_set(&event->in_use, 1);
*id = i;
break;
}
}
if (i == MAX_LINK_EVENT_USERS) {
event = &ctx->event_tbl[id];
if (atomic_read(&event->in_use)) {
ret = -ENOMEM;
pr_err("PCI link event registration full\n");
pr_err("PCIe link event already registered for endpoint: %d\n", id);
} else {
event->cb_ops.callback = ops->callback;
event->cb_ops.ctx = ops->ctx;
atomic_set(&event->in_use, 1);
}
mutex_unlock(&ctx->event_tbl_lock);

View File

@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
/*
* SPDX-FileCopyrightText: Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES.
* All rights reserved.
*/
#ifndef __PCI_CLIENT_H__
#define __PCI_CLIENT_H__
@@ -73,7 +76,7 @@ pci_client_dmabuf_detach(void *pci_client_h, struct dma_buf *dmabuff,
*/
int
pci_client_register_for_link_event(void *pci_client_h,
struct callback_ops *ops, u32 *id);
struct callback_ops *ops, u32 id);
/* Unregister for PCI link events. - teardown only. */
int