subr_sleepqueue.c (296320) | subr_sleepqueue.c (296927) |
---|---|
1/*- 2 * Copyright (c) 2004 John Baldwin <jhb@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 43 unchanged lines hidden (view full) --- 52 * must consistently use the same lock to synchronize with a wait channel, 53 * though this check is currently only a warning for sleep/wakeup due to 54 * pre-existing abuse of that API. The same lock must also be held when 55 * awakening threads, though that is currently only enforced for condition 56 * variables. 57 */ 58 59#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2004 John Baldwin <jhb@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 43 unchanged lines hidden (view full) --- 52 * must consistently use the same lock to synchronize with a wait channel, 53 * though this check is currently only a warning for sleep/wakeup due to 54 * pre-existing abuse of that API. The same lock must also be held when 55 * awakening threads, though that is currently only enforced for condition 56 * variables. 57 */ 58 59#include <sys/cdefs.h> |
60__FBSDID("$FreeBSD: head/sys/kern/subr_sleepqueue.c 296320 2016-03-02 18:46:17Z kib $"); | 60__FBSDID("$FreeBSD: head/sys/kern/subr_sleepqueue.c 296927 2016-03-16 04:22:32Z cem $"); |
61 62#include "opt_sleepqueue_profiling.h" 63#include "opt_ddb.h" 64#include "opt_sched.h" 65 66#include <sys/param.h> 67#include <sys/systm.h> 68#include <sys/lock.h> 69#include <sys/kernel.h> 70#include <sys/ktr.h> 71#include <sys/mutex.h> 72#include <sys/proc.h> 73#include <sys/sbuf.h> 74#include <sys/sched.h> 75#include <sys/sdt.h> 76#include <sys/signalvar.h> 77#include <sys/sleepqueue.h> | 61 62#include "opt_sleepqueue_profiling.h" 63#include "opt_ddb.h" 64#include "opt_sched.h" 65 66#include <sys/param.h> 67#include <sys/systm.h> 68#include <sys/lock.h> 69#include <sys/kernel.h> 70#include <sys/ktr.h> 71#include <sys/mutex.h> 72#include <sys/proc.h> 73#include <sys/sbuf.h> 74#include <sys/sched.h> 75#include <sys/sdt.h> 76#include <sys/signalvar.h> 77#include <sys/sleepqueue.h> |
78#include <sys/stack.h> |
|
78#include <sys/sysctl.h> 79 80#include <vm/uma.h> 81 82#ifdef DDB 83#include <ddb/ddb.h> 84#endif 85 | 79#include <sys/sysctl.h> 80 81#include <vm/uma.h> 82 83#ifdef DDB 84#include <ddb/ddb.h> 85#endif 86 |
87 |
|
86/* 87 * Constants for the hash table of sleep queue chains. 88 * SC_TABLESIZE must be a power of two for SC_MASK to work properly. 89 */ 90#define SC_TABLESIZE 256 /* Must be power of 2. */ 91#define SC_MASK (SC_TABLESIZE - 1) 92#define SC_SHIFT 8 93#define SC_HASH(wc) ((((uintptr_t)(wc) >> SC_SHIFT) ^ (uintptr_t)(wc)) & \ --- 935 unchanged lines hidden (view full) --- 1029 MPASS(wchan != NULL); 1030 sq = sleepq_lookup(wchan); 1031 MPASS(sq != NULL); 1032 1033 /* Thread is asleep on sleep queue sq, so wake it up. */ 1034 return (sleepq_resume_thread(sq, td, 0)); 1035} 1036 | 88/* 89 * Constants for the hash table of sleep queue chains. 90 * SC_TABLESIZE must be a power of two for SC_MASK to work properly. 91 */ 92#define SC_TABLESIZE 256 /* Must be power of 2. */ 93#define SC_MASK (SC_TABLESIZE - 1) 94#define SC_SHIFT 8 95#define SC_HASH(wc) ((((uintptr_t)(wc) >> SC_SHIFT) ^ (uintptr_t)(wc)) & \ --- 935 unchanged lines hidden (view full) --- 1031 MPASS(wchan != NULL); 1032 sq = sleepq_lookup(wchan); 1033 MPASS(sq != NULL); 1034 1035 /* Thread is asleep on sleep queue sq, so wake it up. */ 1036 return (sleepq_resume_thread(sq, td, 0)); 1037} 1038 |
1039/* 1040 * Prints the stacks of all threads presently sleeping on wchan/queue to 1041 * the sbuf sb. Sets count_stacks_printed to the number of stacks actually 1042 * printed. Typically, this will equal the number of threads sleeping on the 1043 * queue, but may be less if sb overflowed before all stacks were printed. 1044 */ 1045int 1046sleepq_sbuf_print_stacks(struct sbuf *sb, void *wchan, int queue, 1047 int *count_stacks_printed) 1048{ 1049 struct thread *td, *td_next; 1050 struct sleepqueue *sq; 1051 struct stack **st; 1052 struct sbuf **td_infos; 1053 int i, stack_idx, error, stacks_to_allocate; 1054 bool finished, partial_print; 1055 1056 error = 0; 1057 finished = false; 1058 partial_print = false; 1059 1060 KASSERT(wchan != NULL, ("%s: invalid NULL wait channel", __func__)); 1061 MPASS((queue >= 0) && (queue < NR_SLEEPQS)); 1062 1063 stacks_to_allocate = 10; 1064 for (i = 0; i < 3 && !finished ; i++) { 1065 /* We cannot malloc while holding the queue's spinlock, so 1066 * we do our mallocs now, and hope it is enough. If it 1067 * isn't, we will free these, drop the lock, malloc more, 1068 * and try again, up to a point. After that point we will 1069 * give up and report ENOMEM. We also cannot write to sb 1070 * during this time since the client may have set the 1071 * SBUF_AUTOEXTEND flag on their sbuf, which could cause a 1072 * malloc as we print to it. So we defer actually printing 1073 * to sb until after we drop the spinlock. 1074 */ 1075 1076 /* Where we will store the stacks. */ 1077 st = malloc(sizeof(struct stack *) * stacks_to_allocate, 1078 M_TEMP, M_WAITOK); 1079 for (stack_idx = 0; stack_idx < stacks_to_allocate; 1080 stack_idx++) 1081 st[stack_idx] = stack_create(); 1082 1083 /* Where we will store the td name, tid, etc. */ 1084 td_infos = malloc(sizeof(struct sbuf *) * stacks_to_allocate, 1085 M_TEMP, M_WAITOK); 1086 for (stack_idx = 0; stack_idx < stacks_to_allocate; 1087 stack_idx++) 1088 td_infos[stack_idx] = sbuf_new(NULL, NULL, 1089 MAXCOMLEN + sizeof(struct thread *) * 2 + 40, 1090 SBUF_FIXEDLEN); 1091 1092 sleepq_lock(wchan); 1093 sq = sleepq_lookup(wchan); 1094 if (sq == NULL) { 1095 /* This sleepq does not exist; exit and return ENOENT. */ 1096 error = ENOENT; 1097 finished = true; 1098 sleepq_release(wchan); 1099 goto loop_end; 1100 } 1101 1102 stack_idx = 0; 1103 /* Save thread info */ 1104 TAILQ_FOREACH_SAFE(td, &sq->sq_blocked[queue], td_slpq, 1105 td_next) { 1106 if (stack_idx >= stacks_to_allocate) 1107 goto loop_end; 1108 1109 /* Note the td_lock is equal to the sleepq_lock here. */ 1110 stack_save_td(st[stack_idx], td); 1111 1112 sbuf_printf(td_infos[stack_idx], "%d: %s %p", 1113 td->td_tid, td->td_name, td); 1114 1115 ++stack_idx; 1116 } 1117 1118 finished = true; 1119 sleepq_release(wchan); 1120 1121 /* Print the stacks */ 1122 for (i = 0; i < stack_idx; i++) { 1123 sbuf_finish(td_infos[i]); 1124 sbuf_printf(sb, "--- thread %s: ---\n", sbuf_data(td_infos[i])); 1125 stack_sbuf_print(sb, st[i]); 1126 sbuf_printf(sb, "\n"); 1127 1128 error = sbuf_error(sb); 1129 if (error == 0) 1130 *count_stacks_printed = stack_idx; 1131 } 1132 1133loop_end: 1134 if (!finished) 1135 sleepq_release(wchan); 1136 for (stack_idx = 0; stack_idx < stacks_to_allocate; 1137 stack_idx++) 1138 stack_destroy(st[stack_idx]); 1139 for (stack_idx = 0; stack_idx < stacks_to_allocate; 1140 stack_idx++) 1141 sbuf_delete(td_infos[stack_idx]); 1142 free(st, M_TEMP); 1143 free(td_infos, M_TEMP); 1144 stacks_to_allocate *= 10; 1145 } 1146 1147 if (!finished && error == 0) 1148 error = ENOMEM; 1149 1150 return (error); 1151} 1152 |
|
1037#ifdef SLEEPQUEUE_PROFILING 1038#define SLEEPQ_PROF_LOCATIONS 1024 1039#define SLEEPQ_SBUFSIZE 512 1040struct sleepq_prof { 1041 LIST_ENTRY(sleepq_prof) sp_link; 1042 const char *sp_wmesg; 1043 long sp_count; 1044}; --- 204 unchanged lines hidden --- | 1153#ifdef SLEEPQUEUE_PROFILING 1154#define SLEEPQ_PROF_LOCATIONS 1024 1155#define SLEEPQ_SBUFSIZE 512 1156struct sleepq_prof { 1157 LIST_ENTRY(sleepq_prof) sp_link; 1158 const char *sp_wmesg; 1159 long sp_count; 1160}; --- 204 unchanged lines hidden --- |