瀏覽代碼

qcacld-3.0: Return EBUSY instead of EAGAIN from __dsc_vdev_can_trans

Currently driver returns EAGAIN as error code if vdev transition is
not possible, driver is not able to process this vdev transition
because some other PSOC/PDEV transition is going on.
On receiving EAGAIN error code userspace retries the same operation
immediately which again leads to failure as existing transition is
still in progress.

In current scenario, for STA+P2P case, if station is connected to
some ap and for p2p if DUT becomes p2p go, now if SSR is triggered,
host driver gets interface down for sta for change mac address as
station gets disconnected as part of SSR and this interface down
is cached as SSR is in progress. Once reinit gets complete, driver
processes this cached interface down as part of SSR and in this
process driver gets the change interface for p2p go, which it
rejects the error code as EAGAIN from __dsc_vdev_can_trans as
SSR is going on and change interface fails to get dsc op.
When user space gets EAGAIN as error code it immediately tries
the change interface again which driver again rejects as SSR is
still in progress. Also, on receiving EAGAIN error code, userspace
retries the change iface operation only once.

To address above issue, return error code as EBUSY, on receiving
EBUSY as erorr code, user space addds some wait before invoking
the same operation again and also it tries this operation 10 times
if it gets EBUSY as error code, this gives sufficient time to
complete the ongoing transition at driver.

Change-Id: I96ec94432e7624546363cda190abfc9970ab1eb9
CRs-Fixed: 3126558
Ashish 3 年之前
父節點
當前提交
ba7faf192a
共有 2 個文件被更改,包括 13 次插入11 次删除
  1. 6 5
      components/dsc/src/wlan_dsc_vdev.c
  2. 7 6
      components/dsc/test/wlan_dsc_test.c

+ 6 - 5
components/dsc/src/wlan_dsc_vdev.c

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * any purpose with or without fee is hereby granted, provided that the
@@ -118,17 +119,17 @@ void dsc_vdev_destroy(struct dsc_vdev **out_vdev)
  *
  *
  * If there are any psoc transition taking place because of SSR, then vdev
  * If there are any psoc transition taking place because of SSR, then vdev
  * trans/op should be rejected and queued in the DSC queue so that it may be
  * trans/op should be rejected and queued in the DSC queue so that it may be
- * resumed after the current trans/op is completed. return QDF_STATUS_E_AGAIN
+ * resumed after the current trans/op is completed. return QDF_STATUS_E_BUSY
  * in this case.
  * in this case.
  *
  *
  * If there is a psoc transition taking place becasue of psoc idle shutdown,
  * If there is a psoc transition taking place becasue of psoc idle shutdown,
  * then the vdev trans/ops should be rejected and queued in the DSC queue so
  * then the vdev trans/ops should be rejected and queued in the DSC queue so
  * that it may be resumed after the current trans/ops is completed. Return
  * that it may be resumed after the current trans/ops is completed. Return
- * QDF_STATUS_E_AGAIN in this case.
+ * QDF_STATUS_E_BUSY in this case.
  *
  *
  * If there are any vdev trans/ops taking place, then the vdev trans/ops
  * If there are any vdev trans/ops taking place, then the vdev trans/ops
  * should be rejected and queued in the DSC queue so that it may be resumed
  * should be rejected and queued in the DSC queue so that it may be resumed
- * after the current trans/ops is completed. Return QDF_STATUS_E_AGAIN in this
+ * after the current trans/ops is completed. Return QDF_STATUS_E_BUSY in this
  * case.
  * case.
  *
  *
  * Return: QDF_STATUS_SUCCESS if transition is allowed, error code if not.
  * Return: QDF_STATUS_SUCCESS if transition is allowed, error code if not.
@@ -151,11 +152,11 @@ static QDF_STATUS __dsc_vdev_can_trans(struct dsc_vdev *vdev)
 		if (qdf_is_driver_unloading())
 		if (qdf_is_driver_unloading())
 			return QDF_STATUS_E_INVAL;
 			return QDF_STATUS_E_INVAL;
 		else
 		else
-			return QDF_STATUS_E_AGAIN;
+			return QDF_STATUS_E_BUSY;
 	}
 	}
 
 
 	if (__dsc_trans_active_or_queued(&vdev->trans))
 	if (__dsc_trans_active_or_queued(&vdev->trans))
-		return QDF_STATUS_E_AGAIN;
+		return QDF_STATUS_E_BUSY;
 
 
 	return QDF_STATUS_SUCCESS;
 	return QDF_STATUS_SUCCESS;
 }
 }

+ 7 - 6
components/dsc/test/wlan_dsc_test.c

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
  * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * any purpose with or without fee is hereby granted, provided that the
@@ -265,8 +266,8 @@ static uint32_t dsc_test_psoc_trans_blocks(void)
 
 
 	/* ... children vdev trans/ops to fail */
 	/* ... children vdev trans/ops to fail */
 	dsc_for_each_psoc_vdev(psoc, vdev) {
 	dsc_for_each_psoc_vdev(psoc, vdev) {
-		action_expect(vdev, trans, QDF_STATUS_E_AGAIN, errors);
-		action_expect(vdev, op, QDF_STATUS_E_AGAIN, errors);
+		action_expect(vdev, trans, QDF_STATUS_E_BUSY, errors);
+		action_expect(vdev, op, QDF_STATUS_E_BUSY, errors);
 	}
 	}
 
 
 	/* ... while driver unload in progress vdev op and trans should be
 	/* ... while driver unload in progress vdev op and trans should be
@@ -303,8 +304,8 @@ static uint32_t dsc_test_psoc_trans_blocks(void)
 
 
 	/* ... children vdev trans/ops to fail */
 	/* ... children vdev trans/ops to fail */
 	dsc_for_each_psoc_vdev(psoc, vdev) {
 	dsc_for_each_psoc_vdev(psoc, vdev) {
-		action_expect(vdev, trans, QDF_STATUS_E_AGAIN, errors);
-		action_expect(vdev, op, QDF_STATUS_E_AGAIN, errors);
+		action_expect(vdev, trans, QDF_STATUS_E_BUSY, errors);
+		action_expect(vdev, op, QDF_STATUS_E_BUSY, errors);
 	}
 	}
 
 
 	/* teardown */
 	/* teardown */
@@ -357,8 +358,8 @@ static uint32_t dsc_test_vdev_trans_blocks(void)
 
 
 		/* ... the same vdev trans/ops to fail */
 		/* ... the same vdev trans/ops to fail */
 		dsc_for_each_psoc_vdev(psoc, vdev) {
 		dsc_for_each_psoc_vdev(psoc, vdev) {
-			action_expect(vdev, trans, QDF_STATUS_E_AGAIN, errors);
-			action_expect(vdev, op, QDF_STATUS_E_AGAIN, errors);
+			action_expect(vdev, trans, QDF_STATUS_E_BUSY, errors);
+			action_expect(vdev, op, QDF_STATUS_E_BUSY, errors);
 		}
 		}
 	}
 	}