Crash in dbuf_evict_one with DTRACE_PROBE

Update the dbuf__evict__one() tracepoint so that it can safely
handle a NULL dmu_buf_impl_t pointer.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>    
Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: loli10K <ezomori.nozomu@gmail.com>
Signed-off-by: gaurkuma <gauravk.18@gmail.com>
Closes #6463
This commit is contained in:
gaurkuma 2017-08-09 11:04:41 -07:00 committed by Tony Hutter
parent 751575fe6f
commit 58c1c40a5e

View File

@ -33,6 +33,10 @@
#include <linux/tracepoint.h>
#include <sys/types.h>
#ifndef TRACE_DBUF_MSG_MAX
#define TRACE_DBUF_MSG_MAX 512
#endif
/*
* Generic support for two argument tracepoints of the form:
*
@ -42,8 +46,7 @@
*/
#define DBUF_TP_STRUCT_ENTRY \
__string(os_spa, \
spa_name(DB_DNODE(db)->dn_objset->os_spa)) \
__dynamic_array(char, os_spa, TRACE_DBUF_MSG_MAX) \
__field(uint64_t, ds_object) \
__field(uint64_t, db_object) \
__field(uint64_t, db_level) \
@ -52,21 +55,38 @@
__field(uint64_t, db_size) \
__field(uint64_t, db_state) \
__field(int64_t, db_holds) \
__dynamic_array(char, msg, TRACE_DBUF_MSG_MAX)
#define DBUF_TP_FAST_ASSIGN \
__assign_str(os_spa, \
spa_name(DB_DNODE(db)->dn_objset->os_spa)); \
\
__entry->ds_object = db->db_objset->os_dsl_dataset ? \
db->db_objset->os_dsl_dataset->ds_object : 0; \
\
__entry->db_object = db->db.db_object; \
__entry->db_level = db->db_level; \
__entry->db_blkid = db->db_blkid; \
__entry->db_offset = db->db.db_offset; \
__entry->db_size = db->db.db_size; \
__entry->db_state = db->db_state; \
__entry->db_holds = refcount_count(&db->db_holds);
#define DBUF_TP_FAST_ASSIGN \
if (db != NULL) { \
__assign_str(os_spa, \
spa_name(DB_DNODE(db)->dn_objset->os_spa)); \
\
__entry->ds_object = db->db_objset->os_dsl_dataset ? \
db->db_objset->os_dsl_dataset->ds_object : 0; \
\
__entry->db_object = db->db.db_object; \
__entry->db_level = db->db_level; \
__entry->db_blkid = db->db_blkid; \
__entry->db_offset = db->db.db_offset; \
__entry->db_size = db->db.db_size; \
__entry->db_state = db->db_state; \
__entry->db_holds = refcount_count(&db->db_holds); \
snprintf(__get_str(msg), TRACE_DBUF_MSG_MAX, \
DBUF_TP_PRINTK_FMT, DBUF_TP_PRINTK_ARGS); \
} else { \
__assign_str(os_spa, "NULL") \
__entry->ds_object = 0; \
__entry->db_object = 0; \
__entry->db_level = 0; \
__entry->db_blkid = 0; \
__entry->db_offset = 0; \
__entry->db_size = 0; \
__entry->db_state = 0; \
__entry->db_holds = 0; \
snprintf(__get_str(msg), TRACE_DBUF_MSG_MAX, \
"dbuf { NULL }"); \
}
#define DBUF_TP_PRINTK_FMT \
"dbuf { spa \"%s\" objset %llu object %llu level %llu " \
@ -84,7 +104,7 @@ DECLARE_EVENT_CLASS(zfs_dbuf_class,
TP_ARGS(db, zio),
TP_STRUCT__entry(DBUF_TP_STRUCT_ENTRY),
TP_fast_assign(DBUF_TP_FAST_ASSIGN),
TP_printk(DBUF_TP_PRINTK_FMT, DBUF_TP_PRINTK_ARGS)
TP_printk("%s", __get_str(msg))
);
/* END CSTYLED */
@ -102,7 +122,7 @@ DECLARE_EVENT_CLASS(zfs_dbuf_evict_one_class,
TP_ARGS(db, mls),
TP_STRUCT__entry(DBUF_TP_STRUCT_ENTRY),
TP_fast_assign(DBUF_TP_FAST_ASSIGN),
TP_printk(DBUF_TP_PRINTK_FMT, DBUF_TP_PRINTK_ARGS)
TP_printk("%s", __get_str(msg))
);
/* END CSTYLED */