1. to enter the debugger (mdb)
#include <sys/debug.h>
debug_enter(char *);
2. timer in the device driver
#include <sys/types.h>
#include <sys/conf.h>
timeout_id_t timeout(void (* func)(void *), void *arg,
clock_t ticks);
SEE ALSO
bufcall(9F), cv_timedwait(9F), ddi_in_panic(9F), delay(9F),
drv_usectohz(9F), untimeout(9F)
3. interrupt clean and restore
intr_clean()
intr_restore()
4. cpu cache line flush
wbinvd
clflush
5. conditional print sample
#ifdef ZFS_DEBUG
extern void __dprintf(const char *file, const char *func,
int line, const char *fmt, ...);
#define dprintf(...) /
if (zfs_flags & ZFS_DEBUG_DPRINTF) /
__dprintf(__FILE__, __func__, __LINE__, __VA_ARGS__)
#else
#define dprintf(...) ((void)0)
#endif /* ZFS_DEBUG */
========================
/* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
void
__dprintf(const char *file, const char *func, int line, const char *fmt, ...)
{
const char *newfile;
char buf[256];
va_list adx;
/*
* Get rid of annoying "../common/" prefix to filename.
*/
newfile = strrchr(file, '/');
if (newfile != NULL) {
newfile = newfile + 1; /* Get rid of leading / */
} else {
newfile = file;
}
va_start(adx, fmt);
(void) vsnprintf(buf, sizeof (buf), fmt, adx);
va_end(adx);
/*
* To get this data, use the zfs-dprintf probe as so:
* dtrace -q -n 'zfs-dprintf /
* /stringof(arg0) == "dbuf.c"/ /
* {printf("%s: %s", stringof(arg1), stringof(arg3))}'
* arg0 = file name
* arg1 = function name
* arg2 = line number
* arg3 = message
*/
DTRACE_PROBE4(zfs__dprintf,
char *, newfile, char *, func, int, line, char *, buf);
}
6. get the kernel tick
#include <sys/types.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
clock_t ddi_get_lbolt(void);
#include <sys/types.h>
#include <sys/ddi.h>
clock_t drv_usectohz(clock_t microsecs);
7. walk a dip tree
/*
* collect_pci_mmio()
* walk through the pci device tree, and collect the mmio resources
*/
static int
collect_pci_mmio(dev_info_t *pdip)
{
int count;
ASSERT(pdip);
/*
* walk through the device tree under pdip
* normally, pdip should be the pci root nexus
*/
ndi_devi_enter(pdip, &count);
ddi_walk_devs(ddi_get_child(pdip),
collect_pci_mmio_walk, NULL);
ndi_devi_exit(pdip, count);
return (DDI_SUCCESS);
}
#include <sys/debug.h>
debug_enter(char *);
2. timer in the device driver
#include <sys/types.h>
#include <sys/conf.h>
timeout_id_t timeout(void (* func)(void *), void *arg,
clock_t ticks);
SEE ALSO
bufcall(9F), cv_timedwait(9F), ddi_in_panic(9F), delay(9F),
drv_usectohz(9F), untimeout(9F)
3. interrupt clean and restore
intr_clean()
intr_restore()
4. cpu cache line flush
wbinvd
clflush
5. conditional print sample
#ifdef ZFS_DEBUG
extern void __dprintf(const char *file, const char *func,
int line, const char *fmt, ...);
#define dprintf(...) /
if (zfs_flags & ZFS_DEBUG_DPRINTF) /
__dprintf(__FILE__, __func__, __LINE__, __VA_ARGS__)
#else
#define dprintf(...) ((void)0)
#endif /* ZFS_DEBUG */
========================
/* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
void
__dprintf(const char *file, const char *func, int line, const char *fmt, ...)
{
const char *newfile;
char buf[256];
va_list adx;
/*
* Get rid of annoying "../common/" prefix to filename.
*/
newfile = strrchr(file, '/');
if (newfile != NULL) {
newfile = newfile + 1; /* Get rid of leading / */
} else {
newfile = file;
}
va_start(adx, fmt);
(void) vsnprintf(buf, sizeof (buf), fmt, adx);
va_end(adx);
/*
* To get this data, use the zfs-dprintf probe as so:
* dtrace -q -n 'zfs-dprintf /
* /stringof(arg0) == "dbuf.c"/ /
* {printf("%s: %s", stringof(arg1), stringof(arg3))}'
* arg0 = file name
* arg1 = function name
* arg2 = line number
* arg3 = message
*/
DTRACE_PROBE4(zfs__dprintf,
char *, newfile, char *, func, int, line, char *, buf);
}
6. get the kernel tick
#include <sys/types.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
clock_t ddi_get_lbolt(void);
#include <sys/types.h>
#include <sys/ddi.h>
clock_t drv_usectohz(clock_t microsecs);
7. walk a dip tree
/*
* collect_pci_mmio()
* walk through the pci device tree, and collect the mmio resources
*/
static int
collect_pci_mmio(dev_info_t *pdip)
{
int count;
ASSERT(pdip);
/*
* walk through the device tree under pdip
* normally, pdip should be the pci root nexus
*/
ndi_devi_enter(pdip, &count);
ddi_walk_devs(ddi_get_child(pdip),
collect_pci_mmio_walk, NULL);
ndi_devi_exit(pdip, count);
return (DDI_SUCCESS);
}