Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: bnx2fc: Avoid using get_cpu() in bnx2fc_cmd_alloc()

Using get_cpu() leads to disabling preemption and in this context it is not
possible to acquire the following spinlock_t on PREEMPT_RT because it
becomes a sleeping lock.

Commit 0ea5c27583e1 ("[SCSI] bnx2fc: common free list for cleanup
commands") says that it is using get_cpu() as a fix in case the CPU is
preempted. While this might be true, the important part is that it is now
using the same CPU for locking and unlocking while previously it always
relied on smp_processor_id(). The date structure itself is protected with
a lock so it does not rely on CPU-local access.

Replace get_cpu() with raw_smp_processor_id() to obtain the current CPU
number which is used as an index for the per-CPU resource.

Link: https://lore.kernel.org/r/20220506105758.283887-5-bigeasy@linutronix.de
Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Sebastian Andrzej Siewior and committed by
Martin K. Petersen
20f8932f a0548edf

+1 -3
+1 -3
drivers/scsi/bnx2fc/bnx2fc_io.c
··· 472 472 u32 free_sqes; 473 473 u32 max_sqes; 474 474 u16 xid; 475 - int index = get_cpu(); 475 + int index = raw_smp_processor_id(); 476 476 477 477 max_sqes = BNX2FC_SCSI_MAX_SQES; 478 478 /* ··· 485 485 (tgt->num_active_ios.counter >= max_sqes) || 486 486 (free_sqes + max_sqes <= BNX2FC_SQ_WQES_MAX)) { 487 487 spin_unlock_bh(&cmd_mgr->free_list_lock[index]); 488 - put_cpu(); 489 488 return NULL; 490 489 } 491 490 ··· 497 498 atomic_inc(&tgt->num_active_ios); 498 499 atomic_dec(&tgt->free_sqes); 499 500 spin_unlock_bh(&cmd_mgr->free_list_lock[index]); 500 - put_cpu(); 501 501 502 502 INIT_LIST_HEAD(&io_req->link); 503 503