[v3,RESEND,3/9] crypto/ycc: Add irq support for ycc kernel rings

Message ID 1667461243-48652-4-git-send-email-guanjun@linux.alibaba.com
State New
Headers
Series Drivers for Alibaba YCC (Yitian Cryptography Complex) cryptographic accelerator |

Commit Message

guanjun Nov. 3, 2022, 7:40 a.m. UTC
  From: Zelin Deng <zelin.deng@linux.alibaba.com>

Each kernel ring has its own command done irq. Temporarily user rings
will not enable irq.

Signed-off-by: Zelin Deng <zelin.deng@linux.alibaba.com>
---
 drivers/crypto/ycc/ycc_isr.c | 92 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 80 insertions(+), 12 deletions(-)
  

Comments

Dan Carpenter Nov. 7, 2022, 7:50 a.m. UTC | #1
Hi 'Guanjun',

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Guanjun/Drivers-for-Alibaba-YCC-Yitian-Cryptography-Complex-cryptographic-accelerator/20221103-154448
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
patch link:    https://lore.kernel.org/r/1667461243-48652-4-git-send-email-guanjun%40linux.alibaba.com
patch subject: [PATCH v3 RESEND 3/9] crypto/ycc: Add irq support for ycc kernel rings
config: ia64-randconfig-m031-20221104
compiler: ia64-linux-gcc (GCC) 12.1.0

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>

smatch warnings:
drivers/crypto/ycc/ycc_isr.c:124 ycc_alloc_irqs() warn: missing error code 'ret'

vim +/ret +124 drivers/crypto/ycc/ycc_isr.c

99da43fc5ee114 Zelin Deng 2022-11-03   98  
99da43fc5ee114 Zelin Deng 2022-11-03   99  int ycc_alloc_irqs(struct ycc_dev *ydev)
99da43fc5ee114 Zelin Deng 2022-11-03  100  {
99da43fc5ee114 Zelin Deng 2022-11-03  101  	struct pci_dev *rcec_pdev = ydev->assoc_dev->pdev;
99da43fc5ee114 Zelin Deng 2022-11-03  102  	int num = ydev->is_vf ? 1 : YCC_RINGPAIR_NUM;
3c2d80e20cfe81 Zelin Deng 2022-11-03  103  	int cpu, cpus = num_online_cpus();
3c2d80e20cfe81 Zelin Deng 2022-11-03  104  	int ret, i, j;
99da43fc5ee114 Zelin Deng 2022-11-03  105  
3c2d80e20cfe81 Zelin Deng 2022-11-03  106  	/* The 0 - (YCC_RINGPAIR_NUM-1) are rings irqs, the last one is dev error irq */
99da43fc5ee114 Zelin Deng 2022-11-03  107  	sprintf(ydev->err_irq_name, "ycc_dev_%d_global_err", ydev->id);
99da43fc5ee114 Zelin Deng 2022-11-03  108  	ret = request_irq(pci_irq_vector(rcec_pdev, num),
99da43fc5ee114 Zelin Deng 2022-11-03  109  			  ycc_g_err_isr, 0, ydev->err_irq_name, ydev);
3c2d80e20cfe81 Zelin Deng 2022-11-03  110  	if (ret) {
99da43fc5ee114 Zelin Deng 2022-11-03  111  		pr_err("Failed to alloc global irq interrupt for dev: %d\n", ydev->id);
3c2d80e20cfe81 Zelin Deng 2022-11-03  112  		goto out;
3c2d80e20cfe81 Zelin Deng 2022-11-03  113  	}
3c2d80e20cfe81 Zelin Deng 2022-11-03  114  
3c2d80e20cfe81 Zelin Deng 2022-11-03  115  	if (ydev->is_polling)
3c2d80e20cfe81 Zelin Deng 2022-11-03  116  		goto out;
3c2d80e20cfe81 Zelin Deng 2022-11-03  117  
3c2d80e20cfe81 Zelin Deng 2022-11-03  118  	for (i = 0; i < num; i++) {
3c2d80e20cfe81 Zelin Deng 2022-11-03  119  		if (ydev->rings[i].type != KERN_RING)
3c2d80e20cfe81 Zelin Deng 2022-11-03  120  			continue;
3c2d80e20cfe81 Zelin Deng 2022-11-03  121  
3c2d80e20cfe81 Zelin Deng 2022-11-03  122  		ydev->msi_name[i] = kzalloc(16, GFP_KERNEL);
3c2d80e20cfe81 Zelin Deng 2022-11-03  123  		if (!ydev->msi_name[i])
3c2d80e20cfe81 Zelin Deng 2022-11-03 @124  			goto free_irq;

ret = -ENOMEM;

3c2d80e20cfe81 Zelin Deng 2022-11-03  125  		snprintf(ydev->msi_name[i], 16, "ycc_ring_%d", i);
3c2d80e20cfe81 Zelin Deng 2022-11-03  126  		ret = request_irq(pci_irq_vector(rcec_pdev, i), ycc_resp_isr,
3c2d80e20cfe81 Zelin Deng 2022-11-03  127  				  0, ydev->msi_name[i], &ydev->rings[i]);
3c2d80e20cfe81 Zelin Deng 2022-11-03  128  		if (ret) {
3c2d80e20cfe81 Zelin Deng 2022-11-03  129  			kfree(ydev->msi_name[i]);
3c2d80e20cfe81 Zelin Deng 2022-11-03  130  			goto free_irq;
3c2d80e20cfe81 Zelin Deng 2022-11-03  131  		}
3c2d80e20cfe81 Zelin Deng 2022-11-03  132  		if (!ydev->is_vf)
3c2d80e20cfe81 Zelin Deng 2022-11-03  133  			cpu = (i % YCC_RINGPAIR_NUM) % cpus;
3c2d80e20cfe81 Zelin Deng 2022-11-03  134  		else
3c2d80e20cfe81 Zelin Deng 2022-11-03  135  			cpu = smp_processor_id() % cpus;
3c2d80e20cfe81 Zelin Deng 2022-11-03  136  
3c2d80e20cfe81 Zelin Deng 2022-11-03  137  		ret = irq_set_affinity_hint(pci_irq_vector(rcec_pdev, i),
3c2d80e20cfe81 Zelin Deng 2022-11-03  138  					    get_cpu_mask(cpu));
3c2d80e20cfe81 Zelin Deng 2022-11-03  139  		if (ret) {
3c2d80e20cfe81 Zelin Deng 2022-11-03  140  			free_irq(pci_irq_vector(rcec_pdev, i), &ydev->rings[i]);
3c2d80e20cfe81 Zelin Deng 2022-11-03  141  			kfree(ydev->msi_name[i]);
3c2d80e20cfe81 Zelin Deng 2022-11-03  142  			goto free_irq;
3c2d80e20cfe81 Zelin Deng 2022-11-03  143  		}
3c2d80e20cfe81 Zelin Deng 2022-11-03  144  	}
3c2d80e20cfe81 Zelin Deng 2022-11-03  145  
3c2d80e20cfe81 Zelin Deng 2022-11-03  146  	return 0;
3c2d80e20cfe81 Zelin Deng 2022-11-03  147  
3c2d80e20cfe81 Zelin Deng 2022-11-03  148  free_irq:
3c2d80e20cfe81 Zelin Deng 2022-11-03  149  	for (j = 0; j < i; j++) {
3c2d80e20cfe81 Zelin Deng 2022-11-03  150  		if (ydev->rings[i].type != KERN_RING)
3c2d80e20cfe81 Zelin Deng 2022-11-03  151  			continue;
3c2d80e20cfe81 Zelin Deng 2022-11-03  152  
3c2d80e20cfe81 Zelin Deng 2022-11-03  153  		free_irq(pci_irq_vector(rcec_pdev, j), &ydev->rings[j]);
3c2d80e20cfe81 Zelin Deng 2022-11-03  154  		kfree(ydev->msi_name[j]);
3c2d80e20cfe81 Zelin Deng 2022-11-03  155  	}
3c2d80e20cfe81 Zelin Deng 2022-11-03  156  	free_irq(pci_irq_vector(rcec_pdev, num), ydev);
3c2d80e20cfe81 Zelin Deng 2022-11-03  157  out:
99da43fc5ee114 Zelin Deng 2022-11-03  158  
99da43fc5ee114 Zelin Deng 2022-11-03  159  	return ret;
99da43fc5ee114 Zelin Deng 2022-11-03  160  }
  
kernel test robot Nov. 10, 2022, 1:28 a.m. UTC | #2
Hi 'Guanjun',

Thank you for the patch! Yet something to improve:

[auto build test ERROR on herbert-cryptodev-2.6/master]
[also build test ERROR on herbert-crypto-2.6/master linus/master v6.1-rc4 next-20221109]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Guanjun/Drivers-for-Alibaba-YCC-Yitian-Cryptography-Complex-cryptographic-accelerator/20221103-154448
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
patch link:    https://lore.kernel.org/r/1667461243-48652-4-git-send-email-guanjun%40linux.alibaba.com
patch subject: [PATCH v3 RESEND 3/9] crypto/ycc: Add irq support for ycc kernel rings
config: xtensa-allyesconfig
compiler: xtensa-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/3c2d80e20cfe81c871c54ee09dd7d8f64477f9fe
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Guanjun/Drivers-for-Alibaba-YCC-Yitian-Cryptography-Complex-cryptographic-accelerator/20221103-154448
        git checkout 3c2d80e20cfe81c871c54ee09dd7d8f64477f9fe
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=xtensa SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from include/linux/pgtable.h:6,
                    from include/linux/kasan.h:33,
                    from include/linux/slab.h:148,
                    from include/linux/irq.h:21,
                    from include/asm-generic/hardirq.h:17,
                    from ./arch/xtensa/include/generated/asm/hardirq.h:1,
                    from include/linux/hardirq.h:11,
                    from include/linux/interrupt.h:11,
                    from include/linux/pci.h:38,
                    from drivers/crypto/ycc/ycc_isr.c:8:
   arch/xtensa/include/asm/pgtable.h:20:33: error: expected identifier before numeric constant
      20 | #define USER_RING               1       /* user ring level */
         |                                 ^
   drivers/crypto/ycc/ycc_ring.h:25:9: note: in expansion of macro 'USER_RING'
      25 |         USER_RING,
         |         ^~~~~~~~~
   drivers/crypto/ycc/ycc_isr.c: In function 'ycc_alloc_irqs':
>> drivers/crypto/ycc/ycc_isr.c:119:44: error: 'KERN_RING' undeclared (first use in this function); did you mean 'KERNEL_RING'?
     119 |                 if (ydev->rings[i].type != KERN_RING)
         |                                            ^~~~~~~~~
         |                                            KERNEL_RING
   drivers/crypto/ycc/ycc_isr.c:119:44: note: each undeclared identifier is reported only once for each function it appears in
   drivers/crypto/ycc/ycc_isr.c: In function 'ycc_free_irqs':
   drivers/crypto/ycc/ycc_isr.c:175:44: error: 'KERN_RING' undeclared (first use in this function); did you mean 'KERNEL_RING'?
     175 |                 if (ydev->rings[i].type != KERN_RING)
         |                                            ^~~~~~~~~
         |                                            KERNEL_RING


vim +119 drivers/crypto/ycc/ycc_isr.c

    98	
    99	int ycc_alloc_irqs(struct ycc_dev *ydev)
   100	{
   101		struct pci_dev *rcec_pdev = ydev->assoc_dev->pdev;
   102		int num = ydev->is_vf ? 1 : YCC_RINGPAIR_NUM;
   103		int cpu, cpus = num_online_cpus();
   104		int ret, i, j;
   105	
   106		/* The 0 - (YCC_RINGPAIR_NUM-1) are rings irqs, the last one is dev error irq */
   107		sprintf(ydev->err_irq_name, "ycc_dev_%d_global_err", ydev->id);
   108		ret = request_irq(pci_irq_vector(rcec_pdev, num),
   109				  ycc_g_err_isr, 0, ydev->err_irq_name, ydev);
   110		if (ret) {
   111			pr_err("Failed to alloc global irq interrupt for dev: %d\n", ydev->id);
   112			goto out;
   113		}
   114	
   115		if (ydev->is_polling)
   116			goto out;
   117	
   118		for (i = 0; i < num; i++) {
 > 119			if (ydev->rings[i].type != KERN_RING)
   120				continue;
   121	
   122			ydev->msi_name[i] = kzalloc(16, GFP_KERNEL);
   123			if (!ydev->msi_name[i])
   124				goto free_irq;
   125			snprintf(ydev->msi_name[i], 16, "ycc_ring_%d", i);
   126			ret = request_irq(pci_irq_vector(rcec_pdev, i), ycc_resp_isr,
   127					  0, ydev->msi_name[i], &ydev->rings[i]);
   128			if (ret) {
   129				kfree(ydev->msi_name[i]);
   130				goto free_irq;
   131			}
   132			if (!ydev->is_vf)
   133				cpu = (i % YCC_RINGPAIR_NUM) % cpus;
   134			else
   135				cpu = smp_processor_id() % cpus;
   136	
   137			ret = irq_set_affinity_hint(pci_irq_vector(rcec_pdev, i),
   138						    get_cpu_mask(cpu));
   139			if (ret) {
   140				free_irq(pci_irq_vector(rcec_pdev, i), &ydev->rings[i]);
   141				kfree(ydev->msi_name[i]);
   142				goto free_irq;
   143			}
   144		}
   145	
   146		return 0;
   147	
   148	free_irq:
   149		for (j = 0; j < i; j++) {
   150			if (ydev->rings[i].type != KERN_RING)
   151				continue;
   152	
   153			free_irq(pci_irq_vector(rcec_pdev, j), &ydev->rings[j]);
   154			kfree(ydev->msi_name[j]);
   155		}
   156		free_irq(pci_irq_vector(rcec_pdev, num), ydev);
   157	out:
   158	
   159		return ret;
   160	}
   161
  

Patch

diff --git a/drivers/crypto/ycc/ycc_isr.c b/drivers/crypto/ycc/ycc_isr.c
index cd2a2d7..a86c8d7 100644
--- a/drivers/crypto/ycc/ycc_isr.c
+++ b/drivers/crypto/ycc/ycc_isr.c
@@ -12,6 +12,17 @@ 
 #include <linux/interrupt.h>
 
 #include "ycc_isr.h"
+#include "ycc_dev.h"
+#include "ycc_ring.h"
+
+
+static irqreturn_t ycc_resp_isr(int irq, void *data)
+{
+	struct ycc_ring *ring = (struct ycc_ring *)data;
+
+	tasklet_hi_schedule(&ring->resp_handler);
+	return IRQ_HANDLED;
+}
 
 /*
  * TODO: will implement when ycc ring actually work.
@@ -38,11 +49,13 @@  static irqreturn_t ycc_g_err_isr(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-/*
- * TODO: will implement when ycc ring actually work.
- */
 void ycc_resp_process(uintptr_t ring_addr)
 {
+	struct ycc_ring *ring = (struct ycc_ring *)ring_addr;
+
+	ycc_dequeue(ring);
+	if (ring->ydev->is_polling)
+		tasklet_hi_schedule(&ring->resp_handler);
 }
 
 int ycc_enable_msix(struct ycc_dev *ydev)
@@ -83,34 +96,89 @@  static void ycc_cleanup_global_err_workqueue(struct ycc_dev *ydev)
 		destroy_workqueue(ydev->dev_err_q);
 }
 
-/*
- * TODO: Just request irq for global err. Irq for each ring
- * will be requested when ring actually work.
- */
 int ycc_alloc_irqs(struct ycc_dev *ydev)
 {
 	struct pci_dev *rcec_pdev = ydev->assoc_dev->pdev;
 	int num = ydev->is_vf ? 1 : YCC_RINGPAIR_NUM;
-	int ret;
+	int cpu, cpus = num_online_cpus();
+	int ret, i, j;
 
+	/* The 0 - (YCC_RINGPAIR_NUM-1) are rings irqs, the last one is dev error irq */
 	sprintf(ydev->err_irq_name, "ycc_dev_%d_global_err", ydev->id);
 	ret = request_irq(pci_irq_vector(rcec_pdev, num),
 			  ycc_g_err_isr, 0, ydev->err_irq_name, ydev);
-	if (ret)
+	if (ret) {
 		pr_err("Failed to alloc global irq interrupt for dev: %d\n", ydev->id);
+		goto out;
+	}
+
+	if (ydev->is_polling)
+		goto out;
+
+	for (i = 0; i < num; i++) {
+		if (ydev->rings[i].type != KERN_RING)
+			continue;
+
+		ydev->msi_name[i] = kzalloc(16, GFP_KERNEL);
+		if (!ydev->msi_name[i])
+			goto free_irq;
+		snprintf(ydev->msi_name[i], 16, "ycc_ring_%d", i);
+		ret = request_irq(pci_irq_vector(rcec_pdev, i), ycc_resp_isr,
+				  0, ydev->msi_name[i], &ydev->rings[i]);
+		if (ret) {
+			kfree(ydev->msi_name[i]);
+			goto free_irq;
+		}
+		if (!ydev->is_vf)
+			cpu = (i % YCC_RINGPAIR_NUM) % cpus;
+		else
+			cpu = smp_processor_id() % cpus;
+
+		ret = irq_set_affinity_hint(pci_irq_vector(rcec_pdev, i),
+					    get_cpu_mask(cpu));
+		if (ret) {
+			free_irq(pci_irq_vector(rcec_pdev, i), &ydev->rings[i]);
+			kfree(ydev->msi_name[i]);
+			goto free_irq;
+		}
+	}
+
+	return 0;
+
+free_irq:
+	for (j = 0; j < i; j++) {
+		if (ydev->rings[i].type != KERN_RING)
+			continue;
+
+		free_irq(pci_irq_vector(rcec_pdev, j), &ydev->rings[j]);
+		kfree(ydev->msi_name[j]);
+	}
+	free_irq(pci_irq_vector(rcec_pdev, num), ydev);
+out:
 
 	return ret;
 }
 
-/*
- * TODO: Same as the allocate action.
- */
 void ycc_free_irqs(struct ycc_dev *ydev)
 {
 	struct pci_dev *rcec_pdev = ydev->assoc_dev->pdev;
 	int num = ydev->is_vf ? 1 : YCC_RINGPAIR_NUM;
+	int i;
 
+	/* Free device err irq */
 	free_irq(pci_irq_vector(rcec_pdev, num), ydev);
+
+	if (ydev->is_polling)
+		return;
+
+	for (i = 0; i < num; i++) {
+		if (ydev->rings[i].type != KERN_RING)
+			continue;
+
+		irq_set_affinity_hint(pci_irq_vector(rcec_pdev, i), NULL);
+		free_irq(pci_irq_vector(rcec_pdev, i), &ydev->rings[i]);
+		kfree(ydev->msi_name[i]);
+	}
 }
 
 int ycc_init_global_err(struct ycc_dev *ydev)