From 1fb5a4f931d7cd1c05c1c21d691bbcee99ba03cc Mon Sep 17 00:00:00 2001 From: Janardhan Reddy Date: Mon, 21 Oct 2024 07:50:12 +0000 Subject: [PATCH] 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 Reviewed-by: Sumeet Gupta Tested-by: Janardhan Reddy AnnapuReddy --- drivers/misc/nvscic2c-pcie/endpoint.c | 7 ++----- drivers/misc/nvscic2c-pcie/pci-client.c | 26 ++++++++++--------------- drivers/misc/nvscic2c-pcie/pci-client.h | 7 +++++-- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/misc/nvscic2c-pcie/endpoint.c b/drivers/misc/nvscic2c-pcie/endpoint.c index 25524c48..dd6f12a0 100644 --- a/drivers/misc/nvscic2c-pcie/endpoint.c +++ b/drivers/misc/nvscic2c-pcie/endpoint.c @@ -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); diff --git a/drivers/misc/nvscic2c-pcie/pci-client.c b/drivers/misc/nvscic2c-pcie/pci-client.c index 71bdecc7..c260ba95 100644 --- a/drivers/misc/nvscic2c-pcie/pci-client.c +++ b/drivers/misc/nvscic2c-pcie/pci-client.c @@ -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); diff --git a/drivers/misc/nvscic2c-pcie/pci-client.h b/drivers/misc/nvscic2c-pcie/pci-client.h index 4486c758..ba7a9a70 100644 --- a/drivers/misc/nvscic2c-pcie/pci-client.h +++ b/drivers/misc/nvscic2c-pcie/pci-client.h @@ -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