Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_intr.c
Show First 20 Lines • Show All 1,321 Lines • ▼ Show 20 Lines | if (ithd->it_flags & IT_DEAD) { | ||||
kthread_exit(); | kthread_exit(); | ||||
} | } | ||||
/* | /* | ||||
* Service interrupts. If another interrupt arrives while | * Service interrupts. If another interrupt arrives while | ||||
* we are running, it will set it_need to note that we | * we are running, it will set it_need to note that we | ||||
* should make another pass. | * should make another pass. | ||||
*/ | */ | ||||
while (atomic_cmpset_int(&ithd->it_need, 1, 0) != 0) { | while (atomic_load_acq_int(&ithd->it_need) != 0) { | ||||
/* | /* | ||||
* This needs a release barrier to make sure | * This might need a full read and write barrier | ||||
* that this write posts before any of the | * to make sure that this write posts before any | ||||
* memory or device accesses in the handlers. | * of the memory or device accesses in the | ||||
* handlers. | |||||
*/ | */ | ||||
atomic_thread_fence_acq_rel(); | atomic_store_rel_int(&ithd->it_need, 0); | ||||
ithread_execute_handlers(p, ie); | ithread_execute_handlers(p, ie); | ||||
} | } | ||||
WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread"); | WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread"); | ||||
mtx_assert(&Giant, MA_NOTOWNED); | mtx_assert(&Giant, MA_NOTOWNED); | ||||
/* | /* | ||||
* Processed all our interrupts. Now get the sched | * Processed all our interrupts. Now get the sched | ||||
* lock. This may take a while and it_need may get | * lock. This may take a while and it_need may get | ||||
* set again, so we have to check it again. | * set again, so we have to check it again. | ||||
*/ | */ | ||||
thread_lock(td); | thread_lock(td); | ||||
if (atomic_load_acq_int(&ithd->it_need) == 0 && | if ((atomic_load_acq_int(&ithd->it_need) == 0) && | ||||
(ithd->it_flags & (IT_DEAD | IT_WAIT)) == 0) { | !(ithd->it_flags & (IT_DEAD | IT_WAIT))) { | ||||
TD_SET_IWAIT(td); | TD_SET_IWAIT(td); | ||||
ie->ie_count = 0; | ie->ie_count = 0; | ||||
mi_switch(SW_VOL | SWT_IWAIT, NULL); | mi_switch(SW_VOL | SWT_IWAIT, NULL); | ||||
} | } | ||||
if (ithd->it_flags & IT_WAIT) { | if (ithd->it_flags & IT_WAIT) { | ||||
wake = 1; | wake = 1; | ||||
ithd->it_flags &= ~IT_WAIT; | ithd->it_flags &= ~IT_WAIT; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | if (ithd->it_flags & IT_DEAD) { | ||||
kthread_exit(); | kthread_exit(); | ||||
} | } | ||||
/* | /* | ||||
* Service interrupts. If another interrupt arrives while | * Service interrupts. If another interrupt arrives while | ||||
* we are running, it will set it_need to note that we | * we are running, it will set it_need to note that we | ||||
* should make another pass. | * should make another pass. | ||||
*/ | */ | ||||
while (atomic_cmpset_int(&ithd->it_need, 1, 0) != 0) { | while (atomic_load_acq_int(&ithd->it_need) != 0) { | ||||
/* | /* | ||||
* This needs a release barrier to make sure | * This might need a full read and write barrier | ||||
* that this write posts before any of the | * to make sure that this write posts before any | ||||
* memory or device accesses in the handlers. | * of the memory or device accesses in the | ||||
* handlers. | |||||
*/ | */ | ||||
atomic_thread_fence_acq_rel(); | atomic_store_rel_int(&ithd->it_need, 0); | ||||
if (priv) | if (priv) | ||||
priv_ithread_execute_handler(p, ih); | priv_ithread_execute_handler(p, ih); | ||||
else | else | ||||
ithread_execute_handlers(p, ie); | ithread_execute_handlers(p, ie); | ||||
} | } | ||||
WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread"); | WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread"); | ||||
mtx_assert(&Giant, MA_NOTOWNED); | mtx_assert(&Giant, MA_NOTOWNED); | ||||
/* | /* | ||||
* Processed all our interrupts. Now get the sched | * Processed all our interrupts. Now get the sched | ||||
* lock. This may take a while and it_need may get | * lock. This may take a while and it_need may get | ||||
* set again, so we have to check it again. | * set again, so we have to check it again. | ||||
*/ | */ | ||||
thread_lock(td); | thread_lock(td); | ||||
if (atomic_load_acq_int(&ithd->it_need) == 0 && | if ((atomic_load_acq_int(&ithd->it_need) == 0) && | ||||
(ithd->it_flags & (IT_DEAD | IT_WAIT)) == 0) { | !(ithd->it_flags & (IT_DEAD | IT_WAIT))) { | ||||
TD_SET_IWAIT(td); | TD_SET_IWAIT(td); | ||||
ie->ie_count = 0; | ie->ie_count = 0; | ||||
mi_switch(SW_VOL | SWT_IWAIT, NULL); | mi_switch(SW_VOL | SWT_IWAIT, NULL); | ||||
} | } | ||||
if (ithd->it_flags & IT_WAIT) { | if (ithd->it_flags & IT_WAIT) { | ||||
wake = 1; | wake = 1; | ||||
ithd->it_flags &= ~IT_WAIT; | ithd->it_flags &= ~IT_WAIT; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 379 Lines • Show Last 20 Lines |