crypto: qat - fix state machines cleanup paths
authorGiovanni Cabiddu <giovanni.cabiddu@intel.com>
Thu, 14 Sep 2023 09:55:45 +0000 (10:55 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Wed, 20 Sep 2023 05:15:30 +0000 (13:15 +0800)
Commit 1bdc85550a2b ("crypto: qat - fix concurrency issue when device
state changes") introduced the function adf_dev_down() which wraps the
functions adf_dev_stop() and adf_dev_shutdown().
In a subsequent change, the sequence adf_dev_stop() followed by
adf_dev_shutdown() was then replaced across the driver with just a call
to the function adf_dev_down().

The functions adf_dev_stop() and adf_dev_shutdown() are called in error
paths to stop the accelerator and free up resources and can be called
even if the counterparts adf_dev_init() and adf_dev_start() did not
complete successfully.
However, the implementation of adf_dev_down() prevents the stop/shutdown
sequence if the device is found already down.
For example, if adf_dev_init() fails, the device status is not set as
started and therefore a call to adf_dev_down() won't be calling
adf_dev_shutdown() to undo what adf_dev_init() did.

Do not check if a device is started in adf_dev_down() but do the
equivalent check in adf_sysfs.c when handling a DEV_DOWN command from
the user.

Fixes: 2b60f79c7b81 ("crypto: qat - replace state machine calls")
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Adam Guerin <adam.guerin@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/intel/qat/qat_common/adf_init.c
drivers/crypto/intel/qat/qat_common/adf_sysfs.c

index 79a81e25de9774a7b49aace5fb2d0c8ad9598239..542318a5b7712b8bc18cbec61d6067672925efc5 100644 (file)
@@ -428,13 +428,6 @@ int adf_dev_down(struct adf_accel_dev *accel_dev, bool reconfig)
 
        mutex_lock(&accel_dev->state_lock);
 
-       if (!adf_dev_started(accel_dev)) {
-               dev_info(&GET_DEV(accel_dev), "Device qat_dev%d already down\n",
-                        accel_dev->accel_id);
-               ret = -EINVAL;
-               goto out;
-       }
-
        if (reconfig) {
                ret = adf_dev_shutdown_cache_cfg(accel_dev);
                goto out;
index a74d2f93036709375c7939f553543ea34223bf74..a8f33558d7cb85fbba3ba004233c5d9ab7fd6a4c 100644 (file)
@@ -52,6 +52,13 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr,
        case DEV_DOWN:
                dev_info(dev, "Stopping device qat_dev%d\n", accel_id);
 
+               if (!adf_dev_started(accel_dev)) {
+                       dev_info(&GET_DEV(accel_dev), "Device qat_dev%d already down\n",
+                                accel_id);
+
+                       break;
+               }
+
                ret = adf_dev_down(accel_dev, true);
                if (ret < 0)
                        return -EINVAL;