]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
crypto: qat - fix IRQ cleanup on 6xxx probe failure
authorGiovanni Cabiddu <giovanni.cabiddu@intel.com>
Wed, 1 Apr 2026 09:31:11 +0000 (10:31 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Sun, 12 Apr 2026 08:47:10 +0000 (16:47 +0800)
When adf_dev_up() partially completes and then fails, the IRQ
handlers registered during adf_isr_resource_alloc() are not detached
before the MSI-X vectors are released.

Since the device is enabled with pcim_enable_device(), calling
pci_alloc_irq_vectors() internally registers pcim_msi_release() as a
devres action. On probe failure, devres runs pcim_msi_release() which
calls pci_free_irq_vectors(), tearing down the MSI-X vectors while IRQ
handlers (for example 'qat0-bundle0') are still attached. This causes
remove_proc_entry() warnings:

    [   22.163964] remove_proc_entry: removing non-empty directory 'irq/143', leaking at least 'qat0-bundle0'

Moving the devm_add_action_or_reset() before adf_dev_up() does not solve
the problem since devres runs in LIFO order and pcim_msi_release(),
registered later inside adf_dev_up(), would still fire before
adf_device_down().

Fix by calling adf_dev_down() explicitly when adf_dev_up() fails, to
properly free IRQ handlers before devres releases the MSI-X vectors.

Fixes: 17fd7514ae68 ("crypto: qat - add qat_6xxx driver")
Cc: stable@vger.kernel.org
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Ahsan Atta <ahsan.atta@intel.com>
Reviewed-by: Laurent M Coquerel <laurent.m.coquerel@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/intel/qat/qat_6xxx/adf_drv.c

index 0684ea9be2ac53443ea63f903c3039de70d17611..c52462a48c340e6a7dc5a528d816122a88c3b291 100644 (file)
@@ -209,8 +209,10 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                return ret;
 
        ret = adf_dev_up(accel_dev, true);
-       if (ret)
+       if (ret) {
+               adf_dev_down(accel_dev);
                return ret;
+       }
 
        ret = devm_add_action_or_reset(dev, adf_device_down, accel_dev);
        if (ret)