On 2/10/21 2:44 AM, Christoph Hellwig wrote: >> struct se_device *se_dev = se_cmd->se_dev; >> - int cpu = se_cmd->cpuid; >> + int cpu; >> + >> + if (se_cmd->se_cmd_flags & SCF_IGNORE_CPUID_COMPL) >> + cpu = smp_processor_id(); >> + else >> + cpu = se_cmd->cpuid; >> >> target_queue_cmd_work(&se_dev->queues[cpu].cq, se_cmd, cpu, >> target_completion_wq); > > Can't we just use se_cmd->cpuid == WORK_CPU_UNBOUND as the no affinity > indicator, which would remove all branches here. We can't right now because the workqueue_struct does not have the WQ_UNBOUND bit set. __queue_work will then do: /* pwq which will be used unless @work is executing elsewhere */ if (wq->flags & WQ_UNBOUND) { if (req_cpu == WORK_CPU_UNBOUND) cpu = wq_select_unbound_cpu(raw_smp_processor_id()); pwq = unbound_pwq_by_node(wq, cpu_to_node(cpu)); } else { if (req_cpu == WORK_CPU_UNBOUND) cpu = raw_smp_processor_id(); pwq = per_cpu_ptr(wq->cpu_pwqs, cpu); } so even if you pass in WORK_CPU_UNBOUND, it will do raw_smp_processor_id and add the work to the cpu's worker pool. I think if I add in a new tunable to make the workqueue bound or unbound like I mentioned in the other thread then I think it will do what you want for both review comments.