drivers/dma/idxd/device.c:370 idxd_cmd_exec() warn: mixing irqsave and irq

From: Dan Carpenter
Date: Thu Dec 05 2024 - 02:53:42 EST


tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: feffde684ac29a3b7aec82d2df850fbdbdee55e4
commit: 0d5c10b4c84d6ae6255129e5f16a0d2119c74334 dmaengine: idxd: add work queue drain support
config: x86_64-randconfig-161-20241112 (https://download.01.org/0day-ci/archive/20241205/202412050237.MXIHJMPC-lkp@xxxxxxxxx/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@xxxxxxxxx>
| Reported-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx>
| Closes: https://lore.kernel.org/r/202412050237.MXIHJMPC-lkp@xxxxxxxxx/

smatch warnings:
drivers/dma/idxd/device.c:370 idxd_cmd_exec() warn: mixing irqsave and irq

vim +370 drivers/dma/idxd/device.c

0d5c10b4c84d6a Dave Jiang 2020-06-26 357 static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand,
0d5c10b4c84d6a Dave Jiang 2020-06-26 358 u32 *status)
bfe1d56091c1a4 Dave Jiang 2020-01-21 359 {
bfe1d56091c1a4 Dave Jiang 2020-01-21 360 union idxd_command_reg cmd;
0d5c10b4c84d6a Dave Jiang 2020-06-26 361 DECLARE_COMPLETION_ONSTACK(done);
0d5c10b4c84d6a Dave Jiang 2020-06-26 362 unsigned long flags;
bfe1d56091c1a4 Dave Jiang 2020-01-21 363
bfe1d56091c1a4 Dave Jiang 2020-01-21 364 memset(&cmd, 0, sizeof(cmd));
bfe1d56091c1a4 Dave Jiang 2020-01-21 365 cmd.cmd = cmd_code;
bfe1d56091c1a4 Dave Jiang 2020-01-21 366 cmd.operand = operand;
0d5c10b4c84d6a Dave Jiang 2020-06-26 367 cmd.int_req = 1;
0d5c10b4c84d6a Dave Jiang 2020-06-26 368
0d5c10b4c84d6a Dave Jiang 2020-06-26 369 spin_lock_irqsave(&idxd->dev_lock, flags);
0d5c10b4c84d6a Dave Jiang 2020-06-26 @370 wait_event_lock_irq(idxd->cmd_waitq,
0d5c10b4c84d6a Dave Jiang 2020-06-26 371 !test_bit(IDXD_FLAG_CMD_RUNNING, &idxd->flags),
0d5c10b4c84d6a Dave Jiang 2020-06-26 372 idxd->dev_lock);

Please understand that these emails complaining about ancient code are
from the zero day bot, not from me. The issue here is that
using spin_lock_irqsave() implies that perhaps the caller disabled IRQs
but then the wait_event_lock_irq() macro enables IRQs when it is
finished.

0d5c10b4c84d6a Dave Jiang 2020-06-26 373
bfe1d56091c1a4 Dave Jiang 2020-01-21 374 dev_dbg(&idxd->pdev->dev, "%s: sending cmd: %#x op: %#x\n",
bfe1d56091c1a4 Dave Jiang 2020-01-21 375 __func__, cmd_code, operand);
0d5c10b4c84d6a Dave Jiang 2020-06-26 376
0d5c10b4c84d6a Dave Jiang 2020-06-26 377 __set_bit(IDXD_FLAG_CMD_RUNNING, &idxd->flags);
0d5c10b4c84d6a Dave Jiang 2020-06-26 378 idxd->cmd_done = &done;
bfe1d56091c1a4 Dave Jiang 2020-01-21 379 iowrite32(cmd.bits, idxd->reg_base + IDXD_CMD_OFFSET);
bfe1d56091c1a4 Dave Jiang 2020-01-21 380
0d5c10b4c84d6a Dave Jiang 2020-06-26 381 /*
0d5c10b4c84d6a Dave Jiang 2020-06-26 382 * After command submitted, release lock and go to sleep until
0d5c10b4c84d6a Dave Jiang 2020-06-26 383 * the command completes via interrupt.
0d5c10b4c84d6a Dave Jiang 2020-06-26 384 */
0d5c10b4c84d6a Dave Jiang 2020-06-26 385 spin_unlock_irqrestore(&idxd->dev_lock, flags);

This irqrestore sets the IRQs back to whatever they were when the function
was called.

0d5c10b4c84d6a Dave Jiang 2020-06-26 386 wait_for_completion(&done);
0d5c10b4c84d6a Dave Jiang 2020-06-26 387 spin_lock_irqsave(&idxd->dev_lock, flags);
0d5c10b4c84d6a Dave Jiang 2020-06-26 388 if (status)
0d5c10b4c84d6a Dave Jiang 2020-06-26 389 *status = ioread32(idxd->reg_base + IDXD_CMDSTS_OFFSET);
0d5c10b4c84d6a Dave Jiang 2020-06-26 390 __clear_bit(IDXD_FLAG_CMD_RUNNING, &idxd->flags);
0d5c10b4c84d6a Dave Jiang 2020-06-26 391 /* Wake up other pending commands */
0d5c10b4c84d6a Dave Jiang 2020-06-26 392 wake_up(&idxd->cmd_waitq);
0d5c10b4c84d6a Dave Jiang 2020-06-26 393 spin_unlock_irqrestore(&idxd->dev_lock, flags);
bfe1d56091c1a4 Dave Jiang 2020-01-21 394 }

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki