History

sched: Unbreak wakeups

Remove broken task->state references and let wake_up_process() DTRT. The anti-pattern in these patches breaks the ordering of ->state vs COND as described in the comment near set_current_state() and can lead to missed wakeups: (OoO load, observes RUNNING)<-. for (;;) { | t->state = UNINTERRUPTIBLE; | smp_mb(); ,-----> | (observes !COND) | / if (COND) ---------' | COND = 1; break; `- if (t->state != RUNNING) wake_up_process(t); // not done schedule(); // forever waiting } t->state = TASK_RUNNING;

Peter Zijlstra committed 5 years ago

Commit 37aadc61 parent b2c09314 files · +9 −17Browse files

Unified · Split

4 files
  1. drivers/net/ethernet/qualcomm/qca_spi.c +2 −4
  2. drivers/usb/gadget/udc/max3420_udc.c +5 −10
  3. drivers/usb/host/max3421-hcd.c +1 −2
  4. kernel/softirq.c +1 −1
drivers/net/ethernet/qualcomm/qca_spi.c+2−4
@@ -653,8 +653,7 @@ qcaspi_intr_handler(int irq, void *data) · 652 unmodified lines
653 struct qcaspi *qca = data;653 struct qcaspi *qca = data;
654 654
655 qca->intr_req++;655 qca->intr_req++;
656 if (qca->spi_thread &&656 if (qca->spi_thread)
657 qca->spi_thread->state != TASK_RUNNING)
658 wake_up_process(qca->spi_thread);657 wake_up_process(qca->spi_thread);
659 658
660 return IRQ_HANDLED;659 return IRQ_HANDLED;
@@ -777,8 +776,7 @@ qcaspi_netdev_xmit(struct sk_buff *skb, struct net_device *dev) · 116 unmodified lines
777 776
778 netif_trans_update(dev);777 netif_trans_update(dev);
779 778
780 if (qca->spi_thread &&779 if (qca->spi_thread)
781 qca->spi_thread->state != TASK_RUNNING)
782 wake_up_process(qca->spi_thread);780 wake_up_process(qca->spi_thread);
783 781
784 return NETDEV_TX_OK;782 return NETDEV_TX_OK;
drivers/usb/gadget/udc/max3420_udc.c+5−10
@@ -509,8 +509,7 @@ static irqreturn_t max3420_vbus_handler(int irq, void *dev_id) · 508 unmodified lines
509 ? USB_STATE_POWERED : USB_STATE_NOTATTACHED);509 ? USB_STATE_POWERED : USB_STATE_NOTATTACHED);
510 spin_unlock_irqrestore(&udc->lock, flags);510 spin_unlock_irqrestore(&udc->lock, flags);
511 511
512 if (udc->thread_task &&512 if (udc->thread_task)
513 udc->thread_task->state != TASK_RUNNING)
514 wake_up_process(udc->thread_task);513 wake_up_process(udc->thread_task);
515 514
516 return IRQ_HANDLED;515 return IRQ_HANDLED;
@@ -529,8 +528,7 @@ static irqreturn_t max3420_irq_handler(int irq, void *dev_id) · 12 unmodified lines
529 }528 }
530 spin_unlock_irqrestore(&udc->lock, flags);529 spin_unlock_irqrestore(&udc->lock, flags);
531 530
532 if (udc->thread_task &&531 if (udc->thread_task)
533 udc->thread_task->state != TASK_RUNNING)
534 wake_up_process(udc->thread_task);532 wake_up_process(udc->thread_task);
535 533
536 return IRQ_HANDLED;534 return IRQ_HANDLED;
@@ -1093,8 +1091,7 @@ static int max3420_wakeup(struct usb_gadget *gadget) · 556 unmodified lines
1093 1091
1094 spin_unlock_irqrestore(&udc->lock, flags);1092 spin_unlock_irqrestore(&udc->lock, flags);
1095 1093
1096 if (udc->thread_task &&1094 if (udc->thread_task)
1097 udc->thread_task->state != TASK_RUNNING)
1098 wake_up_process(udc->thread_task);1095 wake_up_process(udc->thread_task);
1099 return ret;1096 return ret;
1100}1097}
@@ -1117,8 +1114,7 @@ static int max3420_udc_start(struct usb_gadget *gadget, · 16 unmodified lines
1117 udc->todo |= UDC_START;1114 udc->todo |= UDC_START;
1118 spin_unlock_irqrestore(&udc->lock, flags);1115 spin_unlock_irqrestore(&udc->lock, flags);
1119 1116
1120 if (udc->thread_task &&1117 if (udc->thread_task)
1121 udc->thread_task->state != TASK_RUNNING)
1122 wake_up_process(udc->thread_task);1118 wake_up_process(udc->thread_task);
1123 1119
1124 return 0;1120 return 0;
@@ -1137,8 +1133,7 @@ static int max3420_udc_stop(struct usb_gadget *gadget) · 12 unmodified lines
1137 udc->todo |= UDC_START;1133 udc->todo |= UDC_START;
1138 spin_unlock_irqrestore(&udc->lock, flags);1134 spin_unlock_irqrestore(&udc->lock, flags);
1139 1135
1140 if (udc->thread_task &&1136 if (udc->thread_task)
1141 udc->thread_task->state != TASK_RUNNING)
1142 wake_up_process(udc->thread_task);1137 wake_up_process(udc->thread_task);
1143 1138
1144 return 0;1139 return 0;
drivers/usb/host/max3421-hcd.c+1−2
@@ -1169,8 +1169,7 @@ max3421_irq_handler(int irq, void *dev_id) · 1168 unmodified lines
1169 struct spi_device *spi = to_spi_device(hcd->self.controller);1169 struct spi_device *spi = to_spi_device(hcd->self.controller);
1170 struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);1170 struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
1171 1171
1172 if (max3421_hcd->spi_thread &&1172 if (max3421_hcd->spi_thread)
1173 max3421_hcd->spi_thread->state != TASK_RUNNING)
1174 wake_up_process(max3421_hcd->spi_thread);1173 wake_up_process(max3421_hcd->spi_thread);
1175 if (!test_and_set_bit(ENABLE_IRQ, &max3421_hcd->todo))1174 if (!test_and_set_bit(ENABLE_IRQ, &max3421_hcd->todo))
1176 disable_irq_nosync(spi->irq);1175 disable_irq_nosync(spi->irq);
kernel/softirq.c+1−1
@@ -76,7 +76,7 @@ static void wakeup_softirqd(void) · 75 unmodified lines
76 /* Interrupts are disabled: no need to stop preemption */76 /* Interrupts are disabled: no need to stop preemption */
77 struct task_struct *tsk = __this_cpu_read(ksoftirqd);77 struct task_struct *tsk = __this_cpu_read(ksoftirqd);
78 78
79 if (tsk && tsk->state != TASK_RUNNING)79 if (tsk)
80 wake_up_process(tsk);80 wake_up_process(tsk);
81}81}
82 82

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t