From 5ecffb6ba732d11b5a703816e039d9809fdf0e5c Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Fri, 21 Sep 2018 12:20:05 -0700 Subject: [PATCH] qcacld-3.0: Use dynamic alloc for DSC driver context The DSC driver context was originally statically allocated to allow its creation before QDF was initialized. However, other complications with the QDF debug infrastructure lead to QDF being initialized before DSC anyway. Static allocation has a number of drawbacks (esp. see singleton anit-pattern), which impacts our ability to do unit testing on a driver which actively leverages DSC. To support unit-testing DSC in a driver which also uses DSC, move the DSC driver context to dynamic, instead of static, allocation. Change-Id: Ic3121092c71d5c46e8521a775281ad2c45e3fe7d CRs-Fixed: 2320599 --- components/dsc/src/__wlan_dsc.h | 10 +++-- components/dsc/src/wlan_dsc_driver.c | 55 +++++++++++++--------------- components/dsc/src/wlan_dsc_psoc.c | 41 +++++++++++---------- components/dsc/src/wlan_dsc_vdev.c | 41 +++++++++++---------- 4 files changed, 75 insertions(+), 72 deletions(-) diff --git a/components/dsc/src/__wlan_dsc.h b/components/dsc/src/__wlan_dsc.h index a7b5b3cc23..103413d0d4 100644 --- a/components/dsc/src/__wlan_dsc.h +++ b/components/dsc/src/__wlan_dsc.h @@ -160,18 +160,20 @@ struct dsc_vdev { qdf_list_for_each(&(psoc_ptr)->vdevs, vdev_cursor, node) /** - * __dsc_lock() - grab the dsc global lock + * __dsc_lock() - grab the dsc driver lock + * @driver: the driver to lock * * Return: None */ -void __dsc_lock(void); +void __dsc_lock(struct dsc_driver *driver); /** - * __dsc_unlock() - release the dsc global lock + * __dsc_unlock() - release the dsc driver lock + * @driver: the driver to unlock * * Return: None */ -void __dsc_unlock(void); +void __dsc_unlock(struct dsc_driver *driver); /** * __dsc_ops_init() - initialize @ops diff --git a/components/dsc/src/wlan_dsc_driver.c b/components/dsc/src/wlan_dsc_driver.c index da7d46c4a8..b9b70ec02f 100644 --- a/components/dsc/src/wlan_dsc_driver.c +++ b/components/dsc/src/wlan_dsc_driver.c @@ -22,35 +22,30 @@ #include "__wlan_dsc.h" #include "wlan_dsc.h" -static struct dsc_driver __dsc_ctx; -static bool __dsc_init; - -void __dsc_lock(void) +void __dsc_lock(struct dsc_driver *driver) { - dsc_assert(__dsc_init); - qdf_spin_lock_bh(&__dsc_ctx.lock); + dsc_assert(driver); + qdf_spin_lock_bh(&driver->lock); } -void __dsc_unlock(void) +void __dsc_unlock(struct dsc_driver *driver) { - dsc_assert(__dsc_init); - qdf_spin_unlock_bh(&__dsc_ctx.lock); + dsc_assert(driver); + qdf_spin_unlock_bh(&driver->lock); } static QDF_STATUS __dsc_driver_create(struct dsc_driver **out_driver) { struct dsc_driver *driver; - if (!dsc_assert(!__dsc_init)) - return QDF_STATUS_E_ALREADY; - if (!dsc_assert(out_driver)) return QDF_STATUS_E_INVAL; *out_driver = NULL; - __dsc_init = true; - driver = &__dsc_ctx; + driver = qdf_mem_malloc(sizeof(*driver)); + if (!driver) + return QDF_STATUS_E_NOMEM; qdf_spinlock_create(&driver->lock); qdf_list_create(&driver->psocs, 0); @@ -99,7 +94,7 @@ static void __dsc_driver_destroy(struct dsc_driver **out_driver) qdf_list_destroy(&driver->psocs); qdf_spinlock_destroy(&driver->lock); - __dsc_init = false; + qdf_mem_free(driver); } void dsc_driver_destroy(struct dsc_driver **out_driver) @@ -166,9 +161,9 @@ __dsc_driver_trans_start(struct dsc_driver *driver, const char *desc) if (!dsc_assert(desc)) return QDF_STATUS_E_INVAL; - __dsc_lock(); + __dsc_lock(driver); status = __dsc_driver_trans_start_nolock(driver, desc); - __dsc_unlock(); + __dsc_unlock(driver); return status; } @@ -196,17 +191,17 @@ __dsc_driver_trans_start_wait(struct dsc_driver *driver, const char *desc) if (!dsc_assert(desc)) return QDF_STATUS_E_INVAL; - __dsc_lock(); + __dsc_lock(driver); status = __dsc_driver_trans_start_nolock(driver, desc); if (QDF_IS_STATUS_SUCCESS(status)) { - __dsc_unlock(); + __dsc_unlock(driver); return QDF_STATUS_SUCCESS; } __dsc_trans_queue(&driver->trans, &tran, desc); - __dsc_unlock(); + __dsc_unlock(driver); return __dsc_tran_wait(&tran); } @@ -266,18 +261,18 @@ static void __dsc_driver_trans_stop(struct dsc_driver *driver) void dsc_driver_trans_stop(struct dsc_driver *driver) { dsc_enter(); - __dsc_lock(); + __dsc_lock(driver); __dsc_driver_trans_stop(driver); - __dsc_unlock(); + __dsc_unlock(driver); dsc_exit(); } void dsc_driver_trans_assert(struct dsc_driver *driver) { dsc_enter(); - __dsc_lock(); + __dsc_lock(driver); dsc_assert(driver->trans.active_desc); - __dsc_unlock(); + __dsc_unlock(driver); dsc_exit(); } @@ -301,9 +296,9 @@ QDF_STATUS _dsc_driver_op_start(struct dsc_driver *driver, const char *func) QDF_STATUS status; dsc_enter_str(func); - __dsc_lock(); + __dsc_lock(driver); status = __dsc_driver_op_start(driver, func); - __dsc_unlock(); + __dsc_unlock(driver); dsc_exit_status(status); return status; @@ -324,9 +319,9 @@ static void __dsc_driver_op_stop(struct dsc_driver *driver, const char *func) void _dsc_driver_op_stop(struct dsc_driver *driver, const char *func) { dsc_enter_str(func); - __dsc_lock(); + __dsc_lock(driver); __dsc_driver_op_stop(driver, func); - __dsc_unlock(); + __dsc_unlock(driver); dsc_exit(); } @@ -338,7 +333,7 @@ static void __dsc_driver_wait_for_ops(struct dsc_driver *driver) if (!dsc_assert(driver)) return; - __dsc_lock(); + __dsc_lock(driver); /* flushing without preventing new ops is almost certainly a bug */ dsc_assert(!__dsc_driver_can_op(driver)); @@ -347,7 +342,7 @@ static void __dsc_driver_wait_for_ops(struct dsc_driver *driver) if (wait) qdf_event_reset(&driver->ops.event); - __dsc_unlock(); + __dsc_unlock(driver); if (wait) qdf_wait_single_event(&driver->ops.event, 0); diff --git a/components/dsc/src/wlan_dsc_psoc.c b/components/dsc/src/wlan_dsc_psoc.c index 50e3b81233..ea62b32679 100644 --- a/components/dsc/src/wlan_dsc_psoc.c +++ b/components/dsc/src/wlan_dsc_psoc.c @@ -23,6 +23,9 @@ #include "__wlan_dsc.h" #include "wlan_dsc.h" +#define __dsc_driver_lock(psoc) __dsc_lock((psoc)->driver) +#define __dsc_driver_unlock(psoc) __dsc_unlock((psoc)->driver) + static QDF_STATUS __dsc_psoc_create(struct dsc_driver *driver, struct dsc_psoc **out_psoc) { @@ -47,9 +50,9 @@ __dsc_psoc_create(struct dsc_driver *driver, struct dsc_psoc **out_psoc) __dsc_ops_init(&psoc->ops); /* attach */ - __dsc_lock(); + __dsc_driver_lock(psoc); qdf_list_insert_back(&driver->psocs, &psoc->node); - __dsc_unlock(); + __dsc_driver_unlock(psoc); *out_psoc = psoc; @@ -89,9 +92,9 @@ static void __dsc_psoc_destroy(struct dsc_psoc **out_psoc) ; /* detach */ - __dsc_lock(); + __dsc_driver_lock(psoc); qdf_list_remove_node(&psoc->driver->psocs, &psoc->node); - __dsc_unlock(); + __dsc_driver_unlock(psoc); /* de-init */ __dsc_ops_deinit(&psoc->ops); @@ -163,9 +166,9 @@ __dsc_psoc_trans_start(struct dsc_psoc *psoc, const char *desc) if (!dsc_assert(desc)) return QDF_STATUS_E_INVAL; - __dsc_lock(); + __dsc_driver_lock(psoc); status = __dsc_psoc_trans_start_nolock(psoc, desc); - __dsc_unlock(); + __dsc_driver_unlock(psoc); return status; } @@ -193,17 +196,17 @@ __dsc_psoc_trans_start_wait(struct dsc_psoc *psoc, const char *desc) if (!dsc_assert(desc)) return QDF_STATUS_E_INVAL; - __dsc_lock(); + __dsc_driver_lock(psoc); status = __dsc_psoc_trans_start_nolock(psoc, desc); if (QDF_IS_STATUS_SUCCESS(status)) { - __dsc_unlock(); + __dsc_driver_unlock(psoc); return QDF_STATUS_SUCCESS; } __dsc_trans_queue(&psoc->trans, &tran, desc); - __dsc_unlock(); + __dsc_driver_unlock(psoc); return __dsc_tran_wait(&tran); } @@ -247,18 +250,18 @@ static void __dsc_psoc_trans_stop(struct dsc_psoc *psoc) void dsc_psoc_trans_stop(struct dsc_psoc *psoc) { dsc_enter(); - __dsc_lock(); + __dsc_driver_lock(psoc); __dsc_psoc_trans_stop(psoc); - __dsc_unlock(); + __dsc_driver_unlock(psoc); dsc_exit(); } void dsc_psoc_trans_assert(struct dsc_psoc *psoc) { dsc_enter(); - __dsc_lock(); + __dsc_driver_lock(psoc); dsc_assert(psoc->trans.active_desc); - __dsc_unlock(); + __dsc_driver_unlock(psoc); dsc_exit(); } @@ -293,9 +296,9 @@ QDF_STATUS _dsc_psoc_op_start(struct dsc_psoc *psoc, const char *func) QDF_STATUS status; dsc_enter_str(func); - __dsc_lock(); + __dsc_driver_lock(psoc); status = __dsc_psoc_op_start(psoc, func); - __dsc_unlock(); + __dsc_driver_unlock(psoc); dsc_exit_status(status); return status; @@ -316,9 +319,9 @@ static void __dsc_psoc_op_stop(struct dsc_psoc *psoc, const char *func) void _dsc_psoc_op_stop(struct dsc_psoc *psoc, const char *func) { dsc_enter_str(func); - __dsc_lock(); + __dsc_driver_lock(psoc); __dsc_psoc_op_stop(psoc, func); - __dsc_unlock(); + __dsc_driver_unlock(psoc); dsc_exit(); } @@ -330,7 +333,7 @@ static void __dsc_psoc_wait_for_ops(struct dsc_psoc *psoc) if (!dsc_assert(psoc)) return; - __dsc_lock(); + __dsc_driver_lock(psoc); /* flushing without preventing new ops is almost certainly a bug */ dsc_assert(!__dsc_psoc_can_op(psoc)); @@ -339,7 +342,7 @@ static void __dsc_psoc_wait_for_ops(struct dsc_psoc *psoc) if (wait) qdf_event_reset(&psoc->ops.event); - __dsc_unlock(); + __dsc_driver_unlock(psoc); if (wait) qdf_wait_single_event(&psoc->ops.event, 0); diff --git a/components/dsc/src/wlan_dsc_vdev.c b/components/dsc/src/wlan_dsc_vdev.c index 8d673978ed..7466dbd729 100644 --- a/components/dsc/src/wlan_dsc_vdev.c +++ b/components/dsc/src/wlan_dsc_vdev.c @@ -23,6 +23,9 @@ #include "__wlan_dsc.h" #include "wlan_dsc.h" +#define __dsc_driver_lock(vdev) __dsc_lock((vdev)->psoc->driver) +#define __dsc_driver_unlock(vdev) __dsc_unlock((vdev)->psoc->driver) + static QDF_STATUS __dsc_vdev_create(struct dsc_psoc *psoc, struct dsc_vdev **out_vdev) { @@ -46,9 +49,9 @@ __dsc_vdev_create(struct dsc_psoc *psoc, struct dsc_vdev **out_vdev) __dsc_ops_init(&vdev->ops); /* attach */ - __dsc_lock(); + __dsc_driver_lock(vdev); qdf_list_insert_back(&psoc->vdevs, &vdev->node); - __dsc_unlock(); + __dsc_driver_unlock(vdev); *out_vdev = vdev; @@ -84,9 +87,9 @@ static void __dsc_vdev_destroy(struct dsc_vdev **out_vdev) ; /* detach */ - __dsc_lock(); + __dsc_driver_lock(vdev); qdf_list_remove_node(&vdev->psoc->vdevs, &vdev->node); - __dsc_unlock(); + __dsc_driver_unlock(vdev); /* de-init */ __dsc_ops_deinit(&vdev->ops); @@ -137,9 +140,9 @@ __dsc_vdev_trans_start(struct dsc_vdev *vdev, const char *desc) if (!dsc_assert(desc)) return QDF_STATUS_E_INVAL; - __dsc_lock(); + __dsc_driver_lock(vdev); status = __dsc_vdev_trans_start_nolock(vdev, desc); - __dsc_unlock(); + __dsc_driver_unlock(vdev); return status; } @@ -167,17 +170,17 @@ __dsc_vdev_trans_start_wait(struct dsc_vdev *vdev, const char *desc) if (!dsc_assert(desc)) return QDF_STATUS_E_INVAL; - __dsc_lock(); + __dsc_driver_lock(vdev); status = __dsc_vdev_trans_start_nolock(vdev, desc); if (QDF_IS_STATUS_SUCCESS(status)) { - __dsc_unlock(); + __dsc_driver_unlock(vdev); return QDF_STATUS_SUCCESS; } __dsc_trans_queue(&vdev->trans, &tran, desc); - __dsc_unlock(); + __dsc_driver_unlock(vdev); return __dsc_tran_wait(&tran); } @@ -218,18 +221,18 @@ static void __dsc_vdev_trans_stop(struct dsc_vdev *vdev) void dsc_vdev_trans_stop(struct dsc_vdev *vdev) { dsc_enter(); - __dsc_lock(); + __dsc_driver_lock(vdev); __dsc_vdev_trans_stop(vdev); - __dsc_unlock(); + __dsc_driver_unlock(vdev); dsc_exit(); } void dsc_vdev_trans_assert(struct dsc_vdev *vdev) { dsc_enter(); - __dsc_lock(); + __dsc_driver_lock(vdev); dsc_assert(vdev->trans.active_desc); - __dsc_unlock(); + __dsc_driver_unlock(vdev); dsc_exit(); } @@ -252,9 +255,9 @@ QDF_STATUS _dsc_vdev_op_start(struct dsc_vdev *vdev, const char *func) QDF_STATUS status; dsc_enter_str(func); - __dsc_lock(); + __dsc_driver_lock(vdev); status = __dsc_vdev_op_start(vdev, func); - __dsc_unlock(); + __dsc_driver_unlock(vdev); dsc_exit_status(status); return status; @@ -275,9 +278,9 @@ static void __dsc_vdev_op_stop(struct dsc_vdev *vdev, const char *func) void _dsc_vdev_op_stop(struct dsc_vdev *vdev, const char *func) { dsc_enter_str(func); - __dsc_lock(); + __dsc_driver_lock(vdev); __dsc_vdev_op_stop(vdev, func); - __dsc_unlock(); + __dsc_driver_unlock(vdev); dsc_exit(); } @@ -288,7 +291,7 @@ static void __dsc_vdev_wait_for_ops(struct dsc_vdev *vdev) if (!dsc_assert(vdev)) return; - __dsc_lock(); + __dsc_driver_lock(vdev); /* flushing without preventing new ops is almost certainly a bug */ dsc_assert(!__dsc_vdev_can_op(vdev)); @@ -297,7 +300,7 @@ static void __dsc_vdev_wait_for_ops(struct dsc_vdev *vdev) if (wait) qdf_event_reset(&vdev->ops.event); - __dsc_unlock(); + __dsc_driver_unlock(vdev); if (wait) qdf_wait_single_event(&vdev->ops.event, 0);