View | Details | Raw Unified | Return to bug 238971
Collapse All | Expand All

(-)b/sys/kern/kern_timeout.c (-1 / +38 lines)
Lines 65-70 __FBSDID("$FreeBSD$"); Link Here
65
65
66
#ifdef DDB
66
#ifdef DDB
67
#include <ddb/ddb.h>
67
#include <ddb/ddb.h>
68
#include <ddb/db_sym.h>
68
#include <machine/_inttypes.h>
69
#include <machine/_inttypes.h>
69
#endif
70
#endif
70
71
Lines 143-154 u_int callwheelsize, callwheelmask; Link Here
143
struct cc_exec {
144
struct cc_exec {
144
	struct callout		*cc_curr;
145
	struct callout		*cc_curr;
145
	void			(*cc_drain)(void *);
146
	void			(*cc_drain)(void *);
147
	void			*cc_last_func;
148
	void			*cc_last_arg;
146
#ifdef SMP
149
#ifdef SMP
147
	void			(*ce_migration_func)(void *);
150
	void			(*ce_migration_func)(void *);
148
	void			*ce_migration_arg;
151
	void			*ce_migration_arg;
149
	int			ce_migration_cpu;
150
	sbintime_t		ce_migration_time;
152
	sbintime_t		ce_migration_time;
151
	sbintime_t		ce_migration_prec;
153
	sbintime_t		ce_migration_prec;
154
	int			ce_migration_cpu;
152
#endif
155
#endif
153
	bool			cc_cancel;
156
	bool			cc_cancel;
154
	bool			cc_waiting;
157
	bool			cc_waiting;
Lines 177-182 struct callout_cpu { Link Here
177
#define	callout_migrating(c)	((c)->c_iflags & CALLOUT_DFRMIGRATION)
180
#define	callout_migrating(c)	((c)->c_iflags & CALLOUT_DFRMIGRATION)
178
181
179
#define	cc_exec_curr(cc, dir)		cc->cc_exec_entity[dir].cc_curr
182
#define	cc_exec_curr(cc, dir)		cc->cc_exec_entity[dir].cc_curr
183
#define	cc_exec_last_func(cc, dir)	cc->cc_exec_entity[dir].cc_last_func
184
#define	cc_exec_last_arg(cc, dir)	cc->cc_exec_entity[dir].cc_last_arg
180
#define	cc_exec_drain(cc, dir)		cc->cc_exec_entity[dir].cc_drain
185
#define	cc_exec_drain(cc, dir)		cc->cc_exec_entity[dir].cc_drain
181
#define	cc_exec_next(cc)		cc->cc_next
186
#define	cc_exec_next(cc)		cc->cc_next
182
#define	cc_exec_cancel(cc, dir)		cc->cc_exec_entity[dir].cc_cancel
187
#define	cc_exec_cancel(cc, dir)		cc->cc_exec_entity[dir].cc_cancel
Lines 686-691 softclock_call_cc(struct callout *c, struct callout_cpu *cc, Link Here
686
		c->c_iflags &= ~CALLOUT_PENDING;
691
		c->c_iflags &= ~CALLOUT_PENDING;
687
	
692
	
688
	cc_exec_curr(cc, direct) = c;
693
	cc_exec_curr(cc, direct) = c;
694
	cc_exec_last_func(cc, direct) = c_func;
695
	cc_exec_last_arg(cc, direct) = c_arg;
689
	cc_exec_cancel(cc, direct) = false;
696
	cc_exec_cancel(cc, direct) = false;
690
	cc_exec_drain(cc, direct) = NULL;
697
	cc_exec_drain(cc, direct) = NULL;
691
	CC_UNLOCK(cc);
698
	CC_UNLOCK(cc);
Lines 1670-1673 DB_SHOW_COMMAND(callout, db_show_callout) Link Here
1670
1677
1671
	_show_callout((struct callout *)addr);
1678
	_show_callout((struct callout *)addr);
1672
}
1679
}
1680
1681
static void
1682
_show_last_callout(struct callout_cpu *cc, int direct, const char *dirstr)
1683
{
1684
	void *func, *arg;
1685
1686
	func = cc_exec_last_func(cc, direct);
1687
	arg = cc_exec_last_arg(cc, direct);
1688
	db_printf("last%s callout function: %p ", dirstr, func);
1689
	db_printsym((db_expr_t)func, DB_STGY_ANY);
1690
	db_printf("\nlast%s callout argument: %p\n", dirstr, arg);
1691
}
1692
1693
DB_SHOW_COMMAND(callout_last, db_show_callout_last)
1694
{
1695
	struct callout_cpu *cc;
1696
1697
	if (have_addr) {
1698
		if (addr < 0 || addr > mp_maxid || CPU_ABSENT(addr)) {
1699
			db_printf("no such cpu: %d\n", (int)addr);
1700
			return;
1701
		}
1702
		cc = CC_CPU(addr);
1703
	} else {
1704
		cc = CC_CPU(timeout_cpu);
1705
	}
1706
1707
	_show_last_callout(cc, 0, "");
1708
	_show_last_callout(cc, 1, " direct");
1709
}
1673
#endif /* DDB */
1710
#endif /* DDB */
(-)b/tools/test/callout_free/Makefile (+4 lines)
Added Link Here
1
KMOD=	callout_free
2
SRCS=	callout_free.c
3
4
.include <bsd.kmod.mk>
(-)b/tools/test/callout_free/callout_free.c (-1 / +87 lines)
Added Link Here
0
- 
1
/*-
2
 * SPDX-License-Identifier: BSD-2-Clause
3
 *
4
 * Copyright (c) 2019 Eric van Gyzen
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
 * SUCH DAMAGE.
26
 *
27
 * $FreeBSD$
28
 */
29
30
/*
31
 * Free a pending callout.  This was useful for testing the
32
 * "show callout_last" ddb command.
33
 */
34
35
#include <sys/param.h>
36
#include <sys/conf.h>
37
#include <sys/kernel.h>
38
#include <sys/lock.h>
39
#include <sys/module.h>
40
#include <sys/mutex.h>
41
#include <sys/systm.h>
42
43
static struct callout callout_free;
44
static struct mtx callout_free_mutex;
45
static int callout_free_arg;
46
47
static void
48
callout_free_func(void *arg)
49
{
50
	printf("squirrel!\n");
51
	mtx_destroy(&callout_free_mutex);
52
	memset(&callout_free, 'C', sizeof(callout_free));
53
}
54
55
static int
56
callout_free_load(module_t mod, int cmd, void *arg)
57
{
58
	int error;
59
60
	switch (cmd) {
61
	case MOD_LOAD:
62
		mtx_init(&callout_free_mutex, "callout_free", NULL, MTX_DEF);
63
		/*
64
		 * Do not pass CALLOUT_RETURNUNLOCKED so the callout
65
		 * subsystem will unlock the "destroyed" mutex.
66
		 */
67
		callout_init_mtx(&callout_free, &callout_free_mutex, 0);
68
		printf("callout_free_func = %p\n", callout_free_func);
69
		printf("callout_free_arg = %p\n", &callout_free_arg);
70
		callout_reset(&callout_free, hz/10, callout_free_func,
71
		    &callout_free_arg);
72
		error = 0;
73
		break;
74
75
	case MOD_UNLOAD:
76
		error = 0;
77
		break;
78
79
	default:
80
		error = EOPNOTSUPP;
81
		break;
82
	}
83
84
	return (error);
85
}
86
87
DEV_MODULE(callout_free, callout_free_load, NULL);

Return to bug 238971