kern_intr.c (75dfc66c1b2b44609e5a7c3e1d6a751be4922689) kern_intr.c (aba10e131fe7a9ea168af9ff9002e95559a2f80b)
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 46 unchanged lines hidden (view full) ---

55#include <sys/smp.h>
56#include <sys/sysctl.h>
57#include <sys/syslog.h>
58#include <sys/unistd.h>
59#include <sys/vmmeter.h>
60#include <machine/atomic.h>
61#include <machine/cpu.h>
62#include <machine/md_var.h>
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 46 unchanged lines hidden (view full) ---

55#include <sys/smp.h>
56#include <sys/sysctl.h>
57#include <sys/syslog.h>
58#include <sys/unistd.h>
59#include <sys/vmmeter.h>
60#include <machine/atomic.h>
61#include <machine/cpu.h>
62#include <machine/md_var.h>
63#include <machine/smp.h>
63#include <machine/stdarg.h>
64#ifdef DDB
65#include <ddb/ddb.h>
66#include <ddb/db_sym.h>
67#endif
68
69/*
70 * Describe an interrupt thread. There is one of these per interrupt event.

--- 9 unchanged lines hidden (view full) ---

80#define IT_DEAD 0x000001 /* Thread is waiting to exit. */
81#define IT_WAIT 0x000002 /* Thread is waiting for completion. */
82
83struct intr_entropy {
84 struct thread *td;
85 uintptr_t event;
86};
87
64#include <machine/stdarg.h>
65#ifdef DDB
66#include <ddb/ddb.h>
67#include <ddb/db_sym.h>
68#endif
69
70/*
71 * Describe an interrupt thread. There is one of these per interrupt event.

--- 9 unchanged lines hidden (view full) ---

81#define IT_DEAD 0x000001 /* Thread is waiting to exit. */
82#define IT_WAIT 0x000002 /* Thread is waiting for completion. */
83
84struct intr_entropy {
85 struct thread *td;
86 uintptr_t event;
87};
88
89struct intr_event *clk_intr_event;
88struct intr_event *tty_intr_event;
89void *vm_ih;
90struct proc *intrproc;
91
92static MALLOC_DEFINE(M_ITHREAD, "ithread", "Interrupt Threads");
93
94static int intr_storm_threshold = 0;
95SYSCTL_INT(_hw, OID_AUTO, intr_storm_threshold, CTLFLAG_RWTUN,

--- 917 unchanged lines hidden (view full) ---

1013 * Add a software interrupt handler to a specified event. If a given event
1014 * is not specified, then a new event is created.
1015 */
1016int
1017swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler,
1018 void *arg, int pri, enum intr_type flags, void **cookiep)
1019{
1020 struct intr_event *ie;
90struct intr_event *tty_intr_event;
91void *vm_ih;
92struct proc *intrproc;
93
94static MALLOC_DEFINE(M_ITHREAD, "ithread", "Interrupt Threads");
95
96static int intr_storm_threshold = 0;
97SYSCTL_INT(_hw, OID_AUTO, intr_storm_threshold, CTLFLAG_RWTUN,

--- 917 unchanged lines hidden (view full) ---

1015 * Add a software interrupt handler to a specified event. If a given event
1016 * is not specified, then a new event is created.
1017 */
1018int
1019swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler,
1020 void *arg, int pri, enum intr_type flags, void **cookiep)
1021{
1022 struct intr_event *ie;
1021 int error;
1023 int error = 0;
1022
1023 if (flags & INTR_ENTROPY)
1024 return (EINVAL);
1025
1026 ie = (eventp != NULL) ? *eventp : NULL;
1027
1028 if (ie != NULL) {
1029 if (!(ie->ie_flags & IE_SOFT))
1030 return (EINVAL);
1031 } else {
1032 error = intr_event_create(&ie, NULL, IE_SOFT, 0,
1033 NULL, NULL, NULL, swi_assign_cpu, "swi%d:", pri);
1034 if (error)
1035 return (error);
1036 if (eventp != NULL)
1037 *eventp = ie;
1038 }
1024
1025 if (flags & INTR_ENTROPY)
1026 return (EINVAL);
1027
1028 ie = (eventp != NULL) ? *eventp : NULL;
1029
1030 if (ie != NULL) {
1031 if (!(ie->ie_flags & IE_SOFT))
1032 return (EINVAL);
1033 } else {
1034 error = intr_event_create(&ie, NULL, IE_SOFT, 0,
1035 NULL, NULL, NULL, swi_assign_cpu, "swi%d:", pri);
1036 if (error)
1037 return (error);
1038 if (eventp != NULL)
1039 *eventp = ie;
1040 }
1039 error = intr_event_add_handler(ie, name, NULL, handler, arg,
1040 PI_SWI(pri), flags, cookiep);
1041 if (handler != NULL) {
1042 error = intr_event_add_handler(ie, name, NULL, handler, arg,
1043 PI_SWI(pri), flags, cookiep);
1044 }
1041 return (error);
1042}
1043
1044/*
1045 * Schedule a software interrupt thread.
1046 */
1047void
1048swi_sched(void *cookie, int flags)
1049{
1050 struct intr_handler *ih = (struct intr_handler *)cookie;
1051 struct intr_event *ie = ih->ih_event;
1052 struct intr_entropy entropy;
1053 int error __unused;
1054
1055 CTR3(KTR_INTR, "swi_sched: %s %s need=%d", ie->ie_name, ih->ih_name,
1056 ih->ih_need);
1057
1045 return (error);
1046}
1047
1048/*
1049 * Schedule a software interrupt thread.
1050 */
1051void
1052swi_sched(void *cookie, int flags)
1053{
1054 struct intr_handler *ih = (struct intr_handler *)cookie;
1055 struct intr_event *ie = ih->ih_event;
1056 struct intr_entropy entropy;
1057 int error __unused;
1058
1059 CTR3(KTR_INTR, "swi_sched: %s %s need=%d", ie->ie_name, ih->ih_name,
1060 ih->ih_need);
1061
1058 entropy.event = (uintptr_t)ih;
1059 entropy.td = curthread;
1060 random_harvest_queue(&entropy, sizeof(entropy), RANDOM_SWI);
1062 if ((flags & SWI_FROMNMI) == 0) {
1063 entropy.event = (uintptr_t)ih;
1064 entropy.td = curthread;
1065 random_harvest_queue(&entropy, sizeof(entropy), RANDOM_SWI);
1066 }
1061
1062 /*
1063 * Set ih_need for this handler so that if the ithread is already
1064 * running it will execute this handler on the next pass. Otherwise,
1065 * it will execute it the next time it runs.
1066 */
1067 ih->ih_need = 1;
1068
1067
1068 /*
1069 * Set ih_need for this handler so that if the ithread is already
1070 * running it will execute this handler on the next pass. Otherwise,
1071 * it will execute it the next time it runs.
1072 */
1073 ih->ih_need = 1;
1074
1069 if (!(flags & SWI_DELAY)) {
1075 if (flags & SWI_DELAY)
1076 return;
1077
1078 if (flags & SWI_FROMNMI) {
1079#if defined(SMP) && (defined(__i386__) || defined(__amd64__))
1080 KASSERT(ie == clk_intr_event,
1081 ("SWI_FROMNMI used not with clk_intr_event"));
1082 ipi_self_from_nmi(IPI_SWI);
1083#endif
1084 } else {
1070 VM_CNT_INC(v_soft);
1071 error = intr_event_schedule_thread(ie);
1072 KASSERT(error == 0, ("stray software interrupt"));
1073 }
1074}
1075
1076/*
1077 * Remove a software interrupt handler. Currently this code does not

--- 263 unchanged lines hidden (view full) ---

1341 * This fence is required to ensure that no later loads are
1342 * re-ordered before the ie_active store.
1343 */
1344 atomic_thread_fence_seq_cst();
1345
1346 CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) {
1347 if ((ih->ih_flags & IH_SUSP) != 0)
1348 continue;
1085 VM_CNT_INC(v_soft);
1086 error = intr_event_schedule_thread(ie);
1087 KASSERT(error == 0, ("stray software interrupt"));
1088 }
1089}
1090
1091/*
1092 * Remove a software interrupt handler. Currently this code does not

--- 263 unchanged lines hidden (view full) ---

1356 * This fence is required to ensure that no later loads are
1357 * re-ordered before the ie_active store.
1358 */
1359 atomic_thread_fence_seq_cst();
1360
1361 CK_SLIST_FOREACH(ih, &ie->ie_handlers, ih_next) {
1362 if ((ih->ih_flags & IH_SUSP) != 0)
1363 continue;
1364 if ((ie->ie_flags & IE_SOFT) != 0 && ih->ih_need == 0)
1365 continue;
1349 if (ih->ih_filter == NULL) {
1350 thread = true;
1351 continue;
1352 }
1353 CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
1354 ih->ih_filter, ih->ih_argument == NULL ? frame :
1355 ih->ih_argument, ih->ih_name);
1356 if (ih->ih_argument == NULL)

--- 208 unchanged lines hidden (view full) ---

1565
1566/*
1567 * Start standard software interrupt threads
1568 */
1569static void
1570start_softintr(void *dummy)
1571{
1572
1366 if (ih->ih_filter == NULL) {
1367 thread = true;
1368 continue;
1369 }
1370 CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
1371 ih->ih_filter, ih->ih_argument == NULL ? frame :
1372 ih->ih_argument, ih->ih_name);
1373 if (ih->ih_argument == NULL)

--- 208 unchanged lines hidden (view full) ---

1582
1583/*
1584 * Start standard software interrupt threads
1585 */
1586static void
1587start_softintr(void *dummy)
1588{
1589
1590 if (swi_add(&clk_intr_event, "clk", NULL, NULL, SWI_CLOCK,
1591 INTR_MPSAFE, NULL))
1592 panic("died while creating clk swi ithread");
1573 if (swi_add(NULL, "vm", swi_vm, NULL, SWI_VM, INTR_MPSAFE, &vm_ih))
1574 panic("died while creating vm swi ithread");
1575}
1576SYSINIT(start_softintr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softintr,
1577 NULL);
1578
1579/*
1580 * Sysctls used by systat and others: hw.intrnames and hw.intrcnt.

--- 69 unchanged lines hidden ---
1593 if (swi_add(NULL, "vm", swi_vm, NULL, SWI_VM, INTR_MPSAFE, &vm_ih))
1594 panic("died while creating vm swi ithread");
1595}
1596SYSINIT(start_softintr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softintr,
1597 NULL);
1598
1599/*
1600 * Sysctls used by systat and others: hw.intrnames and hw.intrcnt.

--- 69 unchanged lines hidden ---