crypto: qat - num_rings_per_bank is device dependent
authorAhsan Atta <ahsan.atta@intel.com>
Mon, 12 Oct 2020 20:38:19 +0000 (21:38 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 30 Oct 2020 06:34:46 +0000 (17:34 +1100)
This change is to allow support for QAT devices that may not have 16
rings per bank.
The rings structure in bank is allocated dynamically based on the number
of banks supported by a device.

Note that in the error path in adf_init_bank(), ring->inflights is set
to NULL after the free to silence a false positive double free reported
by clang scan-build.

Signed-off-by: Ahsan Atta <ahsan.atta@intel.com>
Co-developed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Fiona Trahe <fiona.trahe@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c
drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c
drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c
drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c
drivers/crypto/qat/qat_common/adf_accel_devices.h
drivers/crypto/qat/qat_common/adf_transport.c
drivers/crypto/qat/qat_common/adf_transport_debug.c
drivers/crypto/qat/qat_common/adf_transport_internal.h
drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c

index 4b2f5aa83391946b06a7d7521994021ad3f767fe..62b0b290ff856ce5e0cf774aeeae6e6329c76001 100644 (file)
@@ -176,6 +176,7 @@ void adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data)
        hw_data->dev_class = &c3xxx_class;
        hw_data->instance_id = c3xxx_class.instances++;
        hw_data->num_banks = ADF_C3XXX_ETR_MAX_BANKS;
+       hw_data->num_rings_per_bank = ADF_ETR_MAX_RINGS_PER_BANK;
        hw_data->num_accel = ADF_C3XXX_MAX_ACCELERATORS;
        hw_data->num_logical_accel = 1;
        hw_data->num_engines = ADF_C3XXX_MAX_ACCELENGINES;
index cdf8c500ef2a7fdd7a879c4c5c60d113847fd3ea..80a355e85a724522722fcfd8a67e00d16dc6e58e 100644 (file)
@@ -69,6 +69,7 @@ void adf_init_hw_data_c3xxxiov(struct adf_hw_device_data *hw_data)
 {
        hw_data->dev_class = &c3xxxiov_class;
        hw_data->num_banks = ADF_C3XXXIOV_ETR_MAX_BANKS;
+       hw_data->num_rings_per_bank = ADF_ETR_MAX_RINGS_PER_BANK;
        hw_data->num_accel = ADF_C3XXXIOV_MAX_ACCELERATORS;
        hw_data->num_logical_accel = 1;
        hw_data->num_engines = ADF_C3XXXIOV_MAX_ACCELENGINES;
index c0b5751e96821657662669f6f15d52cfac137cd6..1334b43e46e42ffa877009e222905b3397029a21 100644 (file)
@@ -186,6 +186,7 @@ void adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data)
        hw_data->dev_class = &c62x_class;
        hw_data->instance_id = c62x_class.instances++;
        hw_data->num_banks = ADF_C62X_ETR_MAX_BANKS;
+       hw_data->num_rings_per_bank = ADF_ETR_MAX_RINGS_PER_BANK;
        hw_data->num_accel = ADF_C62X_MAX_ACCELERATORS;
        hw_data->num_logical_accel = 1;
        hw_data->num_engines = ADF_C62X_MAX_ACCELENGINES;
index a2543f75e81fed896ca00e8848270c5e74f5ec71..7725387e58f81c90ac5c669d40defb0ebb47992f 100644 (file)
@@ -69,6 +69,7 @@ void adf_init_hw_data_c62xiov(struct adf_hw_device_data *hw_data)
 {
        hw_data->dev_class = &c62xiov_class;
        hw_data->num_banks = ADF_C62XIOV_ETR_MAX_BANKS;
+       hw_data->num_rings_per_bank = ADF_ETR_MAX_RINGS_PER_BANK;
        hw_data->num_accel = ADF_C62XIOV_MAX_ACCELERATORS;
        hw_data->num_logical_accel = 1;
        hw_data->num_engines = ADF_C62XIOV_MAX_ACCELENGINES;
index 411a505e1f59f1b0cdbc139a2ea20265a456575a..85b423d28f776bd4f7096999947c6c0e9ce50436 100644 (file)
@@ -139,6 +139,7 @@ struct adf_hw_device_data {
        u16 tx_rings_mask;
        u8 tx_rx_gap;
        u8 num_banks;
+       u8 num_rings_per_bank;
        u8 num_accel;
        u8 num_logical_accel;
        u8 num_engines;
@@ -156,6 +157,8 @@ struct adf_hw_device_data {
 #define GET_BARS(accel_dev) ((accel_dev)->accel_pci_dev.pci_bars)
 #define GET_HW_DATA(accel_dev) (accel_dev->hw_device)
 #define GET_MAX_BANKS(accel_dev) (GET_HW_DATA(accel_dev)->num_banks)
+#define GET_NUM_RINGS_PER_BANK(accel_dev) \
+       GET_HW_DATA(accel_dev)->num_rings_per_bank
 #define GET_MAX_ACCELENGINES(accel_dev) (GET_HW_DATA(accel_dev)->num_engines)
 #define accel_to_pci_dev(accel_ptr) accel_ptr->accel_pci_dev.pci_dev
 
index 2ad774017200f882405ccda44318ecb04efbc62e..24ddaaaa55b119edba4b5ec1d4dbee138eaab681 100644 (file)
@@ -190,6 +190,7 @@ int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,
                    struct adf_etr_ring_data **ring_ptr)
 {
        struct adf_etr_data *transport_data = accel_dev->transport;
+       u8 num_rings_per_bank = GET_NUM_RINGS_PER_BANK(accel_dev);
        struct adf_etr_bank_data *bank;
        struct adf_etr_ring_data *ring;
        char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
@@ -219,7 +220,7 @@ int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,
                dev_err(&GET_DEV(accel_dev), "Can't get ring number\n");
                return -EFAULT;
        }
-       if (ring_num >= ADF_ETR_MAX_RINGS_PER_BANK) {
+       if (ring_num >= num_rings_per_bank) {
                dev_err(&GET_DEV(accel_dev), "Invalid ring number\n");
                return -EFAULT;
        }
@@ -286,15 +287,15 @@ void adf_remove_ring(struct adf_etr_ring_data *ring)
 
 static void adf_ring_response_handler(struct adf_etr_bank_data *bank)
 {
-       u32 empty_rings, i;
+       u8 num_rings_per_bank = GET_NUM_RINGS_PER_BANK(bank->accel_dev);
+       unsigned long empty_rings;
+       int i;
 
        empty_rings = READ_CSR_E_STAT(bank->csr_addr, bank->bank_number);
        empty_rings = ~empty_rings & bank->irq_mask;
 
-       for (i = 0; i < ADF_ETR_MAX_RINGS_PER_BANK; ++i) {
-               if (empty_rings & (1 << i))
-                       adf_handle_response(&bank->rings[i]);
-       }
+       for_each_set_bit(i, &empty_rings, num_rings_per_bank)
+               adf_handle_response(&bank->rings[i]);
 }
 
 void adf_response_handler(uintptr_t bank_addr)
@@ -343,9 +344,12 @@ static int adf_init_bank(struct adf_accel_dev *accel_dev,
                         u32 bank_num, void __iomem *csr_addr)
 {
        struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+       u8 num_rings_per_bank = hw_data->num_rings_per_bank;
        struct adf_etr_ring_data *ring;
        struct adf_etr_ring_data *tx_ring;
        u32 i, coalesc_enabled = 0;
+       unsigned long ring_mask;
+       int size;
 
        memset(bank, 0, sizeof(*bank));
        bank->bank_number = bank_num;
@@ -353,6 +357,13 @@ static int adf_init_bank(struct adf_accel_dev *accel_dev,
        bank->accel_dev = accel_dev;
        spin_lock_init(&bank->lock);
 
+       /* Allocate the rings in the bank */
+       size = num_rings_per_bank * sizeof(struct adf_etr_ring_data);
+       bank->rings = kzalloc_node(size, GFP_KERNEL,
+                                  dev_to_node(&GET_DEV(accel_dev)));
+       if (!bank->rings)
+               return -ENOMEM;
+
        /* Enable IRQ coalescing always. This will allow to use
         * the optimised flag and coalesc register.
         * If it is disabled in the config file just use min time value */
@@ -363,7 +374,7 @@ static int adf_init_bank(struct adf_accel_dev *accel_dev,
        else
                bank->irq_coalesc_timer = ADF_COALESCING_MIN_TIME;
 
-       for (i = 0; i < ADF_ETR_MAX_RINGS_PER_BANK; i++) {
+       for (i = 0; i < num_rings_per_bank; i++) {
                WRITE_CSR_RING_CONFIG(csr_addr, bank_num, i, 0);
                WRITE_CSR_RING_BASE(csr_addr, bank_num, i, 0);
                ring = &bank->rings[i];
@@ -394,11 +405,13 @@ static int adf_init_bank(struct adf_accel_dev *accel_dev,
        WRITE_CSR_INT_SRCSEL(csr_addr, bank_num);
        return 0;
 err:
-       for (i = 0; i < ADF_ETR_MAX_RINGS_PER_BANK; i++) {
+       ring_mask = hw_data->tx_rings_mask;
+       for_each_set_bit(i, &ring_mask, num_rings_per_bank) {
                ring = &bank->rings[i];
-               if (hw_data->tx_rings_mask & (1 << i))
-                       kfree(ring->inflights);
+               kfree(ring->inflights);
+               ring->inflights = NULL;
        }
+       kfree(bank->rings);
        return -ENOMEM;
 }
 
@@ -464,11 +477,12 @@ EXPORT_SYMBOL_GPL(adf_init_etr_data);
 
 static void cleanup_bank(struct adf_etr_bank_data *bank)
 {
+       struct adf_accel_dev *accel_dev = bank->accel_dev;
+       struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+       u8 num_rings_per_bank = hw_data->num_rings_per_bank;
        u32 i;
 
-       for (i = 0; i < ADF_ETR_MAX_RINGS_PER_BANK; i++) {
-               struct adf_accel_dev *accel_dev = bank->accel_dev;
-               struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+       for (i = 0; i < num_rings_per_bank; i++) {
                struct adf_etr_ring_data *ring = &bank->rings[i];
 
                if (bank->ring_mask & (1 << i))
@@ -477,6 +491,7 @@ static void cleanup_bank(struct adf_etr_bank_data *bank)
                if (hw_data->tx_rings_mask & (1 << i))
                        kfree(ring->inflights);
        }
+       kfree(bank->rings);
        adf_bank_debugfs_rm(bank);
        memset(bank, 0, sizeof(*bank));
 }
@@ -507,6 +522,7 @@ void adf_cleanup_etr_data(struct adf_accel_dev *accel_dev)
        if (etr_data) {
                adf_cleanup_etr_handles(accel_dev);
                debugfs_remove(etr_data->debug);
+               kfree(etr_data->banks->rings);
                kfree(etr_data->banks);
                kfree(etr_data);
                accel_dev->transport = NULL;
index dac25ba47260b321935cd2ef67061603c6eac1fb..da79d734c0351adadc30de9f9e3e42094c48d422 100644 (file)
@@ -117,11 +117,14 @@ void adf_ring_debugfs_rm(struct adf_etr_ring_data *ring)
 
 static void *adf_bank_start(struct seq_file *sfile, loff_t *pos)
 {
+       struct adf_etr_bank_data *bank = sfile->private;
+       u8 num_rings_per_bank = GET_NUM_RINGS_PER_BANK(bank->accel_dev);
+
        mutex_lock(&bank_read_lock);
        if (*pos == 0)
                return SEQ_START_TOKEN;
 
-       if (*pos >= ADF_ETR_MAX_RINGS_PER_BANK)
+       if (*pos >= num_rings_per_bank)
                return NULL;
 
        return pos;
@@ -129,7 +132,10 @@ static void *adf_bank_start(struct seq_file *sfile, loff_t *pos)
 
 static void *adf_bank_next(struct seq_file *sfile, void *v, loff_t *pos)
 {
-       if (++(*pos) >= ADF_ETR_MAX_RINGS_PER_BANK)
+       struct adf_etr_bank_data *bank = sfile->private;
+       u8 num_rings_per_bank = GET_NUM_RINGS_PER_BANK(bank->accel_dev);
+
+       if (++(*pos) >= num_rings_per_bank)
                return NULL;
 
        return pos;
index c7faf4e2d30275a9b70ab8f2e2e0c42645c9dde8..501bcf0f1809afb34be0633cf0edd4c63d7ee608 100644 (file)
@@ -28,7 +28,7 @@ struct adf_etr_ring_data {
 };
 
 struct adf_etr_bank_data {
-       struct adf_etr_ring_data rings[ADF_ETR_MAX_RINGS_PER_BANK];
+       struct adf_etr_ring_data *rings;
        struct tasklet_struct resp_handler;
        void __iomem *csr_addr;
        u32 irq_coalesc_timer;
index 6a0d01103136f4f2bc4726a79d4fb34bca677a66..1f3ea3ba1cee37e1600df8ad94aba3972e815dea 100644 (file)
@@ -185,6 +185,7 @@ void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data)
        hw_data->dev_class = &dh895xcc_class;
        hw_data->instance_id = dh895xcc_class.instances++;
        hw_data->num_banks = ADF_DH895XCC_ETR_MAX_BANKS;
+       hw_data->num_rings_per_bank = ADF_ETR_MAX_RINGS_PER_BANK;
        hw_data->num_accel = ADF_DH895XCC_MAX_ACCELERATORS;
        hw_data->num_logical_accel = 1;
        hw_data->num_engines = ADF_DH895XCC_MAX_ACCELENGINES;
index 737f9132f71a85781b329679cc6f34d543dc9753..eca144bc1d67c2014e116b7cdc2a93fbfaf09f6e 100644 (file)
@@ -69,6 +69,7 @@ void adf_init_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data)
 {
        hw_data->dev_class = &dh895xcciov_class;
        hw_data->num_banks = ADF_DH895XCCIOV_ETR_MAX_BANKS;
+       hw_data->num_rings_per_bank = ADF_ETR_MAX_RINGS_PER_BANK;
        hw_data->num_accel = ADF_DH895XCCIOV_MAX_ACCELERATORS;
        hw_data->num_logical_accel = 1;
        hw_data->num_engines = ADF_DH895XCCIOV_MAX_ACCELENGINES;