From 7fa23c15029fc694ab94c5ac005e0657db990678 Mon Sep 17 00:00:00 2001 From: Venkata Sharath Chandra Manchala Date: Thu, 17 Oct 2019 16:51:23 -0700 Subject: [PATCH] qcacmn: Add support to record iova address Add support to record iova and pa address for every buffer posted to CE SRC ring. This is to identify issues in memory corruption. Change-Id: I774b705f9edc89490d1f8dfdd01e8e0d9e9165c0 CRs-Fixed: 2546824 --- hif/src/ce/ce_internal.h | 81 +++++++++++++++++++++--------------- hif/src/ce/ce_service.c | 42 +++++++------------ hif/src/ce/ce_service_srng.c | 5 ++- 3 files changed, 68 insertions(+), 60 deletions(-) diff --git a/hif/src/ce/ce_internal.h b/hif/src/ce/ce_internal.h index de085354eeb0..a5edd14934db 100644 --- a/hif/src/ce/ce_internal.h +++ b/hif/src/ce/ce_internal.h @@ -554,13 +554,16 @@ int hif_get_wake_ce_id(struct hif_softc *scn, uint8_t *ce_id); /** * struct hif_ce_desc_event - structure for detailing a ce event + * @index: location of the descriptor in the ce ring; * @type: what the event was * @time: when it happened * @current_hp: holds the current ring hp value * @current_tp: holds the current ring tp value * @descriptor: descriptor enqueued or dequeued * @memory: virtual address that was used - * @index: location of the descriptor in the ce ring; + * @dma_addr: physical/iova address based on smmu status + * @dma_to_phy: physical address from iova address + * @virt_to_phy: physical address from virtual address * @actual_data_len: length of the data * @data: data pointed by descriptor */ @@ -576,19 +579,25 @@ struct hif_ce_desc_event { union ce_srng_desc descriptor; #endif void *memory; + +#ifdef HIF_RECORD_PADDR + /* iova/pa based on smmu status */ + qdf_dma_addr_t dma_addr; + /* store pa from iova address */ + qdf_dma_addr_t dma_to_phy; + /* store pa */ + qdf_dma_addr_t virt_to_phy; +#endif /* HIF_RECORD_ADDR */ + #ifdef HIF_CE_DEBUG_DATA_BUF size_t actual_data_len; uint8_t *data; #endif /* HIF_CE_DEBUG_DATA_BUF */ - -#ifdef HIF_CONFIG_SLUB_DEBUG_ON - qdf_dma_addr_t dma_to_phy; - qdf_dma_addr_t virt_to_phy; -#endif }; #else struct hif_ce_desc_event; #endif /*#if defined(HIF_CONFIG_SLUB_DEBUG_ON)||defined(HIF_CE_DEBUG_DATA_BUF)*/ + /** * get_next_record_index() - get the next record index * @table_index: atomic index variable to increment @@ -622,25 +631,6 @@ void hif_record_ce_srng_desc_event(struct hif_softc *scn, int ce_id, union ce_srng_desc *descriptor, void *memory, int index, int len, void *hal_ring); -#else -static inline -void hif_record_ce_srng_desc_event(struct hif_softc *scn, int ce_id, - enum hif_ce_event_type type, - union ce_srng_desc *descriptor, - void *memory, int index, - int len, void *hal_ring) -{ -} -#endif - -#ifdef HIF_CE_DEBUG_DATA_BUF -/** - * hif_ce_desc_data_record() - Record data pointed by the CE descriptor - * @event: structure detailing a ce event - * @len: length of the data - * Return: - */ -void hif_ce_desc_data_record(struct hif_ce_desc_event *event, int len); /** * hif_clear_ce_desc_debug_data() - Clear the contents of hif_ce_desc_event @@ -651,6 +641,31 @@ void hif_ce_desc_data_record(struct hif_ce_desc_event *event, int len); * Return: None */ void hif_clear_ce_desc_debug_data(struct hif_ce_desc_event *event); +#else +static inline +void hif_record_ce_srng_desc_event(struct hif_softc *scn, int ce_id, + enum hif_ce_event_type type, + union ce_srng_desc *descriptor, + void *memory, int index, + int len, void *hal_ring) +{ +} + +static inline +void hif_clear_ce_desc_debug_data(struct hif_ce_desc_event *event) +{ +} +#endif /* HIF_CONFIG_SLUB_DEBUG_ON || HIF_CE_DEBUG_DATA_BUF */ + +#ifdef HIF_CE_DEBUG_DATA_BUF +/** + * hif_ce_desc_data_record() - Record data pointed by the CE descriptor + * @event: structure detailing a ce event + * @len: length of the data + * Return: + */ +void hif_ce_desc_data_record(struct hif_ce_desc_event *event, int len); + QDF_STATUS alloc_mem_ce_debug_hist_data(struct hif_softc *scn, uint32_t ce_id); void free_mem_ce_debug_hist_data(struct hif_softc *scn, uint32_t ce_id); #else @@ -667,8 +682,6 @@ static inline void hif_ce_desc_data_record(struct hif_ce_desc_event *event, int len) { } - -void hif_clear_ce_desc_debug_data(struct hif_ce_desc_event *event); #endif /*HIF_CE_DEBUG_DATA_BUF*/ #ifdef HIF_CONFIG_SLUB_DEBUG_ON @@ -692,14 +705,14 @@ static inline void ce_validate_nbytes(uint32_t nbytes, struct CE_state *ce_state) { } -#endif +#endif /* HIF_CONFIG_SLUB_DEBUG_ON */ -#if defined(HIF_CONFIG_SLUB_DEBUG_ON) && defined(HIF_RECORD_RX_PADDR) +#if defined(HIF_RECORD_PADDR) /** * hif_ce_desc_record_rx_paddr() - record physical address for IOMMU * IOVA addr and MMU virtual addr for Rx * @scn: hif_softc - * @event: structure detailing a ce event + * @nbuf: buffer posted to fw * * record physical address for ce_event_type HIF_RX_DESC_POST and * HIF_RX_DESC_COMPLETION @@ -707,12 +720,14 @@ static inline void ce_validate_nbytes(uint32_t nbytes, * Return: none */ void hif_ce_desc_record_rx_paddr(struct hif_softc *scn, - struct hif_ce_desc_event *event); + struct hif_ce_desc_event *event, + qdf_nbuf_t nbuf); #else static inline void hif_ce_desc_record_rx_paddr(struct hif_softc *scn, - struct hif_ce_desc_event *event) + struct hif_ce_desc_event *event, + qdf_nbuf_t nbuf) { } -#endif +#endif /* HIF_RECORD_PADDR */ #endif /* __COPY_ENGINE_INTERNAL_H__ */ diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c index 47365394b58b..2bd149e41908 100644 --- a/hif/src/ce/ce_service.c +++ b/hif/src/ce/ce_service.c @@ -139,36 +139,24 @@ void hif_clear_ce_desc_debug_data(struct hif_ce_desc_event *event) { qdf_mem_zero(event, sizeof(struct hif_ce_desc_event)); } -#endif +#endif /* HIF_CE_DEBUG_DATA_BUF */ -#if defined(HIF_CONFIG_SLUB_DEBUG_ON) && defined(HIF_RECORD_RX_PADDR) -/** - * hif_ce_desc_record_rx_paddr() - record physical address for IOMMU - * IOVA addr and MMU virtual addr for Rx - * @scn: hif_softc - * @event: structure detailing a ce event - * - * Record physical address for ce event type HIF_RX_DESC_POST and - * HIF_RX_DESC_COMPLETION - * - * Return: none - */ +#if defined(HIF_RECORD_PADDR) void hif_ce_desc_record_rx_paddr(struct hif_softc *scn, - struct hif_ce_desc_event *event) + struct hif_ce_desc_event *event, + qdf_nbuf_t memory) { - if (event->type != HIF_RX_DESC_POST && - event->type != HIF_RX_DESC_COMPLETION) - return; - - if (event->descriptor.dest_desc.buffer_addr) + if (memory) { + event->dma_addr = QDF_NBUF_CB_PADDR(memory); event->dma_to_phy = qdf_mem_paddr_from_dmaaddr( - scn->qdf_dev, - event->descriptor.dest_desc.buffer_addr); + scn->qdf_dev, + event->dma_addr); - if (event->memory) - event->virt_to_phy = virt_to_phys(qdf_nbuf_data(event->memory)); + event->virt_to_phy = + virt_to_phys(qdf_nbuf_data(memory)); + } } -#endif +#endif /* HIF_RECORD_RX_PADDR */ /** * hif_record_ce_desc_event() - record ce descriptor events @@ -217,12 +205,14 @@ void hif_record_ce_desc_event(struct hif_softc *scn, int ce_id, if (descriptor) qdf_mem_copy(&event->descriptor, descriptor, - sizeof(union ce_srng_desc)); + sizeof(union ce_desc)); event->memory = memory; event->index = index; - hif_ce_desc_record_rx_paddr(scn, event); + if (event->type == HIF_RX_DESC_POST || + event->type == HIF_RX_DESC_COMPLETION) + hif_ce_desc_record_rx_paddr(scn, event, memory); if (ce_hist->data_enable[ce_id]) hif_ce_desc_data_record(event, len); diff --git a/hif/src/ce/ce_service_srng.c b/hif/src/ce/ce_service_srng.c index 7018f4c0121b..4456f5758e5f 100644 --- a/hif/src/ce/ce_service_srng.c +++ b/hif/src/ce/ce_service_srng.c @@ -124,10 +124,13 @@ void hif_record_ce_srng_desc_event(struct hif_softc *scn, int ce_id, event->memory = memory; event->index = index; + if (event->type == HIF_CE_SRC_RING_BUFFER_POST) + hif_ce_desc_record_rx_paddr(scn, event, memory); + if (ce_hist->data_enable[ce_id]) hif_ce_desc_data_record(event, len); } -#endif +#endif /* HIF_CONFIG_SLUB_DEBUG_ON || HIF_CE_DEBUG_DATA_BUF */ static int ce_send_nolock_srng(struct CE_handle *copyeng,