Deleted Added
full compact
subr_witness.c (69369) subr_witness.c (69376)
1/*-
2 * Copyright (c) 1998 Berkeley Software Design, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

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

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * from BSDI $Id: mutex_witness.c,v 1.1.2.20 2000/04/27 03:10:27 cp Exp $
29 * and BSDI $Id: synch_machdep.c,v 2.3.2.39 2000/04/27 03:10:25 cp Exp $
1/*-
2 * Copyright (c) 1998 Berkeley Software Design, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

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

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * from BSDI $Id: mutex_witness.c,v 1.1.2.20 2000/04/27 03:10:27 cp Exp $
29 * and BSDI $Id: synch_machdep.c,v 2.3.2.39 2000/04/27 03:10:25 cp Exp $
30 * $FreeBSD: head/sys/kern/subr_witness.c 69369 2000-11-29 20:17:15Z jhb $
30 * $FreeBSD: head/sys/kern/subr_witness.c 69376 2000-11-30 00:51:16Z jhb $
31 */
32
33/*
34 * Main Entry: witness
35 * Pronunciation: 'wit-n&s
36 * Function: noun
37 * Etymology: Middle English witnesse, from Old English witnes knowledge,
38 * testimony, witness, from 2wit

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

97 { NULL, NULL }, &all_mtx, &all_mtx };
98#endif /* MUTEX_DEBUG */
99
100static int mtx_cur_cnt;
101static int mtx_max_cnt;
102
103void _mtx_enter_giant_def(void);
104void _mtx_exit_giant_def(void);
31 */
32
33/*
34 * Main Entry: witness
35 * Pronunciation: 'wit-n&s
36 * Function: noun
37 * Etymology: Middle English witnesse, from Old English witnes knowledge,
38 * testimony, witness, from 2wit

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

97 { NULL, NULL }, &all_mtx, &all_mtx };
98#endif /* MUTEX_DEBUG */
99
100static int mtx_cur_cnt;
101static int mtx_max_cnt;
102
103void _mtx_enter_giant_def(void);
104void _mtx_exit_giant_def(void);
105static void propagate_priority(struct proc *) __unused;
105static void propagate_priority(struct proc *);
106
107#define mtx_unowned(m) ((m)->mtx_lock == MTX_UNOWNED)
108#define mtx_owner(m) (mtx_unowned(m) ? NULL \
109 : (struct proc *)((m)->mtx_lock & MTX_FLAGMASK))
110
111#define RETIP(x) *(((uintptr_t *)(&x)) - 1)
112#define SET_PRIO(p, pri) (p)->p_priority = (pri)
113

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

130}
131
132static void
133propagate_priority(struct proc *p)
134{
135 int pri = p->p_priority;
136 struct mtx *m = p->p_blocked;
137
106
107#define mtx_unowned(m) ((m)->mtx_lock == MTX_UNOWNED)
108#define mtx_owner(m) (mtx_unowned(m) ? NULL \
109 : (struct proc *)((m)->mtx_lock & MTX_FLAGMASK))
110
111#define RETIP(x) *(((uintptr_t *)(&x)) - 1)
112#define SET_PRIO(p, pri) (p)->p_priority = (pri)
113

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

130}
131
132static void
133propagate_priority(struct proc *p)
134{
135 int pri = p->p_priority;
136 struct mtx *m = p->p_blocked;
137
138 mtx_assert(&sched_lock, MA_OWNED);
138 for (;;) {
139 struct proc *p1;
140
141 p = mtx_owner(m);
142
143 if (p == NULL) {
144 /*
145 * This really isn't quite right. Really
146 * ought to bump priority of process that
147 * next acquires the mutex.
148 */
149 MPASS(m->mtx_lock == MTX_CONTESTED);
150 return;
151 }
152 MPASS(p->p_magic == P_MAGIC);
139 for (;;) {
140 struct proc *p1;
141
142 p = mtx_owner(m);
143
144 if (p == NULL) {
145 /*
146 * This really isn't quite right. Really
147 * ought to bump priority of process that
148 * next acquires the mutex.
149 */
150 MPASS(m->mtx_lock == MTX_CONTESTED);
151 return;
152 }
153 MPASS(p->p_magic == P_MAGIC);
154 KASSERT(p->p_stat != SSLEEP, ("sleeping process owns a mutex"));
153 if (p->p_priority <= pri)
154 return;
155 if (p->p_priority <= pri)
156 return;
157
155 /*
158 /*
159 * Bump this process' priority.
160 */
161 SET_PRIO(p, pri);
162
163 /*
156 * If lock holder is actually running, just bump priority.
157 */
164 * If lock holder is actually running, just bump priority.
165 */
158 if (TAILQ_NEXT(p, p_procq) == NULL) {
166#ifdef SMP
167 /*
168 * For SMP, we can check the p_oncpu field to see if we are
169 * running.
170 */
171 if (p->p_oncpu != 0xff) {
159 MPASS(p->p_stat == SRUN || p->p_stat == SZOMB);
172 MPASS(p->p_stat == SRUN || p->p_stat == SZOMB);
160 SET_PRIO(p, pri);
161 return;
162 }
173 return;
174 }
175#else
163 /*
176 /*
177 * For UP, we check to see if p is curproc (this shouldn't
178 * ever happen however as it would mean we are in a deadlock.)
179 */
180 if (p == curproc) {
181 panic("Deadlock detected");
182 return;
183 }
184#endif
185 /*
164 * If on run queue move to new run queue, and
165 * quit.
166 */
167 if (p->p_stat == SRUN) {
186 * If on run queue move to new run queue, and
187 * quit.
188 */
189 if (p->p_stat == SRUN) {
190 printf("XXX: moving process %d(%s) to a new run queue\n",
191 p->p_pid, p->p_comm);
168 MPASS(p->p_blocked == NULL);
169 remrunqueue(p);
192 MPASS(p->p_blocked == NULL);
193 remrunqueue(p);
170 SET_PRIO(p, pri);
171 setrunqueue(p);
172 return;
173 }
174
175 /*
194 setrunqueue(p);
195 return;
196 }
197
198 /*
176 * If we aren't blocked on a mutex, give up and quit.
199 * If we aren't blocked on a mutex, we should be.
177 */
200 */
178 if (p->p_stat != SMTX) {
179 printf(
180 "XXX: process %d(%s):%d holds %s but isn't blocked on a mutex\n",
181 p->p_pid, p->p_comm, p->p_stat, m->mtx_description);
182 return;
183 }
201 KASSERT(p->p_stat == SMTX, (
202 "process %d(%s):%d holds %s but isn't blocked on a mutex\n",
203 p->p_pid, p->p_comm, p->p_stat,
204 m->mtx_description));
184
185 /*
186 * Pick up the mutex that p is blocked on.
187 */
188 m = p->p_blocked;
189 MPASS(m != NULL);
190
191 printf("XXX: process %d(%s) is blocked on %s\n", p->p_pid,
192 p->p_comm, m->mtx_description);
193 /*
194 * Check if the proc needs to be moved up on
195 * the blocked chain
196 */
205
206 /*
207 * Pick up the mutex that p is blocked on.
208 */
209 m = p->p_blocked;
210 MPASS(m != NULL);
211
212 printf("XXX: process %d(%s) is blocked on %s\n", p->p_pid,
213 p->p_comm, m->mtx_description);
214 /*
215 * Check if the proc needs to be moved up on
216 * the blocked chain
217 */
197 if ((p1 = TAILQ_PREV(p, rq, p_procq)) == NULL ||
198 p1->p_priority <= pri) {
199 if (p1)
200 printf(
218 if (p == TAILQ_FIRST(&m->mtx_blocked)) {
219 printf("XXX: process at head of run queue\n");
220 continue;
221 }
222 p1 = TAILQ_PREV(p, rq, p_procq);
223 if (p1->p_priority <= pri) {
224 printf(
201 "XXX: previous process %d(%s) has higher priority\n",
225 "XXX: previous process %d(%s) has higher priority\n",
202 p->p_pid, p->p_comm);
203 else
204 printf("XXX: process at head of run queue\n");
226 p->p_pid, p->p_comm);
205 continue;
206 }
207
208 /*
227 continue;
228 }
229
230 /*
209 * Remove proc from blocked chain
231 * Remove proc from blocked chain and determine where
232 * it should be moved up to. Since we know that p1 has
233 * a lower priority than p, we know that at least one
234 * process in the chain has a lower priority and that
235 * p1 will thus not be NULL after the loop.
210 */
211 TAILQ_REMOVE(&m->mtx_blocked, p, p_procq);
212 TAILQ_FOREACH(p1, &m->mtx_blocked, p_procq) {
213 MPASS(p1->p_magic == P_MAGIC);
214 if (p1->p_priority > pri)
215 break;
216 }
236 */
237 TAILQ_REMOVE(&m->mtx_blocked, p, p_procq);
238 TAILQ_FOREACH(p1, &m->mtx_blocked, p_procq) {
239 MPASS(p1->p_magic == P_MAGIC);
240 if (p1->p_priority > pri)
241 break;
242 }
217 if (p1)
218 TAILQ_INSERT_BEFORE(p1, p, p_procq);
219 else
220 TAILQ_INSERT_TAIL(&m->mtx_blocked, p, p_procq);
243 MPASS(p1 != NULL);
244 TAILQ_INSERT_BEFORE(p1, p, p_procq);
221 CTR4(KTR_LOCK,
245 CTR4(KTR_LOCK,
222 "propagate priority: p 0x%p moved before 0x%p on [0x%p] %s",
246 "propagate_priority: p 0x%p moved before 0x%p on [0x%p] %s",
223 p, p1, m, m->mtx_description);
224 }
225}
226
227void
228mtx_enter_hard(struct mtx *m, int type, int saveintr)
229{
230 struct proc *p = CURPROC;

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

236 if ((m->mtx_lock & MTX_FLAGMASK) == (uintptr_t)p) {
237 m->mtx_recurse++;
238 atomic_set_ptr(&m->mtx_lock, MTX_RECURSE);
239 CTR1(KTR_LOCK, "mtx_enter: 0x%p recurse", m);
240 return;
241 }
242 CTR3(KTR_LOCK, "mtx_enter: 0x%p contested (lock=%p) [0x%p]",
243 m, (void *)m->mtx_lock, (void *)RETIP(m));
247 p, p1, m, m->mtx_description);
248 }
249}
250
251void
252mtx_enter_hard(struct mtx *m, int type, int saveintr)
253{
254 struct proc *p = CURPROC;

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

260 if ((m->mtx_lock & MTX_FLAGMASK) == (uintptr_t)p) {
261 m->mtx_recurse++;
262 atomic_set_ptr(&m->mtx_lock, MTX_RECURSE);
263 CTR1(KTR_LOCK, "mtx_enter: 0x%p recurse", m);
264 return;
265 }
266 CTR3(KTR_LOCK, "mtx_enter: 0x%p contested (lock=%p) [0x%p]",
267 m, (void *)m->mtx_lock, (void *)RETIP(m));
268
269 /*
270 * Save our priority. Even though p_nativepri is protected
271 * by sched_lock, we don't obtain it here as it can be
272 * expensive. Since this is the only place p_nativepri is
273 * set, and since two CPUs will not be executing the same
274 * process concurrently, we know that no other CPU is going
275 * to be messing with this. Also, p_nativepri is only read
276 * when we are blocked on a mutex, so that can't be happening
277 * right now either.
278 */
279 p->p_nativepri = p->p_priority;
244 while (!_obtain_lock(m, p)) {
245 uintptr_t v;
246 struct proc *p1;
247
248 mtx_enter(&sched_lock, MTX_SPIN | MTX_RLIKELY);
249 /*
250 * check if the lock has been released while
251 * waiting for the schedlock.

--- 1093 unchanged lines hidden ---
280 while (!_obtain_lock(m, p)) {
281 uintptr_t v;
282 struct proc *p1;
283
284 mtx_enter(&sched_lock, MTX_SPIN | MTX_RLIKELY);
285 /*
286 * check if the lock has been released while
287 * waiting for the schedlock.

--- 1093 unchanged lines hidden ---