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 --- |