summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2009-04-29 17:45:27 +0200
committerPhilipp Reisner <philipp.reisner@linbit.com>2009-07-29 10:26:26 +0200
commit95eaef1cbc63f73df4ff8559dd66b1d29b462535 (patch)
treea667d9b136ca600b975b2699c8cff6fbe703dbd8 /drivers/block
parentc733785235d1cf1e37e70446182a21c06e69d519 (diff)
Replaced our own tracing stuff with Linux's tracepoints
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/Kconfig10
-rw-r--r--drivers/block/drbd/Makefile3
-rw-r--r--drivers/block/drbd/drbd_actlog.c111
-rw-r--r--drivers/block/drbd/drbd_bitmap.c5
-rw-r--r--drivers/block/drbd/drbd_int.h130
-rw-r--r--drivers/block/drbd/drbd_main.c483
-rw-r--r--drivers/block/drbd/drbd_nl.c85
-rw-r--r--drivers/block/drbd/drbd_proc.c4
-rw-r--r--drivers/block/drbd/drbd_receiver.c101
-rw-r--r--drivers/block/drbd/drbd_req.c89
-rw-r--r--drivers/block/drbd/drbd_req.h1
-rw-r--r--drivers/block/drbd/drbd_tracing.c762
-rw-r--r--drivers/block/drbd/drbd_tracing.h87
-rw-r--r--drivers/block/drbd/drbd_worker.c25
-rw-r--r--drivers/block/drbd/drbd_wrappers.h5
15 files changed, 1006 insertions, 895 deletions
diff --git a/drivers/block/drbd/Kconfig b/drivers/block/drbd/Kconfig
index c5847ddb24b3..7ad8c2a3c2f3 100644
--- a/drivers/block/drbd/Kconfig
+++ b/drivers/block/drbd/Kconfig
@@ -35,3 +35,13 @@ config BLK_DEV_DRBD
See also: http://www.drbd.org/, http://www.linux-ha.org
If unsure, say N.
+
+config DRBD_TRACE
+ tristate "DRBD tracing"
+ depends on BLK_DEV_DRBD
+ select TRACEPOINTS
+ help
+
+ Say Y here if you want to be able to trace various events in DRBD.
+
+ If unsure, say N.
diff --git a/drivers/block/drbd/Makefile b/drivers/block/drbd/Makefile
index 7237c339f7da..f0f805cd2051 100644
--- a/drivers/block/drbd/Makefile
+++ b/drivers/block/drbd/Makefile
@@ -2,4 +2,7 @@ drbd-y := drbd_buildtag.o drbd_bitmap.o drbd_proc.o
drbd-y += drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o
drbd-y += lru_cache.o drbd_main.o drbd_strings.o drbd_nl.o
+drbd_trace-y := drbd_tracing.o drbd_strings.o
+
obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o
+obj-$(CONFIG_DRBD_TRACE) += drbd_trace.o
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index fbbddd3d7f31..c894b4fa6af0 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -26,6 +26,7 @@
#include <linux/slab.h>
#include <linux/drbd.h>
#include "drbd_int.h"
+#include "drbd_tracing.h"
#include "drbd_wrappers.h"
/* I do not believe that all storage medias can guarantee atomic
@@ -65,6 +66,17 @@ struct drbd_atodb_wait {
int w_al_write_transaction(struct drbd_conf *, struct drbd_work *, int);
+/* The actual tracepoint needs to have constant number of known arguments...
+ */
+void trace_drbd_resync(struct drbd_conf *mdev, int level, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ trace__drbd_resync(mdev, level, fmt, ap);
+ va_end(ap);
+}
+
STATIC int _drbd_md_sync_page_io(struct drbd_conf *mdev,
struct drbd_backing_dev *bdev,
struct page *page, sector_t sector,
@@ -93,7 +105,7 @@ STATIC int _drbd_md_sync_page_io(struct drbd_conf *mdev,
bio->bi_end_io = drbd_md_io_complete;
bio->bi_rw = rw;
- dump_internal_bio("Md", mdev, bio, 0);
+ trace_drbd_bio(mdev, "Md", bio, 0, NULL);
if (FAULT_ACTIVE(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD))
bio_endio(bio, -EIO);
@@ -223,11 +235,7 @@ void drbd_al_begin_io(struct drbd_conf *mdev, sector_t sector)
D_ASSERT(atomic_read(&mdev->local_cnt) > 0);
- MTRACE(TRACE_TYPE_AL_EXTS, TRACE_LVL_METRICS,
- dev_info(DEV, "al_begin_io( sec=%llus (al_enr=%u) (rs_enr=%d) )\n",
- (unsigned long long) sector, enr,
- (int)BM_SECT_TO_EXT(sector));
- );
+ trace_drbd_actlog(mdev, sector, "al_begin_io");
wait_event(mdev->al_wait, (al_ext = _al_get(mdev, enr)));
@@ -260,11 +268,7 @@ void drbd_al_complete_io(struct drbd_conf *mdev, sector_t sector)
struct lc_element *extent;
unsigned long flags;
- MTRACE(TRACE_TYPE_AL_EXTS, TRACE_LVL_METRICS,
- dev_info(DEV, "al_complete_io( sec=%llus (al_enr=%u) (rs_enr=%d) )\n",
- (unsigned long long) sector, enr,
- (int)BM_SECT_TO_EXT(sector));
- );
+ trace_drbd_actlog(mdev, sector, "al_complete_io");
spin_lock_irqsave(&mdev->al_lock, flags);
@@ -763,11 +767,6 @@ static inline int _try_lc_del(struct drbd_conf *mdev, struct lc_element *al_ext)
lc_del(mdev->act_log, al_ext);
spin_unlock_irq(&mdev->al_lock);
- MTRACE(TRACE_TYPE_AL_EXTS, TRACE_LVL_METRICS,
- if (unlikely(!rv))
- dev_info(DEV, "Waiting for extent in drbd_al_shrink()\n");
- );
-
return rv;
}
@@ -953,10 +952,9 @@ void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size,
ebnr = BM_SECT_TO_BIT(esector - (BM_SECT_PER_BIT-1));
sbnr = BM_SECT_TO_BIT(sector + BM_SECT_PER_BIT-1);
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_METRICS,
- dev_info(DEV, "drbd_set_in_sync: sector=%llus size=%u sbnr=%lu ebnr=%lu\n",
- (unsigned long long)sector, size, sbnr, ebnr);
- );
+ trace_drbd_resync(mdev, TRACE_LVL_METRICS,
+ "drbd_set_in_sync: sector=%llus size=%u sbnr=%lu ebnr=%lu\n",
+ (unsigned long long)sector, size, sbnr, ebnr);
if (sbnr > ebnr)
return;
@@ -1032,11 +1030,9 @@ void __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size,
sbnr = BM_SECT_TO_BIT(sector);
ebnr = BM_SECT_TO_BIT(esector);
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_METRICS,
- dev_info(DEV, "drbd_set_out_of_sync: sector=%llus size=%u "
- "sbnr=%lu ebnr=%lu\n",
- (unsigned long long)sector, size, sbnr, ebnr);
- );
+ trace_drbd_resync(mdev, TRACE_LVL_METRICS,
+ "drbd_set_out_of_sync: sector=%llus size=%u sbnr=%lu ebnr=%lu\n",
+ (unsigned long long)sector, size, sbnr, ebnr);
/* ok, (capacity & 7) != 0 sometimes, but who cares...
* we count rs_{total,left} in bits, not sectors. */
@@ -1133,10 +1129,9 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
struct bm_extent *bm_ext;
int i, sig;
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_ALL,
- dev_info(DEV, "drbd_rs_begin_io: sector=%llus (rs_end=%d)\n",
- (unsigned long long)sector, enr);
- );
+ trace_drbd_resync(mdev, TRACE_LVL_ALL,
+ "drbd_rs_begin_io: sector=%llus (rs_end=%d)\n",
+ (unsigned long long)sector, enr);
sig = wait_event_interruptible(mdev->al_wait,
(bm_ext = _bme_get(mdev, enr)));
@@ -1183,10 +1178,8 @@ int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
struct bm_extent *bm_ext;
int i;
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_ALL,
- dev_info(DEV, "drbd_try_rs_begin_io: sector=%llus\n",
- (unsigned long long)sector);
- );
+ trace_drbd_resync(mdev, TRACE_LVL_ALL, "drbd_try_rs_begin_io: sector=%llus\n",
+ (unsigned long long)sector);
spin_lock_irq(&mdev->al_lock);
if (mdev->resync_wenr != LC_FREE && mdev->resync_wenr != enr) {
@@ -1203,10 +1196,11 @@ int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
* the lc_put here...
* we also have to wake_up
*/
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_ALL,
- dev_info(DEV, "dropping %u, aparently got 'synced' "
- "by application io\n", mdev->resync_wenr);
- );
+
+ trace_drbd_resync(mdev, TRACE_LVL_ALL,
+ "dropping %u, aparently got 'synced' by application io\n",
+ mdev->resync_wenr);
+
bm_ext = (struct bm_extent *)
lc_find(mdev->resync, mdev->resync_wenr);
if (bm_ext) {
@@ -1232,18 +1226,18 @@ int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
* but then could not set BME_LOCKED,
* so we tried again.
* drop the extra reference. */
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_ALL,
- dev_info(DEV, "dropping extra reference on %u\n", enr);
- );
+ trace_drbd_resync(mdev, TRACE_LVL_ALL,
+ "dropping extra reference on %u\n", enr);
+
bm_ext->lce.refcnt--;
D_ASSERT(bm_ext->lce.refcnt > 0);
}
goto check_al;
} else {
if (mdev->resync_locked > mdev->resync->nr_elements-3) {
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_ALL,
- dev_info(DEV, "resync_locked = %u!\n", mdev->resync_locked);
- );
+ trace_drbd_resync(mdev, TRACE_LVL_ALL,
+ "resync_locked = %u!\n", mdev->resync_locked);
+
goto try_again;
}
bm_ext = (struct bm_extent *)lc_get(mdev->resync, enr);
@@ -1268,9 +1262,8 @@ int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
goto check_al;
}
check_al:
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_ALL,
- dev_info(DEV, "checking al for %u\n", enr);
- );
+ trace_drbd_resync(mdev, TRACE_LVL_ALL, "checking al for %u\n", enr);
+
for (i = 0; i < AL_EXT_PER_BM_SECT; i++) {
if (unlikely(al_enr+i == mdev->act_log->new_number))
goto try_again;
@@ -1284,9 +1277,7 @@ proceed:
return 0;
try_again:
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_ALL,
- dev_info(DEV, "need to try again for %u\n", enr);
- );
+ trace_drbd_resync(mdev, TRACE_LVL_ALL, "need to try again for %u\n", enr);
if (bm_ext)
mdev->resync_wenr = enr;
spin_unlock_irq(&mdev->al_lock);
@@ -1299,10 +1290,9 @@ void drbd_rs_complete_io(struct drbd_conf *mdev, sector_t sector)
struct bm_extent *bm_ext;
unsigned long flags;
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_ALL,
- dev_info(DEV, "drbd_rs_complete_io: sector=%llus (rs_enr=%d)\n",
- (long long)sector, enr);
- );
+ trace_drbd_resync(mdev, TRACE_LVL_ALL,
+ "drbd_rs_complete_io: sector=%llus (rs_enr=%d)\n",
+ (long long)sector, enr);
spin_lock_irqsave(&mdev->al_lock, flags);
bm_ext = (struct bm_extent *) lc_find(mdev->resync, enr);
@@ -1336,9 +1326,7 @@ void drbd_rs_complete_io(struct drbd_conf *mdev, sector_t sector)
*/
void drbd_rs_cancel_all(struct drbd_conf *mdev)
{
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_METRICS,
- dev_info(DEV, "drbd_rs_cancel_all\n");
- );
+ trace_drbd_resync(mdev, TRACE_LVL_METRICS, "drbd_rs_cancel_all\n");
spin_lock_irq(&mdev->al_lock);
@@ -1363,9 +1351,7 @@ int drbd_rs_del_all(struct drbd_conf *mdev)
struct bm_extent *bm_ext;
int i;
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_METRICS,
- dev_info(DEV, "drbd_rs_del_all\n");
- );
+ trace_drbd_resync(mdev, TRACE_LVL_METRICS, "drbd_rs_del_all\n");
spin_lock_irq(&mdev->al_lock);
@@ -1417,10 +1403,9 @@ void drbd_rs_failed_io(struct drbd_conf *mdev, sector_t sector, int size)
sector_t esector, nr_sectors;
int wake_up = 0;
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_SUMMARY,
- dev_info(DEV, "drbd_rs_failed_io: sector=%llus, size=%u\n",
- (unsigned long long)sector, size);
- );
+ trace_drbd_resync(mdev, TRACE_LVL_SUMMARY,
+ "drbd_rs_failed_io: sector=%llus, size=%u\n",
+ (unsigned long long)sector, size);
if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) {
dev_err(DEV, "drbd_rs_failed_io: sector=%llus size=%d nonsense!\n",
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 0614f2c96f15..c160f7ab9e01 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -842,11 +842,6 @@ STATIC int bm_rw(struct drbd_conf *mdev, int rw) __must_hold(local)
drbd_blk_run_queue(bdev_get_queue(mdev->bc->md_bdev));
wait_event(b->bm_io_wait, atomic_read(&b->bm_async_io) == 0);
- MTRACE(TRACE_TYPE_MD_IO, TRACE_LVL_SUMMARY,
- dev_info(DEV, "%s of bitmap took %lu jiffies\n",
- rw == READ ? "reading" : "writing", jiffies - now);
- );
-
if (test_bit(BM_MD_IO_ERROR, &b->bm_flags)) {
dev_alert(DEV, "we had at least one MD IO ERROR during bitmap IO\n");
drbd_chk_io_error(mdev, 1, TRUE);
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index ba43fa57b750..175de11d31e4 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -151,6 +151,8 @@ enum {
DRBD_FAULT_MAX,
};
+extern void trace_drbd_resync(struct drbd_conf *mdev, int level, const char *fmt, ...);
+
#ifdef DRBD_ENABLE_FAULTS
extern unsigned int
_drbd_insert_fault(struct drbd_conf *mdev, unsigned int type);
@@ -713,6 +715,19 @@ enum {
DE_IS_FINISHING,
};
+enum epoch_event {
+ EV_PUT,
+ EV_GOT_BARRIER_NR,
+ EV_BARRIER_DONE,
+ EV_BECAME_LAST,
+ EV_TRACE_FLUSH, /* TRACE_ are not real events, only used for tracing */
+ EV_TRACE_ADD_BARRIER, /* Doing the first write as a barrier write */
+ EV_TRACE_SETTING_BI, /* Barrier is expressed with the first write of the next epoch */
+ EV_TRACE_ALLOC,
+ EV_TRACE_FREE,
+ EV_CLEANUP = 32, /* used as flag */
+};
+
struct drbd_epoch_entry {
struct drbd_work w;
struct drbd_conf *mdev;
@@ -1350,117 +1365,7 @@ extern rwlock_t global_state_lock;
extern struct drbd_conf *drbd_new_device(unsigned int minor);
extern void drbd_free_mdev(struct drbd_conf *mdev);
-/* Dynamic tracing framework */
-#ifdef ENABLE_DYNAMIC_TRACE
-
extern int proc_details;
-extern int trace_type;
-extern int trace_devs;
-extern int trace_level;
-
-enum {
- TRACE_LVL_ALWAYS = 0,
- TRACE_LVL_SUMMARY,
- TRACE_LVL_METRICS,
- TRACE_LVL_ALL,
- TRACE_LVL_MAX
-};
-
-enum {
- TRACE_TYPE_PACKET = 0x00000001,
- TRACE_TYPE_RQ = 0x00000002,
- TRACE_TYPE_UUID = 0x00000004,
- TRACE_TYPE_RESYNC = 0x00000008,
- TRACE_TYPE_EE = 0x00000010,
- TRACE_TYPE_UNPLUG = 0x00000020,
- TRACE_TYPE_NL = 0x00000040,
- TRACE_TYPE_AL_EXTS = 0x00000080,
- TRACE_TYPE_INT_RQ = 0x00000100,
- TRACE_TYPE_MD_IO = 0x00000200,
- TRACE_TYPE_EPOCHS = 0x00000400,
-};
-
-static inline int
-is_trace(unsigned int type, unsigned int level) {
- return (trace_level >= level) && (type & trace_type);
-}
-static inline int
-is_mdev_trace(struct drbd_conf *mdev, unsigned int type, unsigned int level) {
- return is_trace(type, level) &&
- ((1 << mdev_to_minor(mdev)) & trace_devs);
-}
-
-#define MTRACE(type, lvl, code...) \
-do { \
- if (unlikely(is_mdev_trace(mdev, type, lvl))) { \
- code \
- } \
-} while (0)
-
-#define TRACE(type, lvl, code...) \
-do { \
- if (unlikely(is_trace(type, lvl))) { \
- code \
- } \
-} while (0)
-
-/* Buffer printing support
- * dbg_print_flags: used for Flags arg to drbd_print_buffer
- * - DBGPRINT_BUFFADDR; if set, each line starts with the
- * virtual address of the line being output. If clear,
- * each line starts with the offset from the beginning
- * of the buffer. */
-enum dbg_print_flags {
- DBGPRINT_BUFFADDR = 0x0001,
-};
-
-extern void drbd_print_uuid(struct drbd_conf *mdev, unsigned int idx);
-
-extern void drbd_print_buffer(const char *prefix, unsigned int flags, int size,
- const void *buffer, const void *buffer_va,
- unsigned int length);
-
-/* Bio printing support */
-extern void _dump_bio(const char *pfx, struct drbd_conf *mdev, struct bio *bio, int complete, struct drbd_request *r);
-
-static inline void dump_bio(struct drbd_conf *mdev,
- struct bio *bio, int complete, struct drbd_request *r)
-{
- MTRACE(TRACE_TYPE_RQ, TRACE_LVL_SUMMARY,
- _dump_bio("Rq", mdev, bio, complete, r);
- );
-}
-
-static inline void dump_internal_bio(const char *pfx, struct drbd_conf *mdev, struct bio *bio, int complete)
-{
- MTRACE(TRACE_TYPE_INT_RQ, TRACE_LVL_SUMMARY,
- _dump_bio(pfx, mdev, bio, complete, NULL);
- );
-}
-
-/* Packet dumping support */
-extern void _dump_packet(struct drbd_conf *mdev, struct socket *sock,
- int recv, union p_polymorph *p,
- char *file, int line);
-
-static inline void
-dump_packet(struct drbd_conf *mdev, struct socket *sock,
- int recv, union p_polymorph *p, char *file, int line)
-{
- MTRACE(TRACE_TYPE_PACKET, TRACE_LVL_SUMMARY,
- _dump_packet(mdev, sock, recv, p, file, line);
- );
-}
-
-#else
-
-#define MTRACE(ignored...) ((void)0)
-#define TRACE(ignored...) ((void)0)
-
-#define dump_bio(ignored...) ((void)0)
-#define dump_internal_bio(ignored...) ((void)0)
-#define dump_packet(ignored...) ((void)0)
-#endif
/* drbd_req */
extern int drbd_make_request_26(struct request_queue *q, struct bio *bio);
@@ -2237,11 +2142,6 @@ static inline void dec_ap_bio(struct drbd_conf *mdev)
static inline void drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val)
{
mdev->ed_uuid = val;
-
- MTRACE(TRACE_TYPE_UUID, TRACE_LVL_METRICS,
- dev_info(DEV, " exposed data uuid now %016llX\n",
- (unsigned long long)val);
- );
}
static inline int seq_cmp(u32 a, u32 b)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 79cb0183f817..4a2593ce1d37 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -53,6 +53,7 @@
#include <linux/drbd.h>
#include <linux/drbd_limits.h>
#include "drbd_int.h"
+#include "drbd_tracing.h"
#include "drbd_req.h" /* only for _req_mod in tl_release and tl_clear */
#include "drbd_vli.h"
@@ -79,6 +80,18 @@ STATIC int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused);
STATIC void md_sync_timer_fn(unsigned long data);
STATIC int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused);
+DEFINE_TRACE(drbd_unplug);
+DEFINE_TRACE(drbd_uuid);
+DEFINE_TRACE(drbd_ee);
+DEFINE_TRACE(drbd_packet);
+DEFINE_TRACE(drbd_md_io);
+DEFINE_TRACE(drbd_epoch);
+DEFINE_TRACE(drbd_netlink);
+DEFINE_TRACE(drbd_actlog);
+DEFINE_TRACE(drbd_bio);
+DEFINE_TRACE(_drbd_resync);
+DEFINE_TRACE(drbd_req);
+
MODULE_AUTHOR("Philipp Reisner <phil@linbit.com>, "
"Lars Ellenberg <lars@linbit.com>");
MODULE_DESCRIPTION("drbd - Distributed Replicated Block Device v" REL_VERSION);
@@ -95,6 +108,7 @@ module_param(minor_count, uint, 0444);
module_param(disable_sendpage, bool, 0644);
module_param(allow_oos, bool, 0);
module_param(cn_idx, uint, 0444);
+module_param(proc_details, int, 0644);
#ifdef DRBD_ENABLE_FAULTS
int enable_faults;
@@ -116,19 +130,8 @@ unsigned int minor_count = 32;
int disable_sendpage;
int allow_oos;
unsigned int cn_idx = CN_IDX_DRBD;
-
-#ifdef ENABLE_DYNAMIC_TRACE
-int trace_type; /* UI_BITMAP of trace types to enable */
-int trace_level; /* UI_CURRENT trace level */
-int trace_devs; /* UI_BITMAP of devices to trace */
int proc_details; /* Detail level in proc drbd*/
-module_param(trace_level, int, 0644);
-module_param(trace_type, int, 0644);
-module_param(trace_devs, int, 0644);
-module_param(proc_details, int, 0644);
-#endif
-
/* Module parameter for setting the user mode helper program
* to run. Default is /sbin/drbdadm */
char usermode_helper[80] = "/sbin/drbdadm";
@@ -1458,7 +1461,7 @@ int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock,
h->command = cpu_to_be16(cmd);
h->length = cpu_to_be16(size-sizeof(struct p_header));
- dump_packet(mdev, sock, 0, (void *)h, __FILE__, __LINE__);
+ trace_drbd_packet(mdev, sock, 0, (void *)h, __FILE__, __LINE__);
sent = drbd_send(mdev, sock, h, size, msg_flags);
ok = (sent == size);
@@ -1510,7 +1513,7 @@ int drbd_send_cmd2(struct drbd_conf *mdev, enum drbd_packets cmd, char *data,
if (!drbd_get_data_sock(mdev))
return 0;
- dump_packet(mdev, mdev->data.socket, 0, (void *)&h, __FILE__, __LINE__);
+ trace_drbd_packet(mdev, mdev->data.socket, 0, (void *)&h, __FILE__, __LINE__);
ok = (sizeof(h) ==
drbd_send(mdev, mdev->data.socket, &h, sizeof(h), 0));
@@ -2227,7 +2230,7 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
dp_flags |= DP_MAY_SET_IN_SYNC;
p.dp_flags = cpu_to_be32(dp_flags);
- dump_packet(mdev, mdev->data.socket, 0, (void *)&p, __FILE__, __LINE__);
+ trace_drbd_packet(mdev, mdev->data.socket, 0, (void *)&p, __FILE__, __LINE__);
set_bit(UNPLUG_REMOTE, &mdev->flags);
ok = (sizeof(p) ==
drbd_send(mdev, mdev->data.socket, &p, sizeof(p), MSG_MORE));
@@ -2278,7 +2281,7 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
if (!drbd_get_data_sock(mdev))
return 0;
- dump_packet(mdev, mdev->data.socket, 0, (void *)&p, __FILE__, __LINE__);
+ trace_drbd_packet(mdev, mdev->data.socket, 0, (void *)&p, __FILE__, __LINE__);
ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p,
sizeof(p), MSG_MORE);
if (ok && dgs) {
@@ -2414,10 +2417,7 @@ STATIC void drbd_unplug_fn(struct request_queue *q)
{
struct drbd_conf *mdev = q->queuedata;
- MTRACE(TRACE_TYPE_UNPLUG, TRACE_LVL_SUMMARY,
- dev_info(DEV, "got unplugged ap_bio_count=%d\n",
- atomic_read(&mdev->ap_bio_cnt));
- );
+ trace_drbd_unplug(mdev, "got unplugged");
/* unplug FIRST */
spin_lock_irq(q->queue_lock);
@@ -3098,9 +3098,7 @@ void drbd_md_sync(struct drbd_conf *mdev)
if (!inc_local_if_state(mdev, D_FAILED))
return;
- MTRACE(TRACE_TYPE_MD_IO, TRACE_LVL_SUMMARY,
- dev_info(DEV, "Writing meta data super block now.\n");
- );
+ trace_drbd_md_io(mdev, WRITE, mdev->bc);
mutex_lock(&mdev->md_io_mutex);
buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page);
@@ -3156,6 +3154,8 @@ int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
if (!inc_local_if_state(mdev, D_ATTACHING))
return ERR_IO_MD_DISK;
+ trace_drbd_md_io(mdev, READ, bdev);
+
mutex_lock(&mdev->md_io_mutex);
buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page);
@@ -3235,9 +3235,7 @@ STATIC void drbd_uuid_move_history(struct drbd_conf *mdev) __must_hold(local)
for (i = UI_HISTORY_START; i < UI_HISTORY_END; i++) {
mdev->bc->md.uuid[i+1] = mdev->bc->md.uuid[i];
- MTRACE(TRACE_TYPE_UUID, TRACE_LVL_ALL,
- drbd_print_uuid(mdev, i+1);
- );
+ trace_drbd_uuid(mdev, i+1);
}
}
@@ -3253,11 +3251,7 @@ void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local)
}
mdev->bc->md.uuid[idx] = val;
-
- MTRACE(TRACE_TYPE_UUID, TRACE_LVL_SUMMARY,
- drbd_print_uuid(mdev, idx);
- );
-
+ trace_drbd_uuid(mdev, idx);
drbd_md_mark_dirty(mdev);
}
@@ -3267,9 +3261,7 @@ void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local)
if (mdev->bc->md.uuid[idx]) {
drbd_uuid_move_history(mdev);
mdev->bc->md.uuid[UI_HISTORY_START] = mdev->bc->md.uuid[idx];
- MTRACE(TRACE_TYPE_UUID, TRACE_LVL_METRICS,
- drbd_print_uuid(mdev, UI_HISTORY_START);
- );
+ trace_drbd_uuid(mdev, UI_HISTORY_START);
}
_drbd_uuid_set(mdev, idx, val);
}
@@ -3286,9 +3278,7 @@ void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local)
dev_info(DEV, "Creating new current UUID\n");
D_ASSERT(mdev->bc->md.uuid[UI_BITMAP] == 0);
mdev->bc->md.uuid[UI_BITMAP] = mdev->bc->md.uuid[UI_CURRENT];
- MTRACE(TRACE_TYPE_UUID, TRACE_LVL_METRICS,
- drbd_print_uuid(mdev, UI_BITMAP);
- );
+ trace_drbd_uuid(mdev, UI_BITMAP);
get_random_bytes(&val, sizeof(u64));
_drbd_uuid_set(mdev, UI_CURRENT, val);
@@ -3303,11 +3293,8 @@ void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local)
drbd_uuid_move_history(mdev);
mdev->bc->md.uuid[UI_HISTORY_START] = mdev->bc->md.uuid[UI_BITMAP];
mdev->bc->md.uuid[UI_BITMAP] = 0;
-
- MTRACE(TRACE_TYPE_UUID, TRACE_LVL_METRICS,
- drbd_print_uuid(mdev, UI_HISTORY_START);
- drbd_print_uuid(mdev, UI_BITMAP);
- );
+ trace_drbd_uuid(mdev, UI_HISTORY_START);
+ trace_drbd_uuid(mdev, UI_BITMAP);
} else {
if (mdev->bc->md.uuid[UI_BITMAP])
dev_warn(DEV, "bm UUID already set");
@@ -3315,9 +3302,7 @@ void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local)
mdev->bc->md.uuid[UI_BITMAP] = val;
mdev->bc->md.uuid[UI_BITMAP] &= ~((u64)1);
- MTRACE(TRACE_TYPE_UUID, TRACE_LVL_METRICS,
- drbd_print_uuid(mdev, UI_BITMAP);
- );
+ trace_drbd_uuid(mdev, UI_BITMAP);
}
drbd_md_mark_dirty(mdev);
}
@@ -3553,415 +3538,5 @@ _drbd_insert_fault(struct drbd_conf *mdev, unsigned int type)
}
#endif
-#ifdef ENABLE_DYNAMIC_TRACE
-
-STATIC char *_drbd_uuid_str(unsigned int idx)
-{
- static char *uuid_str[] = {
- "Current",
- "Bitmap",
- "History_start",
- "History_end",
- "UUID_SIZE",
- "UUID_FLAGS",
- };
-
- return (idx < UI_EXTENDED_SIZE) ? uuid_str[idx] : "*Unknown UUID index*";
-}
-
-/* Pretty print a UUID value */
-void drbd_print_uuid(struct drbd_conf *mdev, unsigned int idx) __must_hold(local)
-{
- dev_info(DEV, " uuid[%s] now %016llX\n",
- _drbd_uuid_str(idx), (unsigned long long)mdev->bc->md.uuid[idx]);
-}
-
-
-/*
- *
- * drbd_print_buffer
- *
- * This routine dumps binary data to the debugging output. Can be
- * called at interrupt level.
- *
- * Arguments:
- *
- * prefix - String is output at the beginning of each line output
- * flags - Control operation of the routine. Currently defined
- * Flags are:
- * DBGPRINT_BUFFADDR; if set, each line starts with the
- * virtual address of the line being outupt. If clear,
- * each line starts with the offset from the beginning
- * of the buffer.
- * size - Indicates the size of each entry in the buffer. Supported
- * values are sizeof(char), sizeof(short) and sizeof(int)
- * buffer - Start address of buffer
- * buffer_va - Virtual address of start of buffer (normally the same
- * as Buffer, but having it separate allows it to hold
- * file address for example)
- * length - length of buffer
- *
- */
-void
-drbd_print_buffer(const char *prefix, unsigned int flags, int size,
- const void *buffer, const void *buffer_va,
- unsigned int length)
-
-#define LINE_SIZE 16
-#define LINE_ENTRIES (int)(LINE_SIZE/size)
-{
- const unsigned char *pstart;
- const unsigned char *pstart_va;
- const unsigned char *pend;
- char bytes_str[LINE_SIZE*3+8], ascii_str[LINE_SIZE+8];
- char *pbytes = bytes_str, *pascii = ascii_str;
- int offset = 0;
- long sizemask;
- int field_width;
- int index;
- const unsigned char *pend_str;
- const unsigned char *p;
- int count;
-
- /* verify size parameter */
- if (size != sizeof(char) &&
- size != sizeof(short) &&
- size != sizeof(int)) {
- printk(KERN_DEBUG "drbd_print_buffer: "
- "ERROR invalid size %d\n", size);
- return;
- }
-
- sizemask = size-1;
- field_width = size*2;
-
- /* Adjust start/end to be on appropriate boundary for size */
- buffer = (const char *)((long)buffer & ~sizemask);
- pend = (const unsigned char *)
- (((long)buffer + length + sizemask) & ~sizemask);
-
- if (flags & DBGPRINT_BUFFADDR) {
- /* Move start back to nearest multiple of line size,
- * if printing address. This results in nicely formatted output
- * with addresses being on line size (16) byte boundaries */
- pstart = (const unsigned char *)((long)buffer & ~(LINE_SIZE-1));
- } else {
- pstart = (const unsigned char *)buffer;
- }
-
- /* Set value of start VA to print if addresses asked for */
- pstart_va = (const unsigned char *)buffer_va
- - ((const unsigned char *)buffer-pstart);
-
- /* Calculate end position to nicely align right hand side */
- pend_str = pstart + (((pend-pstart) + LINE_SIZE-1) & ~(LINE_SIZE-1));
-
- /* Init strings */
- *pbytes = *pascii = '\0';
-
- /* Start at beginning of first line */
- p = pstart;
- count = 0;
-
- while (p < pend_str) {
- if (p < (const unsigned char *)buffer || p >= pend) {
- /* Before start of buffer or after end- print spaces */
- pbytes += sprintf(pbytes, "%*c ", field_width, ' ');
- pascii += sprintf(pascii, "%*c", size, ' ');
- p += size;
- } else {
- /* Add hex and ascii to strings */
- int val;
- switch (size) {
- default:
- case 1:
- val = *(unsigned char *)p;
- break;
- case 2:
- val = *(unsigned short *)p;
- break;
- case 4:
- val = *(unsigned int *)p;
- break;
- }
-
- pbytes += sprintf(pbytes, "%0*x ", field_width, val);
-
- for (index = size; index; index--) {
- *pascii++ = isprint(*p) ? *p : '.';
- p++;
- }
- }
-
- count++;
-
- if (count == LINE_ENTRIES || p >= pend_str) {
- /* Null terminate and print record */
- *pascii = '\0';
- printk(KERN_DEBUG "%s%8.8lx: %*s|%*s|\n",
- prefix,
- (flags & DBGPRINT_BUFFADDR)
- ? (long)pstart_va:(long)offset,
- LINE_ENTRIES*(field_width+1), bytes_str,
- LINE_SIZE, ascii_str);
-
- /* Move onto next line */
- pstart_va += (p-pstart);
- pstart = p;
- count = 0;
- offset += LINE_SIZE;
-
- /* Re-init strings */
- pbytes = bytes_str;
- pascii = ascii_str;
- *pbytes = *pascii = '\0';
- }
- }
-}
-
-#define PSM(A) \
-do { \
- if (mask.A) { \
- int i = snprintf(p, len, " " #A "( %s )", \
- A##s_to_name(val.A)); \
- if (i >= len) \
- return op; \
- p += i; \
- len -= i; \
- } \
-} while (0)
-
-STATIC char *dump_st(char *p, int len, union drbd_state mask, union drbd_state val)
-{
- char *op = p;
- *p = '\0';
- PSM(role);
- PSM(peer);
- PSM(conn);
- PSM(disk);
- PSM(pdsk);
-
- return op;
-}
-
-#define INFOP(fmt, args...) \
-do { \
- if (trace_level >= TRACE_LVL_ALL) { \
- dev_info(DEV, "%s:%d: %s [%d] %s %s " fmt , \
- file, line, current->comm, current->pid, \
- sockname, recv ? "<<<" : ">>>" , \
- ## args); \
- } else { \
- dev_info(DEV, "%s %s " fmt, sockname, \
- recv ? "<<<" : ">>>" , \
- ## args); \
- } \
-} while (0)
-
-STATIC char *_dump_block_id(u64 block_id, char *buff)
-{
- if (is_syncer_block_id(block_id))
- strcpy(buff, "SyncerId");
- else
- sprintf(buff, "%llx", (unsigned long long)block_id);
-
- return buff;
-}
-
-void
-_dump_packet(struct drbd_conf *mdev, struct socket *sock,
- int recv, union p_polymorph *p, char *file, int line)
-{
- char *sockname = sock == mdev->meta.socket ? "meta" : "data";
- int cmd = (recv == 2) ? p->header.command : be16_to_cpu(p->header.command);
- char tmp[300];
- union drbd_state m, v;
-
- switch (cmd) {
- case P_HAND_SHAKE:
- INFOP("%s (protocol %u-%u)\n", cmdname(cmd),
- be32_to_cpu(p->handshake.protocol_min),
- be32_to_cpu(p->handshake.protocol_max));
- break;
-
- case P_BITMAP: /* don't report this */
- case P_COMPRESSED_BITMAP: /* don't report this */
- break;
-
- case P_DATA:
- INFOP("%s (sector %llus, id %s, seq %u, f %x)\n", cmdname(cmd),
- (unsigned long long)be64_to_cpu(p->data.sector),
- _dump_block_id(p->data.block_id, tmp),
- be32_to_cpu(p->data.seq_num),
- be32_to_cpu(p->data.dp_flags)
- );
- break;
-
- case P_DATA_REPLY:
- case P_RS_DATA_REPLY:
- INFOP("%s (sector %llus, id %s)\n", cmdname(cmd),
- (unsigned long long)be64_to_cpu(p->data.sector),
- _dump_block_id(p->data.block_id, tmp)
- );
- break;
-
- case P_RECV_ACK:
- case P_WRITE_ACK:
- case P_RS_WRITE_ACK:
- case P_DISCARD_ACK:
- case P_NEG_ACK:
- case P_NEG_RS_DREPLY:
- INFOP("%s (sector %llus, size %u, id %s, seq %u)\n",
- cmdname(cmd),
- (long long)be64_to_cpu(p->block_ack.sector),
- be32_to_cpu(p->block_ack.blksize),
- _dump_block_id(p->block_ack.block_id, tmp),
- be32_to_cpu(p->block_ack.seq_num)
- );
- break;
-
- case P_DATA_REQUEST:
- case P_RS_DATA_REQUEST:
- INFOP("%s (sector %llus, size %u, id %s)\n", cmdname(cmd),
- (long long)be64_to_cpu(p->block_req.sector),
- be32_to_cpu(p->block_req.blksize),
- _dump_block_id(p->block_req.block_id, tmp)
- );
- break;
-
- case P_BARRIER:
- case P_BARRIER_ACK:
- INFOP("%s (barrier %u)\n", cmdname(cmd), p->barrier.barrier);
- break;
-
- case P_SYNC_PARAM:
- case P_SYNC_PARAM89:
- INFOP("%s (rate %u, verify-alg \"%.64s\", csums-alg \"%.64s\")\n",
- cmdname(cmd), be32_to_cpu(p->rs_param_89.rate),
- p->rs_param_89.verify_alg, p->rs_param_89.csums_alg);
- break;
-
- case P_UUIDS:
- INFOP("%s Curr:%016llX, Bitmap:%016llX, "
- "HisSt:%016llX, HisEnd:%016llX\n",
- cmdname(cmd),
- (unsigned long long)be64_to_cpu(p->uuids.uuid[UI_CURRENT]),
- (unsigned long long)be64_to_cpu(p->uuids.uuid[UI_BITMAP]),
- (unsigned long long)be64_to_cpu(p->uuids.uuid[UI_HISTORY_START]),
- (unsigned long long)be64_to_cpu(p->uuids.uuid[UI_HISTORY_END]));
- break;
-
- case P_SIZES:
- INFOP("%s (d %lluMiB, u %lluMiB, c %lldMiB, "
- "max bio %x, q order %x)\n",
- cmdname(cmd),
- (long long)(be64_to_cpu(p->sizes.d_size)>>(20-9)),
- (long long)(be64_to_cpu(p->sizes.u_size)>>(20-9)),
- (long long)(be64_to_cpu(p->sizes.c_size)>>(20-9)),
- be32_to_cpu(p->sizes.max_segment_size),
- be32_to_cpu(p->sizes.queue_order_type));
- break;
-
- case P_STATE:
- v.i = be32_to_cpu(p->state.state);
- m.i = 0xffffffff;
- dump_st(tmp, sizeof(tmp), m, v);
- INFOP("%s (s %x {%s})\n", cmdname(cmd), v.i, tmp);
- break;
-
- case P_STATE_CHG_REQ:
- m.i = be32_to_cpu(p->req_state.mask);
- v.i = be32_to_cpu(p->req_state.val);
- dump_st(tmp, sizeof(tmp), m, v);
- INFOP("%s (m %x v %x {%s})\n", cmdname(cmd), m.i, v.i, tmp);
- break;
-
- case P_STATE_CHG_REPLY:
- INFOP("%s (ret %x)\n", cmdname(cmd),
- be32_to_cpu(p->req_state_reply.retcode));
- break;
-
- case P_PING:
- case P_PING_ACK:
- /*
- * Dont trace pings at summary level
- */
- if (trace_level < TRACE_LVL_ALL)
- break;
- /* fall through... */
- default:
- INFOP("%s (%u)\n", cmdname(cmd), cmd);
- break;
- }
-}
-
-/* Debug routine to dump info about bio */
-
-void _dump_bio(const char *pfx, struct drbd_conf *mdev, struct bio *bio, int complete, struct drbd_request *r)
-{
-#ifdef CONFIG_LBD
-#define SECTOR_FORMAT "%Lx"
-#else
-#define SECTOR_FORMAT "%lx"
-#endif
-#define SECTOR_SHIFT 9
-
- unsigned long lowaddr = (unsigned long)(bio->bi_sector << SECTOR_SHIFT);
- char *faddr = (char *)(lowaddr);
- char rb[sizeof(void *)*2+6] = { 0, };
- struct bio_vec *bvec;
- int segno;
-
- const int rw = bio->bi_rw;
- const int biorw = (rw & (RW_MASK|RWA_MASK));
- const int biobarrier = (rw & (1<<BIO_RW_BARRIER));
- const int biosync = (rw & ((1<<BIO_RW_UNPLUG) | (1<<BIO_RW_SYNCIO)));
-
- if (r)
- sprintf(rb, "Req:%p ", r);
-
- dev_info(DEV, "%s %s:%s%s%s Bio:%p %s- %soffset " SECTOR_FORMAT ", size %x\n",
- complete ? "<<<" : ">>>",
- pfx,
- biorw == WRITE ? "Write" : "Read",
- biobarrier ? " : B" : "",
- biosync ? " : S" : "",
- bio,
- rb,
- complete ? (drbd_bio_uptodate(bio) ? "Success, " : "Failed, ") : "",
- bio->bi_sector << SECTOR_SHIFT,
- bio->bi_size);
-
- if (trace_level >= TRACE_LVL_METRICS &&
- ((biorw == WRITE) ^ complete)) {
- printk(KERN_DEBUG " ind page offset length\n");
- __bio_for_each_segment(bvec, bio, segno, 0) {
- printk(KERN_DEBUG " [%d] %p %8.8x %8.8x\n", segno,
- bvec->bv_page, bvec->bv_offset, bvec->bv_len);
-
- if (trace_level >= TRACE_LVL_ALL) {
- char *bvec_buf;
- unsigned long flags;
-
- bvec_buf = bvec_kmap_irq(bvec, &flags);
-
- drbd_print_buffer(" ", DBGPRINT_BUFFADDR, 1,
- bvec_buf,
- faddr,
- (bvec->bv_len <= 0x80)
- ? bvec->bv_len : 0x80);
-
- bvec_kunmap_irq(bvec_buf, &flags);
-
- if (bvec->bv_len > 0x40)
- printk(KERN_DEBUG " ....\n");
-
- faddr += bvec->bv_len;
- }
- }
- }
-}
-#endif
-
module_init(drbd_init)
module_exit(drbd_cleanup)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index c72c5adbbfd6..c388478a0188 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -34,8 +34,8 @@
#include <linux/drbd.h>
#include <linux/blkpg.h>
#include <linux/cpumask.h>
-
#include "drbd_int.h"
+#include "drbd_tracing.h"
#include "drbd_wrappers.h"
#include <linux/drbd_tag_magic.h>
#include <linux/drbd_limits.h>
@@ -124,51 +124,6 @@ name ## _to_tags(struct drbd_conf *mdev, \
void drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name);
void drbd_nl_send_reply(struct cn_msg *, int);
-STATIC char *nl_packet_name(int packet_type)
-{
-/* Generate packet type strings */
-#define NL_PACKET(name, number, fields) \
- [P_ ## name] = # name,
-#define NL_INTEGER Argh!
-#define NL_BIT Argh!
-#define NL_INT64 Argh!
-#define NL_STRING Argh!
-
- static char *nl_tag_name[P_nl_after_last_packet] = {
-#include "linux/drbd_nl.h"
- };
-
- return (packet_type < sizeof(nl_tag_name)/sizeof(nl_tag_name[0])) ?
- nl_tag_name[packet_type] : "*Unknown*";
-}
-
-STATIC void nl_trace_packet(void *data)
-{
- struct cn_msg *req = data;
- struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req *)req->data;
-
- printk(KERN_INFO "drbd%d: "
- "Netlink: << %s (%d) - seq: %x, ack: %x, len: %x\n",
- nlp->drbd_minor,
- nl_packet_name(nlp->packet_type),
- nlp->packet_type,
- req->seq, req->ack, req->len);
-}
-
-STATIC void nl_trace_reply(void *data)
-{
- struct cn_msg *req = data;
- struct drbd_nl_cfg_reply *nlp = (struct drbd_nl_cfg_reply *)req->data;
-
- printk(KERN_INFO "drbd%d: "
- "Netlink: >> %s (%d) - seq: %x, ack: %x, len: %x\n",
- nlp->minor,
- nlp->packet_type == P_nl_after_last_packet ?
- "Empty-Reply" : nl_packet_name(nlp->packet_type),
- nlp->packet_type,
- req->seq, req->ack, req->len);
-}
-
int drbd_khelper(struct drbd_conf *mdev, char *cmd)
{
char mb[12];
@@ -711,15 +666,6 @@ void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_seg_s) __mu
max_seg_s = min(b->max_sectors * b->hardsect_size, max_seg_s);
- MTRACE(TRACE_TYPE_RQ, TRACE_LVL_SUMMARY,
- DUMPI(b->max_sectors);
- DUMPI(b->max_phys_segments);
- DUMPI(b->max_hw_segments);
- DUMPI(b->max_segment_size);
- DUMPI(b->hardsect_size);
- DUMPI(b->seg_boundary_mask);
- );
-
q->max_sectors = max_seg_s >> 9;
if (max_segments) {
q->max_phys_segments = max_segments;
@@ -733,15 +679,6 @@ void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_seg_s) __mu
q->seg_boundary_mask = PAGE_SIZE-1;
blk_queue_stack_limits(q, b);
- MTRACE(TRACE_TYPE_RQ, TRACE_LVL_SUMMARY,
- DUMPI(q->max_sectors);
- DUMPI(q->max_phys_segments);
- DUMPI(q->max_hw_segments);
- DUMPI(q->max_segment_size);
- DUMPI(q->hardsect_size);
- DUMPI(q->seg_boundary_mask);
- );
-
if (b->merge_bvec_fn)
dev_warn(DEV, "Backing device's merge_bvec_fn() = %p\n",
b->merge_bvec_fn);
@@ -2055,7 +1992,7 @@ STATIC void drbd_connector_callback(void *data)
goto fail;
}
- TRACE(TRACE_TYPE_NL, TRACE_LVL_SUMMARY, nl_trace_packet(data););
+ trace_drbd_netlink(data, 1);
if (nlp->packet_type >= P_nl_after_last_packet) {
retcode = ERR_PACKET_NR;
@@ -2093,8 +2030,7 @@ STATIC void drbd_connector_callback(void *data)
cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + rr;
cn_reply->flags = 0;
- TRACE(TRACE_TYPE_NL, TRACE_LVL_SUMMARY, nl_trace_reply(cn_reply););
-
+ trace_drbd_netlink(cn_reply, 0);
rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
if (rr && rr != -ESRCH)
printk(KERN_INFO "drbd: cn_netlink_send()=%d\n", rr);
@@ -2193,8 +2129,7 @@ void drbd_bcast_state(struct drbd_conf *mdev, union drbd_state state)
reply->minor = mdev_to_minor(mdev);
reply->ret_code = NO_ERROR;
- TRACE(TRACE_TYPE_NL, TRACE_LVL_SUMMARY, nl_trace_reply(cn_reply););
-
+ trace_drbd_netlink(cn_reply, 0);
cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
}
@@ -2232,8 +2167,7 @@ void drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name)
reply->minor = mdev_to_minor(mdev);
reply->ret_code = NO_ERROR;
- TRACE(TRACE_TYPE_NL, TRACE_LVL_SUMMARY, nl_trace_reply(cn_reply););
-
+ trace_drbd_netlink(cn_reply, 0);
cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
}
@@ -2302,8 +2236,7 @@ void drbd_bcast_ee(struct drbd_conf *mdev,
reply->minor = mdev_to_minor(mdev);
reply->ret_code = NO_ERROR;
- TRACE(TRACE_TYPE_NL, TRACE_LVL_SUMMARY, nl_trace_reply(cn_reply););
-
+ trace_drbd_netlink(cn_reply, 0);
cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
kfree(cn_reply);
}
@@ -2346,8 +2279,7 @@ void drbd_bcast_sync_progress(struct drbd_conf *mdev)
reply->minor = mdev_to_minor(mdev);
reply->ret_code = NO_ERROR;
- TRACE(TRACE_TYPE_NL, TRACE_LVL_SUMMARY, nl_trace_reply(cn_reply););
-
+ trace_drbd_netlink(cn_reply, 0);
cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
}
@@ -2401,8 +2333,7 @@ void drbd_nl_send_reply(struct cn_msg *req, int ret_code)
reply->minor = ((struct drbd_nl_cfg_req *)req->data)->drbd_minor;
reply->ret_code = ret_code;
- TRACE(TRACE_TYPE_NL, TRACE_LVL_SUMMARY, nl_trace_reply(cn_reply););
-
+ trace_drbd_netlink(cn_reply, 0);
rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
if (rr && rr != -ESRCH)
printk(KERN_INFO "drbd: cn_netlink_send()=%d\n", rr);
diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c
index 76b512180606..7de68d9d6aba 100644
--- a/drivers/block/drbd/drbd_proc.c
+++ b/drivers/block/drbd/drbd_proc.c
@@ -135,7 +135,6 @@ STATIC void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq)
seq_printf(seq, " K/sec\n");
}
-#ifdef ENABLE_DYNAMIC_TRACE
STATIC void resync_dump_detail(struct seq_file *seq, struct lc_element *e)
{
struct bm_extent *bme = (struct bm_extent *)e;
@@ -145,7 +144,6 @@ STATIC void resync_dump_detail(struct seq_file *seq, struct lc_element *e)
bme->flags & BME_LOCKED ? "LOCKED" : "------"
);
}
-#endif
STATIC int drbd_seq_show(struct seq_file *seq, void *v)
{
@@ -245,7 +243,6 @@ STATIC int drbd_seq_show(struct seq_file *seq, void *v)
mdev->rs_total - mdev->ov_left,
mdev->rs_total);
-#ifdef ENABLE_DYNAMIC_TRACE
if (proc_details >= 1 && inc_local_if_state(mdev, D_FAILED)) {
lc_printf_stats(seq, mdev->resync);
lc_printf_stats(seq, mdev->act_log);
@@ -258,7 +255,6 @@ STATIC int drbd_seq_show(struct seq_file *seq, void *v)
resync_dump_detail);
}
}
-#endif
}
return 0;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 078ce728a2fc..077480fe6923 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -49,6 +49,7 @@
#include <linux/scatterlist.h>
#include <linux/drbd.h>
#include "drbd_int.h"
+#include "drbd_tracing.h"
#include "drbd_req.h"
#include "drbd_vli.h"
@@ -58,14 +59,6 @@ struct flush_work {
struct drbd_epoch *epoch;
};
-enum epoch_event {
- EV_PUT,
- EV_GOT_BARRIER_NR,
- EV_BARRIER_DONE,
- EV_BECAME_LAST,
- EV_CLEANUP = 32, /* used as flag */
-};
-
enum finish_epoch {
FE_STILL_LIVE,
FE_DESTROYED,
@@ -284,10 +277,7 @@ struct drbd_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev,
e->epoch = NULL;
e->flags = 0;
- MTRACE(TRACE_TYPE_EE, TRACE_LVL_ALL,
- dev_info(DEV, "allocated EE sec=%llus size=%u ee=%p\n",
- (unsigned long long)sector, data_size, e);
- );
+ trace_drbd_ee(mdev, e, "allocated");
return e;
@@ -308,10 +298,7 @@ void drbd_free_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e)
struct bio_vec *bvec;
int i;
- MTRACE(TRACE_TYPE_EE, TRACE_LVL_ALL,
- dev_info(DEV, "Free EE sec=%llus size=%u ee=%p\n",
- (unsigned long long)e->sector, e->size, e);
- );
+ trace_drbd_ee(mdev, e, "freed");
__bio_for_each_segment(bvec, bio, i, 0) {
drbd_pp_free(mdev, bvec->bv_page);
@@ -390,10 +377,7 @@ STATIC int drbd_process_done_ee(struct drbd_conf *mdev)
* all ignore the last argument.
*/
list_for_each_entry_safe(e, t, &work_list, w.list) {
- MTRACE(TRACE_TYPE_EE, TRACE_LVL_ALL,
- dev_info(DEV, "Process EE on done_ee sec=%llus size=%u ee=%p\n",
- (unsigned long long)e->sector, e->size, e);
- );
+ trace_drbd_ee(mdev, e, "process_done_ee");
/* list_del not necessary, next/prev members not touched */
if (e->w.cb(mdev, &e->w, 0) == 0)
ok = 0;
@@ -998,13 +982,6 @@ STATIC enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,
int schedule_flush = 0;
enum finish_epoch rv = FE_STILL_LIVE;
- static char *epoch_event_str[] = {
- [EV_PUT] = "put",
- [EV_GOT_BARRIER_NR] = "got_barrier_nr",
- [EV_BARRIER_DONE] = "barrier_done",
- [EV_BECAME_LAST] = "became_last",
- };
-
spin_lock(&mdev->epoch_lock);
do {
next_epoch = NULL;
@@ -1034,15 +1011,7 @@ STATIC enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,
break;
}
- MTRACE(TRACE_TYPE_EPOCHS, TRACE_LVL_ALL,
- dev_info(DEV, "Update epoch %p/%d { size=%d active=%d %c%c n%c%c } ev=%s\n",
- epoch, epoch->barrier_nr, epoch_size, atomic_read(&epoch->active),
- test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) ? 'n' : '-',
- test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags) ? 'b' : '-',
- test_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags) ? 'i' : '-',
- test_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags) ? 'd' : '-',
- epoch_event_str[ev]);
- );
+ trace_drbd_epoch(mdev, epoch, ev);
if (epoch_size != 0 &&
atomic_read(&epoch->active) == 0 &&
@@ -1075,10 +1044,7 @@ STATIC enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,
list_del(&epoch->list);
ev = EV_BECAME_LAST | (ev & EV_CLEANUP);
mdev->epochs--;
- MTRACE(TRACE_TYPE_EPOCHS, TRACE_LVL_SUMMARY,
- dev_info(DEV, "Freeing epoch %p/%d { size=%d } nr_epochs=%d\n",
- epoch, epoch->barrier_nr, epoch_size, mdev->epochs);
- );
+ trace_drbd_epoch(mdev, epoch, EV_TRACE_FREE);
kfree(epoch);
if (rv == FE_STILL_LIVE)
@@ -1104,10 +1070,7 @@ STATIC enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev,
struct flush_work *fw;
fw = kmalloc(sizeof(*fw), GFP_ATOMIC);
if (fw) {
- MTRACE(TRACE_TYPE_EPOCHS, TRACE_LVL_METRICS,
- dev_info(DEV, "Schedul flush %p/%d { size=%d } nr_epochs=%d\n",
- epoch, epoch->barrier_nr, epoch_size, mdev->epochs);
- );
+ trace_drbd_epoch(mdev, epoch, EV_TRACE_FLUSH);
fw->w.cb = w_flush;
fw->epoch = epoch;
drbd_queue_work(&mdev->data.work, &fw->w);
@@ -1273,9 +1236,7 @@ STATIC int receive_Barrier(struct drbd_conf *mdev, struct p_header *h)
list_add(&epoch->list, &mdev->current_epoch->list);
mdev->current_epoch = epoch;
mdev->epochs++;
- MTRACE(TRACE_TYPE_EPOCHS, TRACE_LVL_METRICS,
- dev_info(DEV, "Allocat epoch %p/xxxx { } nr_epochs=%d\n", epoch, mdev->epochs);
- );
+ trace_drbd_epoch(mdev, epoch, EV_TRACE_ALLOC);
} else {
/* The current_epoch got recycled while we allocated this one... */
kfree(epoch);
@@ -1485,11 +1446,8 @@ STATIC int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_si
list_add(&e->w.list, &mdev->sync_ee);
spin_unlock_irq(&mdev->req_lock);
- MTRACE(TRACE_TYPE_EE, TRACE_LVL_ALL,
- dev_info(DEV, "submit EE (RS)WRITE sec=%llus size=%u ee=%p\n",
- (unsigned long long)e->sector, e->size, e);
- );
- dump_internal_bio("Sec", mdev, e->private_bio, 0);
+ trace_drbd_ee(mdev, e, "submitting for (rs)write");
+ trace_drbd_bio(mdev, "Sec", e->private_bio, 0, NULL);
drbd_generic_make_request(mdev, DRBD_FAULT_RS_WR, e->private_bio);
/* accounting done in endio */
@@ -1752,23 +1710,17 @@ STATIC int receive_Data(struct drbd_conf *mdev, struct p_header *h)
a Barrier. */
epoch = list_entry(e->epoch->list.prev, struct drbd_epoch, list);
if (epoch == e->epoch) {
- MTRACE(TRACE_TYPE_EPOCHS, TRACE_LVL_METRICS,
- dev_info(DEV, "Add barrier %p/%d\n",
- epoch, epoch->barrier_nr);
- );
set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags);
+ trace_drbd_epoch(mdev, e->epoch, EV_TRACE_ADD_BARRIER);
rw |= (1<<BIO_RW_BARRIER);
e->flags |= EE_IS_BARRIER;
} else {
if (atomic_read(&epoch->epoch_size) > 1 ||
!test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) {
- MTRACE(TRACE_TYPE_EPOCHS, TRACE_LVL_METRICS,
- dev_info(DEV, "Add barrier %p/%d, setting bi in %p/%d\n",
- e->epoch, e->epoch->barrier_nr,
- epoch, epoch->barrier_nr);
- );
set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags);
+ trace_drbd_epoch(mdev, epoch, EV_TRACE_SETTING_BI);
set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags);
+ trace_drbd_epoch(mdev, e->epoch, EV_TRACE_ADD_BARRIER);
rw |= (1<<BIO_RW_BARRIER);
e->flags |= EE_IS_BARRIER;
}
@@ -1940,13 +1892,9 @@ STATIC int receive_Data(struct drbd_conf *mdev, struct p_header *h)
drbd_al_begin_io(mdev, e->sector);
}
- MTRACE(TRACE_TYPE_EE, TRACE_LVL_ALL,
- dev_info(DEV, "submit EE (DATA)WRITE sec=%llus size=%u ee=%p\n",
- (unsigned long long)e->sector, e->size, e);
- );
-
e->private_bio->bi_rw = rw;
- dump_internal_bio("Sec", mdev, e->private_bio, 0);
+ trace_drbd_ee(mdev, e, "submitting for (data)write");
+ trace_drbd_bio(mdev, "Sec", e->private_bio, 0, NULL);
drbd_generic_make_request(mdev, DRBD_FAULT_DT_WR, e->private_bio);
/* accounting done in endio */
@@ -2104,12 +2052,8 @@ STATIC int receive_DataRequest(struct drbd_conf *mdev, struct p_header *h)
inc_unacked(mdev);
- MTRACE(TRACE_TYPE_EE, TRACE_LVL_ALL,
- dev_info(DEV, "submit EE READ sec=%llus size=%u ee=%p\n",
- (unsigned long long)e->sector, e->size, e);
- );
-
- dump_internal_bio("Sec", mdev, e->private_bio, 0);
+ trace_drbd_ee(mdev, e, "submitting for read");
+ trace_drbd_bio(mdev, "Sec", e->private_bio, 0, NULL);
drbd_generic_make_request(mdev, fault_type, e->private_bio);
maybe_kick_lo(mdev);
@@ -2331,15 +2275,12 @@ STATIC int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(l
/* lowest bit is set when we were primary,
* next bit (weight 2) is set when peer was primary */
- MTRACE(TRACE_TYPE_UUID, TRACE_LVL_METRICS, DUMPI(rct););
-
switch (rct) {
case 0: /* !self_pri && !peer_pri */ return 0;
case 1: /* self_pri && !peer_pri */ return 1;
case 2: /* !self_pri && peer_pri */ return -1;
case 3: /* self_pri && peer_pri */
dc = test_bit(DISCARD_CONCURRENT, &mdev->flags);
- MTRACE(TRACE_TYPE_UUID, TRACE_LVL_METRICS, DUMPI(dc););
return dc ? -1 : 1;
}
}
@@ -3467,7 +3408,7 @@ STATIC void drbdd(struct drbd_conf *mdev)
break;
}
- dump_packet(mdev, mdev->data.socket, 2, &mdev->data.rbuf,
+ trace_drbd_packet(mdev, mdev->data.socket, 2, &mdev->data.rbuf,
__FILE__, __LINE__);
}
}
@@ -3729,7 +3670,7 @@ int drbd_do_handshake(struct drbd_conf *mdev)
return 0;
}
- dump_packet(mdev, mdev->data.socket, 2, &mdev->data.rbuf,
+ trace_drbd_packet(mdev, mdev->data.socket, 2, &mdev->data.rbuf,
__FILE__, __LINE__);
p->protocol_min = be32_to_cpu(p->protocol_min);
@@ -4309,14 +4250,14 @@ STATIC int drbd_asender(struct drbd_thread *thi)
}
expect = cmd->pkt_size;
ERR_IF(len != expect-sizeof(struct p_header)) {
- dump_packet(mdev, mdev->meta.socket, 1, (void *)h, __FILE__, __LINE__);
+ trace_drbd_packet(mdev, mdev->meta.socket, 1, (void *)h, __FILE__, __LINE__);
DUMPI(expect);
goto reconnect;
}
}
if (received == expect) {
D_ASSERT(cmd != NULL);
- dump_packet(mdev, mdev->meta.socket, 1, (void *)h, __FILE__, __LINE__);
+ trace_drbd_packet(mdev, mdev->meta.socket, 1, (void *)h, __FILE__, __LINE__);
if (!cmd->process(mdev, h))
goto reconnect;
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index cbfcb6b8b4d4..dcf642563c77 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -29,82 +29,9 @@
#include <linux/slab.h>
#include <linux/drbd.h>
#include "drbd_int.h"
+#include "drbd_tracing.h"
#include "drbd_req.h"
-/* outside of the ifdef
- * because of the _print_rq_state(,FIXME) in barrier_acked */
-STATIC void _print_rq_state(struct drbd_request *req, const char *txt)
-{
- const unsigned long s = req->rq_state;
- struct drbd_conf *mdev = req->mdev;
- const int rw = (req->master_bio == NULL ||
- bio_data_dir(req->master_bio) == WRITE) ?
- 'W' : 'R';
-
- dev_info(DEV, "%s %p %c L%c%c%cN%c%c%c%c%c %u (%llus +%u) %s\n",
- txt, req, rw,
- s & RQ_LOCAL_PENDING ? 'p' : '-',
- s & RQ_LOCAL_COMPLETED ? 'c' : '-',
- s & RQ_LOCAL_OK ? 'o' : '-',
- s & RQ_NET_PENDING ? 'p' : '-',
- s & RQ_NET_QUEUED ? 'q' : '-',
- s & RQ_NET_SENT ? 's' : '-',
- s & RQ_NET_DONE ? 'd' : '-',
- s & RQ_NET_OK ? 'o' : '-',
- req->epoch,
- (unsigned long long)req->sector,
- req->size,
- conns_to_name(mdev->state.conn));
-}
-
-/* #define VERBOSE_REQUEST_CODE */
-#if defined(VERBOSE_REQUEST_CODE) || defined(ENABLE_DYNAMIC_TRACE)
-STATIC void _print_req_mod(struct drbd_request *req, enum drbd_req_event what)
-{
- struct drbd_conf *mdev = req->mdev;
- const int rw = (req->master_bio == NULL ||
- bio_data_dir(req->master_bio) == WRITE) ?
- 'W' : 'R';
-
- static const char *rq_event_names[] = {
- [created] = "created",
- [to_be_send] = "to_be_send",
- [to_be_submitted] = "to_be_submitted",
- [queue_for_net_write] = "queue_for_net_write",
- [queue_for_net_read] = "queue_for_net_read",
- [send_canceled] = "send_canceled",
- [send_failed] = "send_failed",
- [handed_over_to_network] = "handed_over_to_network",
- [connection_lost_while_pending] =
- "connection_lost_while_pending",
- [recv_acked_by_peer] = "recv_acked_by_peer",
- [write_acked_by_peer] = "write_acked_by_peer",
- [neg_acked] = "neg_acked",
- [conflict_discarded_by_peer] = "conflict_discarded_by_peer",
- [barrier_acked] = "barrier_acked",
- [data_received] = "data_received",
- [read_completed_with_error] = "read_completed_with_error",
- [write_completed_with_error] = "write_completed_with_error",
- [completed_ok] = "completed_ok",
- };
-
- dev_info(DEV, "_req_mod(%p %c ,%s)\n", req, rw, rq_event_names[what]);
-}
-
-# ifdef ENABLE_DYNAMIC_TRACE
-# define print_rq_state(R, T) \
- MTRACE(TRACE_TYPE_RQ, TRACE_LVL_METRICS, _print_rq_state(R, T);)
-# define print_req_mod(T, W) \
- MTRACE(TRACE_TYPE_RQ, TRACE_LVL_METRICS, _print_req_mod(T, W);)
-# else
-# define print_rq_state(R, T) _print_rq_state(R, T)
-# define print_req_mod(T, W) _print_req_mod(T, W)
-# endif
-
-#else
-#define print_rq_state(R, T)
-#define print_req_mod(T, W)
-#endif
/* Update disk stats at start of I/O request */
static inline void _drbd_start_io_acct(struct drbd_conf *mdev, struct drbd_request *req, struct bio *bio)
@@ -292,7 +219,7 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev,
static void _complete_master_bio(struct drbd_conf *mdev,
struct drbd_request *req, int error)
{
- dump_bio(mdev, req->master_bio, 1, req);
+ trace_drbd_bio(mdev, "Rq", req->master_bio, 1, req);
bio_endio(req->master_bio, error);
req->master_bio = NULL;
dec_ap_bio(mdev);
@@ -304,7 +231,7 @@ void _req_may_be_done(struct drbd_request *req, int error)
struct drbd_conf *mdev = req->mdev;
int rw;
- print_rq_state(req, "_req_may_be_done");
+ trace_drbd_req(req, nothing, "_req_may_be_done");
/* we must not complete the master bio, while it is
* still being processed by _drbd_send_zc_bio (drbd_send_dblock)
@@ -486,7 +413,7 @@ void _req_mod(struct drbd_request *req, enum drbd_req_event what, int error)
if (error && (bio_rw(req->master_bio) != READA))
dev_err(DEV, "got an _req_mod() errno of %d\n", error);
- print_req_mod(req, what);
+ trace_drbd_req(req, what, NULL);
switch (what) {
default:
@@ -739,8 +666,8 @@ void _req_mod(struct drbd_request *req, enum drbd_req_event what, int error)
/* barrier came in before all requests have been acked.
* this is bad, because if the connection is lost now,
* we won't be able to clean them up... */
- _print_rq_state(req,
- "FIXME (barrier_acked but pending)");
+ dev_err(DEV, "FIXME (barrier_acked but pending)\n");
+ trace_drbd_req(req, nothing, "FIXME (barrier_acked but pending)");
list_move(&req->tl_requests, &mdev->out_of_sequence_requests);
}
D_ASSERT(req->rq_state & RQ_NET_SENT);
@@ -810,7 +737,7 @@ STATIC int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio)
return 0;
}
- dump_bio(mdev, bio, 0, req);
+ trace_drbd_bio(mdev, "Rq", bio, 0, req);
local = inc_local(mdev);
if (!local) {
@@ -1003,7 +930,7 @@ allocate_barrier:
if (local) {
req->private_bio->bi_bdev = mdev->bc->backing_bdev;
- dump_internal_bio("Pri", mdev, req->private_bio, 0);
+ trace_drbd_bio(mdev, "Pri", req->private_bio, 0, NULL);
if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR
: rw == READ ? DRBD_FAULT_DT_RD
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h
index 8866ea62f431..a63a1e9ae5a8 100644
--- a/drivers/block/drbd/drbd_req.h
+++ b/drivers/block/drbd/drbd_req.h
@@ -103,6 +103,7 @@ enum drbd_req_event {
read_completed_with_error,
write_completed_with_error,
completed_ok,
+ nothing, /* for tracing only */
};
/* encoding of request states for now. we don't actually need that many bits.
diff --git a/drivers/block/drbd/drbd_tracing.c b/drivers/block/drbd/drbd_tracing.c
new file mode 100644
index 000000000000..2eff178fbb0f
--- /dev/null
+++ b/drivers/block/drbd/drbd_tracing.c
@@ -0,0 +1,762 @@
+/*
+ drbd_tracing.c
+
+ This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+ Copyright (C) 2003-2008, LINBIT Information Technologies GmbH.
+ Copyright (C) 2003-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+ Copyright (C) 2003-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+ drbd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ drbd is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with drbd; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include <linux/module.h>
+#include <linux/drbd.h>
+#include <linux/ctype.h>
+#include <linux/marker.h>
+#include "drbd_int.h"
+#include "drbd_tracing.h"
+#include <linux/drbd_tag_magic.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Philipp Reisner, Lars Ellenberg");
+MODULE_DESCRIPTION("DRBD tracepoint probes");
+MODULE_PARM_DESC(trace_mask, "Bitmap of events to trace see drbd_tracing.c");
+MODULE_PARM_DESC(trace_level, "Current tracing level (changeable in /sys)");
+MODULE_PARM_DESC(trace_devs, "Bitmap of devices to trace (changeable in /sys)");
+
+unsigned int trace_mask = 0; /* Bitmap of events to trace */
+int trace_level; /* Current trace level */
+int trace_devs; /* Bitmap of devices to trace */
+
+module_param(trace_mask, uint, 0444);
+module_param(trace_level, int, 0644);
+module_param(trace_devs, int, 0644);
+
+enum {
+ TRACE_PACKET = 0x0001,
+ TRACE_RQ = 0x0002,
+ TRACE_UUID = 0x0004,
+ TRACE_RESYNC = 0x0008,
+ TRACE_EE = 0x0010,
+ TRACE_UNPLUG = 0x0020,
+ TRACE_NL = 0x0040,
+ TRACE_AL_EXT = 0x0080,
+ TRACE_INT_RQ = 0x0100,
+ TRACE_MD_IO = 0x0200,
+ TRACE_EPOCH = 0x0400,
+};
+
+/* Buffer printing support
+ * dbg_print_flags: used for Flags arg to drbd_print_buffer
+ * - DBGPRINT_BUFFADDR; if set, each line starts with the
+ * virtual address of the line being output. If clear,
+ * each line starts with the offset from the beginning
+ * of the buffer. */
+enum dbg_print_flags {
+ DBGPRINT_BUFFADDR = 0x0001,
+};
+
+/* Macro stuff */
+STATIC char *nl_packet_name(int packet_type)
+{
+/* Generate packet type strings */
+#define NL_PACKET(name, number, fields) \
+ [P_ ## name] = # name,
+#define NL_INTEGER Argh!
+#define NL_BIT Argh!
+#define NL_INT64 Argh!
+#define NL_STRING Argh!
+
+ static char *nl_tag_name[P_nl_after_last_packet] = {
+#include "linux/drbd_nl.h"
+ };
+
+ return (packet_type < sizeof(nl_tag_name)/sizeof(nl_tag_name[0])) ?
+ nl_tag_name[packet_type] : "*Unknown*";
+}
+/* /Macro stuff */
+
+static inline int is_mdev_trace(struct drbd_conf *mdev, unsigned int level)
+{
+ return trace_level >= level && ((1 << mdev_to_minor(mdev)) & trace_devs);
+}
+
+static void probe_drbd_unplug(struct drbd_conf *mdev, char *msg)
+{
+ if (!is_mdev_trace(mdev, TRACE_LVL_ALWAYS))
+ return;
+
+ dev_info(DEV, "%s, ap_bio_count=%d\n", msg, atomic_read(&mdev->ap_bio_cnt));
+}
+
+static void probe_drbd_uuid(struct drbd_conf *mdev, enum drbd_uuid_index index)
+{
+ static char *uuid_str[UI_EXTENDED_SIZE] = {
+ [UI_CURRENT] = "CURRENT",
+ [UI_BITMAP] = "BITMAP",
+ [UI_HISTORY_START] = "HISTORY_START",
+ [UI_HISTORY_END] = "HISTORY_END",
+ [UI_SIZE] = "SIZE",
+ [UI_FLAGS] = "FLAGS",
+ };
+
+ if (!is_mdev_trace(mdev, TRACE_LVL_ALWAYS))
+ return;
+
+ if (index >= UI_EXTENDED_SIZE) {
+ dev_warn(DEV, " uuid_index >= EXTENDED_SIZE\n");
+ return;
+ }
+
+ dev_info(DEV, " uuid[%s] now %016llX\n",
+ uuid_str[index],
+ (unsigned long long)mdev->bc->md.uuid[index]);
+}
+
+static void probe_drbd_md_io(struct drbd_conf *mdev, int rw,
+ struct drbd_backing_dev *bdev)
+{
+ if (!is_mdev_trace(mdev, TRACE_LVL_ALWAYS))
+ return;
+
+ dev_info(DEV, " %s metadata superblock now\n",
+ rw == READ ? "Reading" : "Writing");
+}
+
+static void probe_drbd_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e, char* msg)
+{
+ if (!is_mdev_trace(mdev, TRACE_LVL_ALWAYS))
+ return;
+
+ dev_info(DEV, "EE %s sec=%llus size=%u e=%p\n",
+ msg, (unsigned long long)e->sector, e->size, e);
+}
+
+static void probe_drbd_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch,
+ enum epoch_event ev)
+{
+ static char *epoch_event_str[] = {
+ [EV_PUT] = "put",
+ [EV_GOT_BARRIER_NR] = "got_barrier_nr",
+ [EV_BARRIER_DONE] = "barrier_done",
+ [EV_BECAME_LAST] = "became_last",
+ [EV_TRACE_FLUSH] = "issuing_flush",
+ [EV_TRACE_ADD_BARRIER] = "added_barrier",
+ [EV_TRACE_SETTING_BI] = "just set barrier_in_next_epoch",
+ };
+
+ if (!is_mdev_trace(mdev, TRACE_LVL_ALWAYS))
+ return;
+
+ ev &= ~EV_CLEANUP;
+
+ switch (ev) {
+ case EV_TRACE_ALLOC:
+ dev_info(DEV, "Allocat epoch %p/xxxx { } nr_epochs=%d\n", epoch, mdev->epochs);
+ break;
+ case EV_TRACE_FREE:
+ dev_info(DEV, "Freeing epoch %p/%d { size=%d } nr_epochs=%d\n",
+ epoch, epoch->barrier_nr, atomic_read(&epoch->epoch_size),
+ mdev->epochs);
+ break;
+ default:
+ dev_info(DEV, "Update epoch %p/%d { size=%d active=%d %c%c n%c%c } ev=%s\n",
+ epoch, epoch->barrier_nr, atomic_read(&epoch->epoch_size),
+ atomic_read(&epoch->active),
+ test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) ? 'n' : '-',
+ test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags) ? 'b' : '-',
+ test_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags) ? 'i' : '-',
+ test_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags) ? 'd' : '-',
+ epoch_event_str[ev]);
+ }
+}
+
+static void probe_drbd_netlink(void *data, int is_req)
+{
+ struct cn_msg *msg = data;
+
+ if (is_req) {
+ struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req *)msg->data;
+
+ printk(KERN_INFO "drbd%d: "
+ "Netlink: << %s (%d) - seq: %x, ack: %x, len: %x\n",
+ nlp->drbd_minor,
+ nl_packet_name(nlp->packet_type),
+ nlp->packet_type,
+ msg->seq, msg->ack, msg->len);
+ } else {
+ struct drbd_nl_cfg_reply *nlp = (struct drbd_nl_cfg_reply *)msg->data;
+
+ printk(KERN_INFO "drbd%d: "
+ "Netlink: >> %s (%d) - seq: %x, ack: %x, len: %x\n",
+ nlp->minor,
+ nlp->packet_type == P_nl_after_last_packet ?
+ "Empty-Reply" : nl_packet_name(nlp->packet_type),
+ nlp->packet_type,
+ msg->seq, msg->ack, msg->len);
+ }
+}
+
+static void probe_drbd_actlog(struct drbd_conf *mdev, sector_t sector, char* msg)
+{
+ unsigned int enr = (sector >> (AL_EXTENT_SIZE_B-9));
+
+ if (!is_mdev_trace(mdev, TRACE_LVL_ALWAYS))
+ return;
+
+ dev_info(DEV, "%s (sec=%llus, al_enr=%u, rs_enr=%d)\n",
+ msg, (unsigned long long) sector, enr,
+ (int)BM_SECT_TO_EXT(sector));
+}
+
+/*
+ *
+ * drbd_print_buffer
+ *
+ * This routine dumps binary data to the debugging output. Can be
+ * called at interrupt level.
+ *
+ * Arguments:
+ *
+ * prefix - String is output at the beginning of each line output
+ * flags - Control operation of the routine. Currently defined
+ * Flags are:
+ * DBGPRINT_BUFFADDR; if set, each line starts with the
+ * virtual address of the line being outupt. If clear,
+ * each line starts with the offset from the beginning
+ * of the buffer.
+ * size - Indicates the size of each entry in the buffer. Supported
+ * values are sizeof(char), sizeof(short) and sizeof(int)
+ * buffer - Start address of buffer
+ * buffer_va - Virtual address of start of buffer (normally the same
+ * as Buffer, but having it separate allows it to hold
+ * file address for example)
+ * length - length of buffer
+ *
+ */
+static void drbd_print_buffer(const char *prefix, unsigned int flags, int size,
+ const void *buffer, const void *buffer_va,
+ unsigned int length)
+
+#define LINE_SIZE 16
+#define LINE_ENTRIES (int)(LINE_SIZE/size)
+{
+ const unsigned char *pstart;
+ const unsigned char *pstart_va;
+ const unsigned char *pend;
+ char bytes_str[LINE_SIZE*3+8], ascii_str[LINE_SIZE+8];
+ char *pbytes = bytes_str, *pascii = ascii_str;
+ int offset = 0;
+ long sizemask;
+ int field_width;
+ int index;
+ const unsigned char *pend_str;
+ const unsigned char *p;
+ int count;
+
+ /* verify size parameter */
+ if (size != sizeof(char) &&
+ size != sizeof(short) &&
+ size != sizeof(int)) {
+ printk(KERN_DEBUG "drbd_print_buffer: "
+ "ERROR invalid size %d\n", size);
+ return;
+ }
+
+ sizemask = size-1;
+ field_width = size*2;
+
+ /* Adjust start/end to be on appropriate boundary for size */
+ buffer = (const char *)((long)buffer & ~sizemask);
+ pend = (const unsigned char *)
+ (((long)buffer + length + sizemask) & ~sizemask);
+
+ if (flags & DBGPRINT_BUFFADDR) {
+ /* Move start back to nearest multiple of line size,
+ * if printing address. This results in nicely formatted output
+ * with addresses being on line size (16) byte boundaries */
+ pstart = (const unsigned char *)((long)buffer & ~(LINE_SIZE-1));
+ } else {
+ pstart = (const unsigned char *)buffer;
+ }
+
+ /* Set value of start VA to print if addresses asked for */
+ pstart_va = (const unsigned char *)buffer_va
+ - ((const unsigned char *)buffer-pstart);
+
+ /* Calculate end position to nicely align right hand side */
+ pend_str = pstart + (((pend-pstart) + LINE_SIZE-1) & ~(LINE_SIZE-1));
+
+ /* Init strings */
+ *pbytes = *pascii = '\0';
+
+ /* Start at beginning of first line */
+ p = pstart;
+ count = 0;
+
+ while (p < pend_str) {
+ if (p < (const unsigned char *)buffer || p >= pend) {
+ /* Before start of buffer or after end- print spaces */
+ pbytes += sprintf(pbytes, "%*c ", field_width, ' ');
+ pascii += sprintf(pascii, "%*c", size, ' ');
+ p += size;
+ } else {
+ /* Add hex and ascii to strings */
+ int val;
+ switch (size) {
+ default:
+ case 1:
+ val = *(unsigned char *)p;
+ break;
+ case 2:
+ val = *(unsigned short *)p;
+ break;
+ case 4:
+ val = *(unsigned int *)p;
+ break;
+ }
+
+ pbytes += sprintf(pbytes, "%0*x ", field_width, val);
+
+ for (index = size; index; index--) {
+ *pascii++ = isprint(*p) ? *p : '.';
+ p++;
+ }
+ }
+
+ count++;
+
+ if (count == LINE_ENTRIES || p >= pend_str) {
+ /* Null terminate and print record */
+ *pascii = '\0';
+ printk(KERN_DEBUG "%s%8.8lx: %*s|%*s|\n",
+ prefix,
+ (flags & DBGPRINT_BUFFADDR)
+ ? (long)pstart_va:(long)offset,
+ LINE_ENTRIES*(field_width+1), bytes_str,
+ LINE_SIZE, ascii_str);
+
+ /* Move onto next line */
+ pstart_va += (p-pstart);
+ pstart = p;
+ count = 0;
+ offset += LINE_SIZE;
+
+ /* Re-init strings */
+ pbytes = bytes_str;
+ pascii = ascii_str;
+ *pbytes = *pascii = '\0';
+ }
+ }
+}
+
+static void probe_drbd_resync(struct drbd_conf *mdev, int level, const char *fmt, va_list args)
+{
+ char str[256];
+
+ if (!is_mdev_trace(mdev, level))
+ return;
+
+ if (vsnprintf(str, 256, fmt, args) >= 256)
+ str[255] = 0;
+
+ printk(KERN_INFO "%s %s: %s", dev_driver_string(disk_to_dev(mdev->vdisk)),
+ dev_name(disk_to_dev(mdev->vdisk)), str);
+}
+
+static void probe_drbd_bio(struct drbd_conf *mdev, const char *pfx, struct bio *bio, int complete,
+ struct drbd_request *r)
+{
+#ifdef CONFIG_LBD
+#define SECTOR_FORMAT "%Lx"
+#else
+#define SECTOR_FORMAT "%lx"
+#endif
+#define SECTOR_SHIFT 9
+
+ unsigned long lowaddr = (unsigned long)(bio->bi_sector << SECTOR_SHIFT);
+ char *faddr = (char *)(lowaddr);
+ char rb[sizeof(void *)*2+6] = { 0, };
+ struct bio_vec *bvec;
+ int segno;
+
+ const int rw = bio->bi_rw;
+ const int biorw = (rw & (RW_MASK|RWA_MASK));
+ const int biobarrier = (rw & (1<<BIO_RW_BARRIER));
+ const int biosync = (rw & ((1<<BIO_RW_UNPLUG) | (1<<BIO_RW_SYNCIO)));
+
+ if (!is_mdev_trace(mdev, TRACE_LVL_ALWAYS))
+ return;
+
+ if (r)
+ sprintf(rb, "Req:%p ", r);
+
+ dev_info(DEV, "%s %s:%s%s%s Bio:%p %s- %soffset " SECTOR_FORMAT ", size %x\n",
+ complete ? "<<<" : ">>>",
+ pfx,
+ biorw == WRITE ? "Write" : "Read",
+ biobarrier ? " : B" : "",
+ biosync ? " : S" : "",
+ bio,
+ rb,
+ complete ? (bio_flagged(bio, BIO_UPTODATE) ? "Success, " : "Failed, ") : "",
+ bio->bi_sector << SECTOR_SHIFT,
+ bio->bi_size);
+
+ if (trace_level >= TRACE_LVL_METRICS &&
+ ((biorw == WRITE) ^ complete)) {
+ printk(KERN_DEBUG " ind page offset length\n");
+ __bio_for_each_segment(bvec, bio, segno, 0) {
+ printk(KERN_DEBUG " [%d] %p %8.8x %8.8x\n", segno,
+ bvec->bv_page, bvec->bv_offset, bvec->bv_len);
+
+ if (trace_level >= TRACE_LVL_ALL) {
+ char *bvec_buf;
+ unsigned long flags;
+
+ bvec_buf = bvec_kmap_irq(bvec, &flags);
+
+ drbd_print_buffer(" ", DBGPRINT_BUFFADDR, 1,
+ bvec_buf,
+ faddr,
+ (bvec->bv_len <= 0x80)
+ ? bvec->bv_len : 0x80);
+
+ bvec_kunmap_irq(bvec_buf, &flags);
+
+ if (bvec->bv_len > 0x40)
+ printk(KERN_DEBUG " ....\n");
+
+ faddr += bvec->bv_len;
+ }
+ }
+ }
+}
+
+static void probe_drbd_req(struct drbd_request *req, enum drbd_req_event what, char *msg)
+{
+ static const char *rq_event_names[] = {
+ [created] = "created",
+ [to_be_send] = "to_be_send",
+ [to_be_submitted] = "to_be_submitted",
+ [queue_for_net_write] = "queue_for_net_write",
+ [queue_for_net_read] = "queue_for_net_read",
+ [send_canceled] = "send_canceled",
+ [send_failed] = "send_failed",
+ [handed_over_to_network] = "handed_over_to_network",
+ [connection_lost_while_pending] =
+ "connection_lost_while_pending",
+ [recv_acked_by_peer] = "recv_acked_by_peer",
+ [write_acked_by_peer] = "write_acked_by_peer",
+ [neg_acked] = "neg_acked",
+ [conflict_discarded_by_peer] = "conflict_discarded_by_peer",
+ [barrier_acked] = "barrier_acked",
+ [data_received] = "data_received",
+ [read_completed_with_error] = "read_completed_with_error",
+ [write_completed_with_error] = "write_completed_with_error",
+ [completed_ok] = "completed_ok",
+ };
+
+ struct drbd_conf *mdev = req->mdev;
+
+ const int rw = (req->master_bio == NULL ||
+ bio_data_dir(req->master_bio) == WRITE) ?
+ 'W' : 'R';
+ const unsigned long s = req->rq_state;
+
+ if (what != nothing) {
+ dev_info(DEV, "_req_mod(%p %c ,%s)\n", req, rw, rq_event_names[what]);
+ } else {
+ dev_info(DEV, "%s %p %c L%c%c%cN%c%c%c%c%c %u (%llus +%u) %s\n",
+ msg, req, rw,
+ s & RQ_LOCAL_PENDING ? 'p' : '-',
+ s & RQ_LOCAL_COMPLETED ? 'c' : '-',
+ s & RQ_LOCAL_OK ? 'o' : '-',
+ s & RQ_NET_PENDING ? 'p' : '-',
+ s & RQ_NET_QUEUED ? 'q' : '-',
+ s & RQ_NET_SENT ? 's' : '-',
+ s & RQ_NET_DONE ? 'd' : '-',
+ s & RQ_NET_OK ? 'o' : '-',
+ req->epoch,
+ (unsigned long long)req->sector,
+ req->size,
+ conns_to_name(mdev->state.conn));
+ }
+}
+
+
+#define peers_to_name roles_to_name
+#define pdsks_to_name disks_to_name
+
+#define PSM(A) \
+do { \
+ if (mask.A) { \
+ int i = snprintf(p, len, " " #A "( %s )", \
+ A##s_to_name(val.A)); \
+ if (i >= len) \
+ return op; \
+ p += i; \
+ len -= i; \
+ } \
+} while (0)
+
+STATIC char *dump_st(char *p, int len, union drbd_state mask, union drbd_state val)
+{
+ char *op = p;
+ *p = '\0';
+ PSM(role);
+ PSM(peer);
+ PSM(conn);
+ PSM(disk);
+ PSM(pdsk);
+
+ return op;
+}
+
+#define INFOP(fmt, args...) \
+do { \
+ if (trace_level >= TRACE_LVL_ALL) { \
+ dev_info(DEV, "%s:%d: %s [%d] %s %s " fmt , \
+ file, line, current->comm, current->pid, \
+ sockname, recv ? "<<<" : ">>>" , \
+ ## args); \
+ } else { \
+ dev_info(DEV, "%s %s " fmt, sockname, \
+ recv ? "<<<" : ">>>" , \
+ ## args); \
+ } \
+} while (0)
+
+STATIC char *_dump_block_id(u64 block_id, char *buff)
+{
+ if (is_syncer_block_id(block_id))
+ strcpy(buff, "SyncerId");
+ else
+ sprintf(buff, "%llx", (unsigned long long)block_id);
+
+ return buff;
+}
+
+static void probe_drbd_packet(struct drbd_conf *mdev, struct socket *sock,
+ int recv, union p_polymorph *p, char *file, int line)
+{
+ char *sockname = sock == mdev->meta.socket ? "meta" : "data";
+ int cmd = (recv == 2) ? p->header.command : be16_to_cpu(p->header.command);
+ char tmp[300];
+ union drbd_state m, v;
+
+ switch (cmd) {
+ case P_HAND_SHAKE:
+ INFOP("%s (protocol %u-%u)\n", cmdname(cmd),
+ be32_to_cpu(p->handshake.protocol_min),
+ be32_to_cpu(p->handshake.protocol_max));
+ break;
+
+ case P_BITMAP: /* don't report this */
+ case P_COMPRESSED_BITMAP: /* don't report this */
+ break;
+
+ case P_DATA:
+ INFOP("%s (sector %llus, id %s, seq %u, f %x)\n", cmdname(cmd),
+ (unsigned long long)be64_to_cpu(p->data.sector),
+ _dump_block_id(p->data.block_id, tmp),
+ be32_to_cpu(p->data.seq_num),
+ be32_to_cpu(p->data.dp_flags)
+ );
+ break;
+
+ case P_DATA_REPLY:
+ case P_RS_DATA_REPLY:
+ INFOP("%s (sector %llus, id %s)\n", cmdname(cmd),
+ (unsigned long long)be64_to_cpu(p->data.sector),
+ _dump_block_id(p->data.block_id, tmp)
+ );
+ break;
+
+ case P_RECV_ACK:
+ case P_WRITE_ACK:
+ case P_RS_WRITE_ACK:
+ case P_DISCARD_ACK:
+ case P_NEG_ACK:
+ case P_NEG_RS_DREPLY:
+ INFOP("%s (sector %llus, size %u, id %s, seq %u)\n",
+ cmdname(cmd),
+ (long long)be64_to_cpu(p->block_ack.sector),
+ be32_to_cpu(p->block_ack.blksize),
+ _dump_block_id(p->block_ack.block_id, tmp),
+ be32_to_cpu(p->block_ack.seq_num)
+ );
+ break;
+
+ case P_DATA_REQUEST:
+ case P_RS_DATA_REQUEST:
+ INFOP("%s (sector %llus, size %u, id %s)\n", cmdname(cmd),
+ (long long)be64_to_cpu(p->block_req.sector),
+ be32_to_cpu(p->block_req.blksize),
+ _dump_block_id(p->block_req.block_id, tmp)
+ );
+ break;
+
+ case P_BARRIER:
+ case P_BARRIER_ACK:
+ INFOP("%s (barrier %u)\n", cmdname(cmd), p->barrier.barrier);
+ break;
+
+ case P_SYNC_PARAM:
+ case P_SYNC_PARAM89:
+ INFOP("%s (rate %u, verify-alg \"%.64s\", csums-alg \"%.64s\")\n",
+ cmdname(cmd), be32_to_cpu(p->rs_param_89.rate),
+ p->rs_param_89.verify_alg, p->rs_param_89.csums_alg);
+ break;
+
+ case P_UUIDS:
+ INFOP("%s Curr:%016llX, Bitmap:%016llX, "
+ "HisSt:%016llX, HisEnd:%016llX\n",
+ cmdname(cmd),
+ (unsigned long long)be64_to_cpu(p->uuids.uuid[UI_CURRENT]),
+ (unsigned long long)be64_to_cpu(p->uuids.uuid[UI_BITMAP]),
+ (unsigned long long)be64_to_cpu(p->uuids.uuid[UI_HISTORY_START]),
+ (unsigned long long)be64_to_cpu(p->uuids.uuid[UI_HISTORY_END]));
+ break;
+
+ case P_SIZES:
+ INFOP("%s (d %lluMiB, u %lluMiB, c %lldMiB, "
+ "max bio %x, q order %x)\n",
+ cmdname(cmd),
+ (long long)(be64_to_cpu(p->sizes.d_size)>>(20-9)),
+ (long long)(be64_to_cpu(p->sizes.u_size)>>(20-9)),
+ (long long)(be64_to_cpu(p->sizes.c_size)>>(20-9)),
+ be32_to_cpu(p->sizes.max_segment_size),
+ be32_to_cpu(p->sizes.queue_order_type));
+ break;
+
+ case P_STATE:
+ v.i = be32_to_cpu(p->state.state);
+ m.i = 0xffffffff;
+ dump_st(tmp, sizeof(tmp), m, v);
+ INFOP("%s (s %x {%s})\n", cmdname(cmd), v.i, tmp);
+ break;
+
+ case P_STATE_CHG_REQ:
+ m.i = be32_to_cpu(p->req_state.mask);
+ v.i = be32_to_cpu(p->req_state.val);
+ dump_st(tmp, sizeof(tmp), m, v);
+ INFOP("%s (m %x v %x {%s})\n", cmdname(cmd), m.i, v.i, tmp);
+ break;
+
+ case P_STATE_CHG_REPLY:
+ INFOP("%s (ret %x)\n", cmdname(cmd),
+ be32_to_cpu(p->req_state_reply.retcode));
+ break;
+
+ case P_PING:
+ case P_PING_ACK:
+ /*
+ * Dont trace pings at summary level
+ */
+ if (trace_level < TRACE_LVL_ALL)
+ break;
+ /* fall through... */
+ default:
+ INFOP("%s (%u)\n", cmdname(cmd), cmd);
+ break;
+ }
+}
+
+
+static int __init drbd_trace_init(void)
+{
+ int ret;
+
+ if (trace_mask & TRACE_UNPLUG) {
+ ret = register_trace_drbd_unplug(probe_drbd_unplug);
+ WARN_ON(ret);
+ }
+ if (trace_mask & TRACE_UUID) {
+ ret = register_trace_drbd_uuid(probe_drbd_uuid);
+ WARN_ON(ret);
+ }
+ if (trace_mask & TRACE_EE) {
+ ret = register_trace_drbd_ee(probe_drbd_ee);
+ WARN_ON(ret);
+ }
+ if (trace_mask & TRACE_PACKET) {
+ ret = register_trace_drbd_packet(probe_drbd_packet);
+ WARN_ON(ret);
+ }
+ if (trace_mask & TRACE_MD_IO) {
+ ret = register_trace_drbd_md_io(probe_drbd_md_io);
+ WARN_ON(ret);
+ }
+ if (trace_mask & TRACE_EPOCH) {
+ ret = register_trace_drbd_epoch(probe_drbd_epoch);
+ WARN_ON(ret);
+ }
+ if (trace_mask & TRACE_NL) {
+ ret = register_trace_drbd_netlink(probe_drbd_netlink);
+ WARN_ON(ret);
+ }
+ if (trace_mask & TRACE_AL_EXT) {
+ ret = register_trace_drbd_actlog(probe_drbd_actlog);
+ WARN_ON(ret);
+ }
+ if (trace_mask & TRACE_RQ) {
+ ret = register_trace_drbd_bio(probe_drbd_bio);
+ WARN_ON(ret);
+ }
+ if (trace_mask & TRACE_INT_RQ) {
+ ret = register_trace_drbd_req(probe_drbd_req);
+ WARN_ON(ret);
+ }
+ if (trace_mask & TRACE_RESYNC) {
+ ret = register_trace__drbd_resync(probe_drbd_resync);
+ WARN_ON(ret);
+ }
+ return 0;
+}
+
+module_init(drbd_trace_init);
+
+static void __exit drbd_trace_exit(void)
+{
+ if (trace_mask & TRACE_UNPLUG)
+ unregister_trace_drbd_unplug(probe_drbd_unplug);
+ if (trace_mask & TRACE_UUID)
+ unregister_trace_drbd_uuid(probe_drbd_uuid);
+ if (trace_mask & TRACE_EE)
+ unregister_trace_drbd_ee(probe_drbd_ee);
+ if (trace_mask & TRACE_PACKET)
+ unregister_trace_drbd_packet(probe_drbd_packet);
+ if (trace_mask & TRACE_MD_IO)
+ unregister_trace_drbd_md_io(probe_drbd_md_io);
+ if (trace_mask & TRACE_EPOCH)
+ unregister_trace_drbd_epoch(probe_drbd_epoch);
+ if (trace_mask & TRACE_NL)
+ unregister_trace_drbd_netlink(probe_drbd_netlink);
+ if (trace_mask & TRACE_AL_EXT)
+ unregister_trace_drbd_actlog(probe_drbd_actlog);
+ if (trace_mask & TRACE_RQ)
+ unregister_trace_drbd_bio(probe_drbd_bio);
+ if (trace_mask & TRACE_INT_RQ)
+ unregister_trace_drbd_req(probe_drbd_req);
+ if (trace_mask & TRACE_RESYNC)
+ unregister_trace__drbd_resync(probe_drbd_resync);
+
+ tracepoint_synchronize_unregister();
+}
+
+module_exit(drbd_trace_exit);
diff --git a/drivers/block/drbd/drbd_tracing.h b/drivers/block/drbd/drbd_tracing.h
new file mode 100644
index 000000000000..c4531a137f65
--- /dev/null
+++ b/drivers/block/drbd/drbd_tracing.h
@@ -0,0 +1,87 @@
+/*
+ drbd_tracing.h
+
+ This file is part of DRBD by Philipp Reisner and Lars Ellenberg.
+
+ Copyright (C) 2003-2008, LINBIT Information Technologies GmbH.
+ Copyright (C) 2003-2008, Philipp Reisner <philipp.reisner@linbit.com>.
+ Copyright (C) 2003-2008, Lars Ellenberg <lars.ellenberg@linbit.com>.
+
+ drbd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ drbd is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with drbd; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#ifndef DRBD_TRACING_H
+#define DRBD_TRACING_H
+
+#include <linux/tracepoint.h>
+#include "drbd_int.h"
+#include "drbd_req.h"
+
+enum {
+ TRACE_LVL_ALWAYS = 0,
+ TRACE_LVL_SUMMARY,
+ TRACE_LVL_METRICS,
+ TRACE_LVL_ALL,
+ TRACE_LVL_MAX
+};
+
+DECLARE_TRACE(drbd_unplug,
+ TP_PROTO(struct drbd_conf *mdev, char* msg),
+ TP_ARGS(mdev, msg));
+
+DECLARE_TRACE(drbd_uuid,
+ TP_PROTO(struct drbd_conf *mdev, enum drbd_uuid_index index),
+ TP_ARGS(mdev, index));
+
+DECLARE_TRACE(drbd_ee,
+ TP_PROTO(struct drbd_conf *mdev, struct drbd_epoch_entry *e, char* msg),
+ TP_ARGS(mdev, e, msg));
+
+DECLARE_TRACE(drbd_md_io,
+ TP_PROTO(struct drbd_conf *mdev, int rw, struct drbd_backing_dev *bdev),
+ TP_ARGS(mdev, rw, bdev));
+
+DECLARE_TRACE(drbd_epoch,
+ TP_PROTO(struct drbd_conf *mdev, struct drbd_epoch *epoch, enum epoch_event ev),
+ TP_ARGS(mdev, epoch, ev));
+
+DECLARE_TRACE(drbd_netlink,
+ TP_PROTO(void *data, int is_req),
+ TP_ARGS(data, is_req));
+
+DECLARE_TRACE(drbd_actlog,
+ TP_PROTO(struct drbd_conf *mdev, sector_t sector, char* msg),
+ TP_ARGS(mdev, sector, msg));
+
+DECLARE_TRACE(drbd_bio,
+ TP_PROTO(struct drbd_conf *mdev, const char *pfx, struct bio *bio, int complete,
+ struct drbd_request *r),
+ TP_ARGS(mdev, pfx, bio, complete, r));
+
+DECLARE_TRACE(drbd_req,
+ TP_PROTO(struct drbd_request *req, enum drbd_req_event what, char *msg),
+ TP_ARGS(req, what, msg));
+
+DECLARE_TRACE(drbd_packet,
+ TP_PROTO(struct drbd_conf *mdev, struct socket *sock,
+ int recv, union p_polymorph *p, char *file, int line),
+ TP_ARGS(mdev, sock, recv, p, file, line));
+
+DECLARE_TRACE(_drbd_resync,
+ TP_PROTO(struct drbd_conf *mdev, int level, const char *fmt, va_list args),
+ TP_ARGS(mdev, level, fmt, args));
+
+#endif
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c
index 4be8814fd50d..81f3a4e8ea49 100644
--- a/drivers/block/drbd/drbd_worker.c
+++ b/drivers/block/drbd/drbd_worker.c
@@ -43,6 +43,7 @@
#include <linux/drbd.h>
#include "drbd_int.h"
#include "drbd_req.h"
+#include "drbd_tracing.h"
#define SLEEP_TIME (HZ/10)
@@ -88,7 +89,7 @@ void drbd_md_io_complete(struct bio *bio, int error)
md_io->error = error;
- dump_internal_bio("Md", md_io->mdev, bio, 1);
+ trace_drbd_bio(md_io->mdev, "Md", bio, 1, NULL);
complete(&md_io->event);
}
@@ -116,7 +117,7 @@ void drbd_endio_read_sec(struct bio *bio, int error) __releases(local)
D_ASSERT(e->block_id != ID_VACANT);
- dump_internal_bio("Sec", mdev, bio, 1);
+ trace_drbd_bio(mdev, "Sec", bio, 1, NULL);
spin_lock_irqsave(&mdev->req_lock, flags);
mdev->read_cnt += e->size >> 9;
@@ -129,10 +130,7 @@ void drbd_endio_read_sec(struct bio *bio, int error) __releases(local)
drbd_queue_work(&mdev->data.work, &e->w);
dec_local(mdev);
- MTRACE(TRACE_TYPE_EE, TRACE_LVL_ALL,
- dev_info(DEV, "Moved EE (READ) to worker sec=%llus size=%u ee=%p\n",
- (unsigned long long)e->sector, e->size, e);
- );
+ trace_drbd_ee(mdev, e, "read completed");
}
/* writes on behalf of the partner, or resync writes,
@@ -175,7 +173,7 @@ void drbd_endio_write_sec(struct bio *bio, int error) __releases(local)
D_ASSERT(e->block_id != ID_VACANT);
- dump_internal_bio("Sec", mdev, bio, 1);
+ trace_drbd_bio(mdev, "Sec", bio, 1, NULL);
spin_lock_irqsave(&mdev->req_lock, flags);
mdev->writ_cnt += e->size >> 9;
@@ -191,10 +189,7 @@ void drbd_endio_write_sec(struct bio *bio, int error) __releases(local)
list_del(&e->w.list); /* has been on active_ee or sync_ee */
list_add_tail(&e->w.list, &mdev->done_ee);
- MTRACE(TRACE_TYPE_EE, TRACE_LVL_ALL,
- dev_info(DEV, "Moved EE (WRITE) to done_ee sec=%llus size=%u ee=%p\n",
- (unsigned long long)e->sector, e->size, e);
- );
+ trace_drbd_ee(mdev, e, "write completed");
/* No hlist_del_init(&e->colision) here, we did not send the Ack yet,
* neither did we wake possibly waiting conflicting requests.
@@ -241,7 +236,7 @@ void drbd_endio_pri(struct bio *bio, int error)
error = -EIO;
}
- dump_internal_bio("Pri", mdev, bio, 1);
+ trace_drbd_bio(mdev, "Pri", bio, 1, NULL);
/* to avoid recursion in _req_mod */
what = error
@@ -1265,10 +1260,8 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
union drbd_state ns;
int r;
- MTRACE(TRACE_TYPE_RESYNC, TRACE_LVL_SUMMARY,
- dev_info(DEV, "Resync starting: side=%s\n",
- side == C_SYNC_TARGET ? "SyncTarget" : "SyncSource");
- );
+ trace_drbd_resync(mdev, TRACE_LVL_SUMMARY, "Resync starting: side=%s\n",
+ side == C_SYNC_TARGET ? "SyncTarget" : "SyncSource");
drbd_bm_recount_bits(mdev);
diff --git a/drivers/block/drbd/drbd_wrappers.h b/drivers/block/drbd/drbd_wrappers.h
index 501ca2ed31f7..b7ce5acca0bb 100644
--- a/drivers/block/drbd/drbd_wrappers.h
+++ b/drivers/block/drbd/drbd_wrappers.h
@@ -1,3 +1,6 @@
+#ifndef _DRBD_WRAPPERS_H
+#define _DRBD_WRAPPERS_H
+
#include <linux/ctype.h>
#include <linux/mm.h>
@@ -90,3 +93,5 @@ static inline int drbd_crypto_is_hash(struct crypto_tfm *tfm)
# undef __cond_lock
# define __cond_lock(x,c) (c)
#endif
+
+#endif