[v3,RESEND,3/9] crypto/ycc: Add irq support for ycc kernel rings
Commit Message
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
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 }
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
@@ -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)