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
653653 struct qcaspi *qca = data;
654654
655655 qca->intr_req++;
656− if (qca->spi_thread &&
657− qca->spi_thread->state != TASK_RUNNING)
656+ if (qca->spi_thread)
658657 wake_up_process(qca->spi_thread);
659658
660659 return IRQ_HANDLED;
@@ -777,8 +776,7 @@ qcaspi_netdev_xmit(struct sk_buff *skb, struct net_device *dev) · 116 unmodified lines
777776
778777 netif_trans_update(dev);
779778
780− if (qca->spi_thread &&
781− qca->spi_thread->state != TASK_RUNNING)
779+ if (qca->spi_thread)
782780 wake_up_process(qca->spi_thread);
783781
784782 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
509509 ? USB_STATE_POWERED : USB_STATE_NOTATTACHED);
510510 spin_unlock_irqrestore(&udc->lock, flags);
511511
512− if (udc->thread_task &&
513− udc->thread_task->state != TASK_RUNNING)
512+ if (udc->thread_task)
514513 wake_up_process(udc->thread_task);
515514
516515 return IRQ_HANDLED;
@@ -529,8 +528,7 @@ static irqreturn_t max3420_irq_handler(int irq, void *dev_id) · 12 unmodified lines
529528 }
530529 spin_unlock_irqrestore(&udc->lock, flags);
531530
532− if (udc->thread_task &&
533− udc->thread_task->state != TASK_RUNNING)
531+ if (udc->thread_task)
534532 wake_up_process(udc->thread_task);
535533
536534 return IRQ_HANDLED;
@@ -1093,8 +1091,7 @@ static int max3420_wakeup(struct usb_gadget *gadget) · 556 unmodified lines
10931091
10941092 spin_unlock_irqrestore(&udc->lock, flags);
10951093
1096− if (udc->thread_task &&
1097− udc->thread_task->state != TASK_RUNNING)
1094+ if (udc->thread_task)
10981095 wake_up_process(udc->thread_task);
10991096 return ret;
11001097 }
@@ -1117,8 +1114,7 @@ static int max3420_udc_start(struct usb_gadget *gadget, · 16 unmodified lines
11171114 udc->todo |= UDC_START;
11181115 spin_unlock_irqrestore(&udc->lock, flags);
11191116
1120− if (udc->thread_task &&
1121− udc->thread_task->state != TASK_RUNNING)
1117+ if (udc->thread_task)
11221118 wake_up_process(udc->thread_task);
11231119
11241120 return 0;
@@ -1137,8 +1133,7 @@ static int max3420_udc_stop(struct usb_gadget *gadget) · 12 unmodified lines
11371133 udc->todo |= UDC_START;
11381134 spin_unlock_irqrestore(&udc->lock, flags);
11391135
1140− if (udc->thread_task &&
1141− udc->thread_task->state != TASK_RUNNING)
1136+ if (udc->thread_task)
11421137 wake_up_process(udc->thread_task);
11431138
11441139 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
11691169 struct spi_device *spi = to_spi_device(hcd->self.controller);
11701170 struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd);
11711171
1172− if (max3421_hcd->spi_thread &&
1173− max3421_hcd->spi_thread->state != TASK_RUNNING)
1172+ if (max3421_hcd->spi_thread)
11741173 wake_up_process(max3421_hcd->spi_thread);
11751174 if (!test_and_set_bit(ENABLE_IRQ, &max3421_hcd->todo))
11761175 disable_irq_nosync(spi->irq);
kernel/softirq.c+1−1
@@ -76,7 +76,7 @@ static void wakeup_softirqd(void) · 75 unmodified lines
7676 /* Interrupts are disabled: no need to stop preemption */
7777 struct task_struct *tsk = __this_cpu_read(ksoftirqd);
7878
79− if (tsk && tsk->state != TASK_RUNNING)
79+ if (tsk)
8080 wake_up_process(tsk);
8181 }
8282

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