| 944 | } |
| 945 | |
| 946 | static int |
| 947 | intr_event_schedule_thread(struct intr_event *ie) |
| 948 | { |
| 949 | struct intr_entropy entropy; |
| 950 | struct intr_thread *it; |
| 951 | struct thread *td; |
| 952 | struct thread *ctd; |
| 953 | |
| 954 | /* |
| 955 | * If no ithread or no handlers, then we have a stray interrupt. |
| 956 | */ |
| 957 | if (ie == NULL || CK_SLIST_EMPTY(&ie->ie_handlers) || |
| 958 | ie->ie_thread == NULL) |
| 959 | return (EINVAL); |
| 960 | |
| 961 | ctd = curthread; |
| 962 | it = ie->ie_thread; |
| 963 | td = it->it_thread; |
| 964 | |
| 965 | /* |
| 966 | * If any of the handlers for this ithread claim to be good |
| 967 | * sources of entropy, then gather some. |
| 968 | */ |
| 969 | if (ie->ie_hflags & IH_ENTROPY) { |
| 970 | entropy.event = (uintptr_t)ie; |
| 971 | entropy.td = ctd; |
| 972 | random_harvest_queue(&entropy, sizeof(entropy), RANDOM_INTERRUPT); |
| 973 | } |
| 974 | |
| 975 | KASSERT(td->td_proc != NULL, ("ithread %s has no process", ie->ie_name)); |
| 976 | |
| 977 | /* |
| 978 | * Set it_need to tell the thread to keep running if it is already |
| 979 | * running. Then, lock the thread and see if we actually need to |
| 980 | * put it on the runqueue. |
| 981 | * |
| 982 | * Use store_rel to arrange that the store to ih_need in |
| 983 | * swi_sched() is before the store to it_need and prepare for |
| 984 | * transfer of this order to loads in the ithread. |
| 985 | */ |
| 986 | atomic_store_rel_int(&it->it_need, 1); |
| 987 | thread_lock(td); |
| 988 | if (TD_AWAITING_INTR(td)) { |
| 989 | CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, td->td_proc->p_pid, |
| 990 | td->td_name); |
| 991 | TD_CLR_IWAIT(td); |
| 992 | sched_add(td, SRQ_INTR); |
| 993 | } else { |
| 994 | CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d", |
| 995 | __func__, td->td_proc->p_pid, td->td_name, it->it_need, td->td_state); |
| 996 | thread_unlock(td); |
| 997 | } |
| 998 | |
| 999 | return (0); |
| 1000 | } |
| 1001 | |
| 1002 | /* |
| 1003 | * Allow interrupt event binding for software interrupt handlers -- a no-op, |
no test coverage detected