From: Shawn Du <[email protected]>
Though one can specify '-d /dev/sda1' when using blktrace, it still
traces the whole sda.
To support per-partition tracing, when we start tracing, we initialize
bt->start_lba and bt->end_lba to the start and end sector of that
partition.
Note some actions are per device, thus we don't filter 0-sector events.
The original patch and discussion can be found here:
http://marc.info/?l=linux-btrace&m=122949374214540&w=2
Signed-off-by: Shawn Du <[email protected]>
Signed-off-by: Li Zefan <[email protected]>
---
block/compat_ioctl.c | 2 +-
drivers/scsi/sg.c | 1 +
include/linux/blktrace_api.h | 6 ++++--
kernel/trace/blktrace.c | 29 +++++++++++++++++++++--------
4 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index f87615d..f8c218c 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -568,7 +568,7 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg)
memcpy(&buts.name, &cbuts.name, 32);
mutex_lock(&bdev->bd_mutex);
- ret = do_blk_trace_setup(q, b, bdev->bd_dev, &buts);
+ ret = do_blk_trace_setup(q, b, bdev->bd_dev, bdev, &buts);
mutex_unlock(&bdev->bd_mutex);
if (ret)
return ret;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 82312df..49c9873 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1065,6 +1065,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
return blk_trace_setup(sdp->device->request_queue,
sdp->disk->disk_name,
MKDEV(SCSI_GENERIC_MAJOR, sdp->index),
+ NULL,
(char *)arg);
case BLKTRACESTART:
return blk_trace_startstop(sdp->device->request_queue, 1);
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index d960889..6b2c87e 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -165,8 +165,9 @@ struct blk_trace {
extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *);
extern void blk_trace_shutdown(struct request_queue *);
-extern int do_blk_trace_setup(struct request_queue *q,
- char *name, dev_t dev, struct blk_user_trace_setup *buts);
+extern int do_blk_trace_setup(struct request_queue *q, char *name,
+ dev_t dev, struct block_device *bdev,
+ struct blk_user_trace_setup *buts);
extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
/**
@@ -193,6 +194,7 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
extern void blk_add_driver_data(struct request_queue *q, struct request *rq,
void *data, size_t len);
extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+ struct block_device *bdev,
char __user *arg);
extern int blk_trace_startstop(struct request_queue *q, int start);
extern int blk_trace_remove(struct request_queue *q);
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 2b98195..e932654 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -147,7 +147,7 @@ static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
{
if (((bt->act_mask << BLK_TC_SHIFT) & what) == 0)
return 1;
- if (sector < bt->start_lba || sector > bt->end_lba)
+ if (sector && (sector < bt->start_lba || sector > bt->end_lba))
return 1;
if (bt->pid && pid != bt->pid)
return 1;
@@ -192,7 +192,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
what |= MASK_TC_BIT(rw, DISCARD);
pid = tsk->pid;
- if (unlikely(act_log_check(bt, what, sector, pid)))
+ if (act_log_check(bt, what, sector, pid))
return;
cpu = raw_smp_processor_id();
@@ -407,11 +407,13 @@ static struct rchan_callbacks blk_relay_callbacks = {
* Setup everything required to start tracing
*/
int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
- struct blk_user_trace_setup *buts)
+ struct block_device *bdev,
+ struct blk_user_trace_setup *buts)
{
struct blk_trace *old_bt, *bt = NULL;
struct dentry *dir = NULL;
int ret, i;
+ struct hd_struct *part = NULL;
if (!buts->buf_size || !buts->buf_nr)
return -EINVAL;
@@ -480,11 +482,21 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (!bt->act_mask)
bt->act_mask = (u16) -1;
- bt->start_lba = buts->start_lba;
- bt->end_lba = buts->end_lba;
- if (!bt->end_lba)
+ if (bdev)
+ part = bdev->bd_part;
+
+ if (part) {
+ bt->start_lba = part->start_sect;
+ bt->end_lba = part->start_sect + part->nr_sects;
+ } else
bt->end_lba = -1ULL;
+ /* overwrite with user settings */
+ if (buts->start_lba)
+ bt->start_lba = buts->start_lba;
+ if (buts->end_lba)
+ bt->end_lba = buts->end_lba;
+
bt->pid = buts->pid;
bt->trace_state = Blktrace_setup;
@@ -505,6 +517,7 @@ err:
}
int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+ struct block_device *bdev,
char __user *arg)
{
struct blk_user_trace_setup buts;
@@ -514,7 +527,7 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (ret)
return -EFAULT;
- ret = do_blk_trace_setup(q, name, dev, &buts);
+ ret = do_blk_trace_setup(q, name, dev, bdev, &buts);
if (ret)
return ret;
@@ -582,7 +595,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
switch (cmd) {
case BLKTRACESETUP:
bdevname(bdev, b);
- ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
+ ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
break;
case BLKTRACESTART:
start = 1;
--
1.5.4.rc3
The previous patch adds support to trace a single partition for
relay+ioctl blktrace, and this patch is for ftrace plugin blktrace:
# echo 1 > /sys/block/sda/sda7/enable
# cat start_lba
102398373
# cat end_lba
102703545
Signed-off-by: Li Zefan <[email protected]>
---
kernel/trace/blktrace.c | 39 +++++++++++++++++++++++++--------------
1 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index e932654..d109898 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -403,6 +403,23 @@ static struct rchan_callbacks blk_relay_callbacks = {
.remove_buf_file = blk_remove_buf_file_callback,
};
+static void blk_trace_setup_lba(struct blk_trace *bt,
+ struct block_device *bdev)
+{
+ struct hd_struct *part = NULL;
+
+ if (bdev)
+ part = bdev->bd_part;
+
+ if (part) {
+ bt->start_lba = part->start_sect;
+ bt->end_lba = part->start_sect + part->nr_sects;
+ } else {
+ bt->start_lba = 0;
+ bt->end_lba = -1ULL;
+ }
+}
+
/*
* Setup everything required to start tracing
*/
@@ -413,7 +430,6 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
struct blk_trace *old_bt, *bt = NULL;
struct dentry *dir = NULL;
int ret, i;
- struct hd_struct *part = NULL;
if (!buts->buf_size || !buts->buf_nr)
return -EINVAL;
@@ -482,14 +498,7 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (!bt->act_mask)
bt->act_mask = (u16) -1;
- if (bdev)
- part = bdev->bd_part;
-
- if (part) {
- bt->start_lba = part->start_sect;
- bt->end_lba = part->start_sect + part->nr_sects;
- } else
- bt->end_lba = -1ULL;
+ blk_trace_setup_lba(bt, bdev);
/* overwrite with user settings */
if (buts->start_lba)
@@ -1370,7 +1379,8 @@ static int blk_trace_remove_queue(struct request_queue *q)
/*
* Setup everything required to start tracing
*/
-static int blk_trace_setup_queue(struct request_queue *q, dev_t dev)
+static int blk_trace_setup_queue(struct request_queue *q,
+ struct block_device *bdev)
{
struct blk_trace *old_bt, *bt = NULL;
int ret = -ENOMEM;
@@ -1383,9 +1393,10 @@ static int blk_trace_setup_queue(struct request_queue *q, dev_t dev)
if (!bt->msg_data)
goto free_bt;
- bt->dev = dev;
+ bt->dev = bdev->bd_dev;
bt->act_mask = (u16)-1;
- bt->end_lba = -1ULL;
+
+ blk_trace_setup_lba(bt, bdev);
old_bt = xchg(&q->blk_trace, bt);
if (old_bt != NULL) {
@@ -1602,7 +1613,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
if (attr == &dev_attr_enable) {
if (value)
- ret = blk_trace_setup_queue(q, bdev->bd_dev);
+ ret = blk_trace_setup_queue(q, bdev);
else
ret = blk_trace_remove_queue(q);
goto out_unlock_bdev;
@@ -1610,7 +1621,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
ret = 0;
if (q->blk_trace == NULL)
- ret = blk_trace_setup_queue(q, bdev->bd_dev);
+ ret = blk_trace_setup_queue(q, bdev);
if (ret == 0) {
if (attr == &dev_attr_act_mask)
--
1.5.4.rc3
Impact: allow ftrace-plugin blktrace to trace device-mapper devices
To trace a single partition:
# echo 1 > /sys/block/sda/sda1/enable
To trace the whole sda instead:
# echo 1 > /sys/block/sda/enable
Thus we also fix an issue reported by Ted, that ftrace-plugin blktrace
can't be used to trace device-mapper devices.
Now:
# echo 1 > /sys/block/dm-0/trace/enable
echo: write error: No such device or address
# mount -t ext4 /dev/dm-0 /mnt
# echo 1 > /sys/block/dm-0/trace/enable
# echo blk > /debug/tracing/current_tracer
Reported-by: Theodore Tso <[email protected]>
Signed-off-by: Li Zefan <[email protected]>
---
block/blk-sysfs.c | 7 ++++++-
include/linux/blktrace_api.h | 6 ++++++
kernel/trace/blktrace.c | 5 +++++
3 files changed, 17 insertions(+), 1 deletions(-)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 73f36be..8653d71 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -387,16 +387,21 @@ struct kobj_type blk_queue_ktype = {
int blk_register_queue(struct gendisk *disk)
{
int ret;
+ struct device *dev = disk_to_dev(disk);
struct request_queue *q = disk->queue;
if (WARN_ON(!q))
return -ENXIO;
+ ret = blk_trace_init_sysfs(dev);
+ if (ret)
+ return ret;
+
if (!q->request_fn)
return 0;
- ret = kobject_add(&q->kobj, kobject_get(&disk_to_dev(disk)->kobj),
+ ret = kobject_add(&q->kobj, kobject_get(&dev->kobj),
"%s", "queue");
if (ret < 0)
return ret;
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 6b2c87e..b5d1ca4 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -198,6 +198,7 @@ extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
char __user *arg);
extern int blk_trace_startstop(struct request_queue *q, int start);
extern int blk_trace_remove(struct request_queue *q);
+extern int blk_trace_init_sysfs(struct device *dev);
extern struct attribute_group blk_trace_attr_group;
@@ -211,6 +212,11 @@ extern struct attribute_group blk_trace_attr_group;
#define blk_trace_remove(q) (-ENOTTY)
#define blk_add_trace_msg(q, fmt, ...) do { } while (0)
+static inline int blk_trace_init_sysfs(struct device *dev)
+{
+ return 0;
+}
+
#endif /* CONFIG_BLK_DEV_IO_TRACE */
#endif /* __KERNEL__ */
#endif
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index d109898..8e7c5da 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -1644,3 +1644,8 @@ out:
return ret ? ret : count;
}
+int blk_trace_init_sysfs(struct device *dev)
+{
+ return sysfs_create_group(&dev->kobj, &blk_trace_attr_group);
+}
+
--
1.5.4.rc3
* Li Zefan <[email protected]> wrote:
> --- a/include/linux/blktrace_api.h
> +++ b/include/linux/blktrace_api.h
> @@ -165,8 +165,9 @@ struct blk_trace {
>
> extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *);
> extern void blk_trace_shutdown(struct request_queue *);
> -extern int do_blk_trace_setup(struct request_queue *q,
> - char *name, dev_t dev, struct blk_user_trace_setup *buts);
> +extern int do_blk_trace_setup(struct request_queue *q, char *name,
> + dev_t dev, struct block_device *bdev,
> + struct blk_user_trace_setup *buts);
> extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
>
> /**
> @@ -193,6 +194,7 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
> extern void blk_add_driver_data(struct request_queue *q, struct request *rq,
> void *data, size_t len);
> extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
> + struct block_device *bdev,
> char __user *arg);
> extern int blk_trace_startstop(struct request_queue *q, int start);
> extern int blk_trace_remove(struct request_queue *q);
Small detail: you forgot about the !CONFIG_BLK_DEV_IO_TRACE case
here, the wrapper macros there need to be updated.
(no need to resend - i fixed this up in the 1/3 and 3/3 patches)
Ingo
* Li Zefan <[email protected]> wrote:
> From: Shawn Du <[email protected]>
>
> Though one can specify '-d /dev/sda1' when using blktrace, it
> still traces the whole sda.
>
> To support per-partition tracing, when we start tracing, we
> initialize bt->start_lba and bt->end_lba to the start and end
> sector of that partition.
>
> Note some actions are per device, thus we don't filter 0-sector
> events.
>
> The original patch and discussion can be found here:
> http://marc.info/?l=linux-btrace&m=122949374214540&w=2
>
> Signed-off-by: Shawn Du <[email protected]>
> Signed-off-by: Li Zefan <[email protected]>
Thanks - beyond the small detail i mailed about a few minutes ago
the series looks good: i'll queue this up in tracing/blktrace unless
Jens has second thoughts.
Lets note that this approach still has the (long existing)
limitation that only one device can be block-traced at a time.
Furthermore, various other aspects of act_log_check() itself could
be expressed in terms of per tracepoint filters as well: the PID
filter field for example - which is supported in the ioctl ABI but
currently not exposed in the user-space blktrace utility. Same goes
for the action mask which is frequently used.
But before we can lift all these limitations and can have equivalent
functionality in the generic event tracer we still need more filter
engine infrastructure work (range operators and dev_t field
support). Plus TRACE_EVENT() based blk tracepoints.
Once we have that, the conversion will be straightforward: all
existing filter functionality of blktrace is static, so it will map
directly to new-style filter expressions. That will give us block
tracing for an arbitrary number of block devices (including the
basic mode of 'trace all block IO in the system') and a much wider
range of filtering capabilities.
Thanks,
Ingo
>> @@ -193,6 +194,7 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
>> extern void blk_add_driver_data(struct request_queue *q, struct request *rq,
>> void *data, size_t len);
>> extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
>> + struct block_device *bdev,
>> char __user *arg);
>> extern int blk_trace_startstop(struct request_queue *q, int start);
>> extern int blk_trace_remove(struct request_queue *q);
>
> Small detail: you forgot about the !CONFIG_BLK_DEV_IO_TRACE case
> here, the wrapper macros there need to be updated.
>
Ah, sorry..
> (no need to resend - i fixed this up in the 1/3 and 3/3 patches)
>
and thanks! (But I think only 1/3 patch needs to be fixed)
The 3rd patch can be for 2.6.30, if Ted or somene else wants to use
ftrace-plugin blktrace to trace dm devices in 2.6.30.
--
Zefan
Ingo Molnar wrote:
> * Li Zefan <[email protected]> wrote:
>
>> From: Shawn Du <[email protected]>
>>
>> Though one can specify '-d /dev/sda1' when using blktrace, it
>> still traces the whole sda.
>>
>> To support per-partition tracing, when we start tracing, we
>> initialize bt->start_lba and bt->end_lba to the start and end
>> sector of that partition.
>>
>> Note some actions are per device, thus we don't filter 0-sector
>> events.
>>
>> The original patch and discussion can be found here:
>> http://marc.info/?l=linux-btrace&m=122949374214540&w=2
>>
>> Signed-off-by: Shawn Du <[email protected]>
>> Signed-off-by: Li Zefan <[email protected]>
>
> Thanks - beyond the small detail i mailed about a few minutes ago
> the series looks good: i'll queue this up in tracing/blktrace unless
> Jens has second thoughts.
>
> Lets note that this approach still has the (long existing)
> limitation that only one device can be block-traced at a time.
>
No, both userspace blktrace and ftrace-plugin trace can trace
more than one device at a time.
# btrace /dev/sda /dev/dm-0
or
# echo 1 > /sys/block/sda/trace/enable
# echo 1 > /sys/block/dm-0/trace/enable
> Furthermore, various other aspects of act_log_check() itself could
> be expressed in terms of per tracepoint filters as well: the PID
> filter field for example - which is supported in the ioctl ABI but
> currently not exposed in the user-space blktrace utility. Same goes
> for the action mask which is frequently used.
>
Actually action mask can be specified by 'blktrace -a/-A mask/mask_name'
But yes the pid filter is not exposed in user-space blktrace.
> But before we can lift all these limitations and can have equivalent
> functionality in the generic event tracer we still need more filter
> engine infrastructure work (range operators and dev_t field
> support). Plus TRACE_EVENT() based blk tracepoints.
>
> Once we have that, the conversion will be straightforward: all
> existing filter functionality of blktrace is static, so it will map
> directly to new-style filter expressions. That will give us block
> tracing for an arbitrary number of block devices (including the
> basic mode of 'trace all block IO in the system') and a much wider
> range of filtering capabilities.
>
> Thanks,
>
> Ingo
>
>
* Li Zefan <[email protected]> wrote:
> >> @@ -193,6 +194,7 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
> >> extern void blk_add_driver_data(struct request_queue *q, struct request *rq,
> >> void *data, size_t len);
> >> extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
> >> + struct block_device *bdev,
> >> char __user *arg);
> >> extern int blk_trace_startstop(struct request_queue *q, int start);
> >> extern int blk_trace_remove(struct request_queue *q);
> >
> > Small detail: you forgot about the !CONFIG_BLK_DEV_IO_TRACE case
> > here, the wrapper macros there need to be updated.
> >
>
> Ah, sorry..
>
> > (no need to resend - i fixed this up in the 1/3 and 3/3 patches)
> >
>
> and thanks! (But I think only 1/3 patch needs to be fixed)
3/3 had context dependencies - no functionality dependency.
> The 3rd patch can be for 2.6.30, if Ted or somene else wants to
> use ftrace-plugin blktrace to trace dm devices in 2.6.30.
ok, good point - we can cherry-pick it over into tracing/urgent
after Ted reports back his experiences with these changes.
Ingo
* Li Zefan <[email protected]> wrote:
> Ingo Molnar wrote:
> > * Li Zefan <[email protected]> wrote:
> >
> >> From: Shawn Du <[email protected]>
> >>
> >> Though one can specify '-d /dev/sda1' when using blktrace, it
> >> still traces the whole sda.
> >>
> >> To support per-partition tracing, when we start tracing, we
> >> initialize bt->start_lba and bt->end_lba to the start and end
> >> sector of that partition.
> >>
> >> Note some actions are per device, thus we don't filter 0-sector
> >> events.
> >>
> >> The original patch and discussion can be found here:
> >> http://marc.info/?l=linux-btrace&m=122949374214540&w=2
> >>
> >> Signed-off-by: Shawn Du <[email protected]>
> >> Signed-off-by: Li Zefan <[email protected]>
> >
> > Thanks - beyond the small detail i mailed about a few minutes ago
> > the series looks good: i'll queue this up in tracing/blktrace unless
> > Jens has second thoughts.
> >
> > Lets note that this approach still has the (long existing)
> > limitation that only one device can be block-traced at a time.
> >
>
> No, both userspace blktrace and ftrace-plugin trace can trace
> more than one device at a time.
>
> # btrace /dev/sda /dev/dm-0
>
> or
>
> # echo 1 > /sys/block/sda/trace/enable
> # echo 1 > /sys/block/dm-0/trace/enable
When they are independent - but not multiple partitions at a time:
[root@aldebaran ~]# echo 1 > /sys/block/sda/sda1/trace/enable
[root@aldebaran ~]# echo 1 > /sys/block/sda/sda2/trace/enable
-bash: echo: write error: Device or resource busy
[root@aldebaran ~]#
Nor did i see any "trace all block IO in the system" kind of
functionality in blktrace. (or maybe there's one that i missed?)
> > Furthermore, various other aspects of act_log_check() itself
> > could be expressed in terms of per tracepoint filters as well:
> > the PID filter field for example - which is supported in the
> > ioctl ABI but currently not exposed in the user-space blktrace
> > utility. Same goes for the action mask which is frequently used.
> >
>
> Actually action mask can be specified by 'blktrace -a/-A
> mask/mask_name'
Yes, this is what i meant by "which is frequently used".
Ingo
>>> Lets note that this approach still has the (long existing)
>>> limitation that only one device can be block-traced at a time.
>>>
>> No, both userspace blktrace and ftrace-plugin trace can trace
>> more than one device at a time.
>>
>> # btrace /dev/sda /dev/dm-0
>>
>> or
>>
>> # echo 1 > /sys/block/sda/trace/enable
>> # echo 1 > /sys/block/dm-0/trace/enable
>
> When they are independent - but not multiple partitions at a time:
>
The only way to trace multipl partitions is to trace the whole
sda, or set trace/start_lsa and trace/end_lsa properly.
> [root@aldebaran ~]# echo 1 > /sys/block/sda/sda1/trace/enable
> [root@aldebaran ~]# echo 1 > /sys/block/sda/sda2/trace/enable
> -bash: echo: write error: Device or resource busy
That's because struct blk_trace is attached to struct request_queue,
sda1 and sda2 share the same rq:
# echo 1 > /sys/block/sda/sda1/trace/enable
# cat /sys/block/sda/sda1/trace/enable
1
# cat /sys/block/sda/sda2/trace/enable
1
> [root@aldebaran ~]#
>
> Nor did i see any "trace all block IO in the system" kind of
> functionality in blktrace. (or maybe there's one that i missed?)
>
Right, and the only way to do this is 'blktrace sda sdb sdc ...'
* Li Zefan <[email protected]> wrote:
> >>> Lets note that this approach still has the (long existing)
> >>> limitation that only one device can be block-traced at a time.
> >>>
> >> No, both userspace blktrace and ftrace-plugin trace can trace
> >> more than one device at a time.
> >>
> >> # btrace /dev/sda /dev/dm-0
> >>
> >> or
> >>
> >> # echo 1 > /sys/block/sda/trace/enable
> >> # echo 1 > /sys/block/dm-0/trace/enable
> >
> > When they are independent - but not multiple partitions at a time:
>
> The only way to trace multipl partitions is to trace the whole
> sda, or set trace/start_lsa and trace/end_lsa properly.
... or, once we have the filtering engine upgraded, to use
or-connected filters:
# [mockup example]
sector >= 20000 && sector <= 30000
||
sector >= 50000 && sector <= 60000
Note that users dont have to care about these expressions - they
could get auto-added when tracing is enabled for a partition.
Such type of more complex compound filters are possible already -
what we dont have is comparison operators (right now we only have ==
and !=), nor built-in convenience support for dev_t.
Another variant would be:
dev == sda1
||
dev == sda3
type of compound filters - achieving the same goal as the sector
based filter.
> > [root@aldebaran ~]# echo 1 > /sys/block/sda/sda1/trace/enable
> > [root@aldebaran ~]# echo 1 > /sys/block/sda/sda2/trace/enable
> > -bash: echo: write error: Device or resource busy
>
> That's because struct blk_trace is attached to struct
> request_queue, sda1 and sda2 share the same rq:
>
> # echo 1 > /sys/block/sda/sda1/trace/enable
> # cat /sys/block/sda/sda1/trace/enable
> 1
> # cat /sys/block/sda/sda2/trace/enable
> 1
yes - i'm just pointing out the limitation. It's no big issue
currently - most of the actual tracing happens on specific
devices/partitions. (Perhaps 'whole system blk tracing' is a common
pattern though.)
I'm just pointing out that this is a beauty wart, and that it will
be mostly addressed when we go to TRACE_EVENT() based tracepoints in
blktrace :-)
Ingo
Commit-ID: 1411074bef90ccb3b709b98965ac79508b51c452
Gitweb: http://git.kernel.org/tip/1411074bef90ccb3b709b98965ac79508b51c452
Author: Li Zefan <[email protected]>
AuthorDate: Tue, 14 Apr 2009 13:59:34 +0800
Committer: Ingo Molnar <[email protected]>
CommitDate: Wed, 15 Apr 2009 09:38:44 +0200
blktrace: support per-partition tracing for ftrace plugin
The previous patch adds support to trace a single partition for
relay+ioctl blktrace, and this patch is for ftrace plugin blktrace:
# echo 1 > /sys/block/sda/sda7/enable
# cat start_lba
102398373
# cat end_lba
102703545
Signed-off-by: Li Zefan <[email protected]>
Acked-by: "Theodore Ts'o" <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Shawn Du <[email protected]>
Cc: Jens Axboe <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
---
kernel/trace/blktrace.c | 39 +++++++++++++++++++++++++--------------
1 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index e932654..d109898 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -403,6 +403,23 @@ static struct rchan_callbacks blk_relay_callbacks = {
.remove_buf_file = blk_remove_buf_file_callback,
};
+static void blk_trace_setup_lba(struct blk_trace *bt,
+ struct block_device *bdev)
+{
+ struct hd_struct *part = NULL;
+
+ if (bdev)
+ part = bdev->bd_part;
+
+ if (part) {
+ bt->start_lba = part->start_sect;
+ bt->end_lba = part->start_sect + part->nr_sects;
+ } else {
+ bt->start_lba = 0;
+ bt->end_lba = -1ULL;
+ }
+}
+
/*
* Setup everything required to start tracing
*/
@@ -413,7 +430,6 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
struct blk_trace *old_bt, *bt = NULL;
struct dentry *dir = NULL;
int ret, i;
- struct hd_struct *part = NULL;
if (!buts->buf_size || !buts->buf_nr)
return -EINVAL;
@@ -482,14 +498,7 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (!bt->act_mask)
bt->act_mask = (u16) -1;
- if (bdev)
- part = bdev->bd_part;
-
- if (part) {
- bt->start_lba = part->start_sect;
- bt->end_lba = part->start_sect + part->nr_sects;
- } else
- bt->end_lba = -1ULL;
+ blk_trace_setup_lba(bt, bdev);
/* overwrite with user settings */
if (buts->start_lba)
@@ -1370,7 +1379,8 @@ static int blk_trace_remove_queue(struct request_queue *q)
/*
* Setup everything required to start tracing
*/
-static int blk_trace_setup_queue(struct request_queue *q, dev_t dev)
+static int blk_trace_setup_queue(struct request_queue *q,
+ struct block_device *bdev)
{
struct blk_trace *old_bt, *bt = NULL;
int ret = -ENOMEM;
@@ -1383,9 +1393,10 @@ static int blk_trace_setup_queue(struct request_queue *q, dev_t dev)
if (!bt->msg_data)
goto free_bt;
- bt->dev = dev;
+ bt->dev = bdev->bd_dev;
bt->act_mask = (u16)-1;
- bt->end_lba = -1ULL;
+
+ blk_trace_setup_lba(bt, bdev);
old_bt = xchg(&q->blk_trace, bt);
if (old_bt != NULL) {
@@ -1602,7 +1613,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
if (attr == &dev_attr_enable) {
if (value)
- ret = blk_trace_setup_queue(q, bdev->bd_dev);
+ ret = blk_trace_setup_queue(q, bdev);
else
ret = blk_trace_remove_queue(q);
goto out_unlock_bdev;
@@ -1610,7 +1621,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
ret = 0;
if (q->blk_trace == NULL)
- ret = blk_trace_setup_queue(q, bdev->bd_dev);
+ ret = blk_trace_setup_queue(q, bdev);
if (ret == 0) {
if (attr == &dev_attr_act_mask)
Commit-ID: fd22f2711aadb26ff56f7d3637430af098dfaeb1
Gitweb: http://git.kernel.org/tip/fd22f2711aadb26ff56f7d3637430af098dfaeb1
Author: Li Zefan <[email protected]>
AuthorDate: Tue, 14 Apr 2009 14:00:05 +0800
Committer: Ingo Molnar <[email protected]>
CommitDate: Wed, 15 Apr 2009 09:38:54 +0200
blktrace: add trace/ to /sys/block/sda
Impact: allow ftrace-plugin blktrace to trace device-mapper devices
To trace a single partition:
# echo 1 > /sys/block/sda/sda1/enable
To trace the whole sda instead:
# echo 1 > /sys/block/sda/enable
Thus we also fix an issue reported by Ted, that ftrace-plugin blktrace
can't be used to trace device-mapper devices.
Now:
# echo 1 > /sys/block/dm-0/trace/enable
echo: write error: No such device or address
# mount -t ext4 /dev/dm-0 /mnt
# echo 1 > /sys/block/dm-0/trace/enable
# echo blk > /debug/tracing/current_tracer
Reported-by: Theodore Tso <[email protected]>
Signed-off-by: Li Zefan <[email protected]>
Acked-by: "Theodore Ts'o" <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Shawn Du <[email protected]>
Cc: Jens Axboe <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
---
block/blk-sysfs.c | 7 ++++++-
include/linux/blktrace_api.h | 6 ++++++
kernel/trace/blktrace.c | 5 +++++
3 files changed, 17 insertions(+), 1 deletions(-)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 73f36be..8653d71 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -387,16 +387,21 @@ struct kobj_type blk_queue_ktype = {
int blk_register_queue(struct gendisk *disk)
{
int ret;
+ struct device *dev = disk_to_dev(disk);
struct request_queue *q = disk->queue;
if (WARN_ON(!q))
return -ENXIO;
+ ret = blk_trace_init_sysfs(dev);
+ if (ret)
+ return ret;
+
if (!q->request_fn)
return 0;
- ret = kobject_add(&q->kobj, kobject_get(&disk_to_dev(disk)->kobj),
+ ret = kobject_add(&q->kobj, kobject_get(&dev->kobj),
"%s", "queue");
if (ret < 0)
return ret;
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 267edc4..62763c9 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -198,6 +198,7 @@ extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
char __user *arg);
extern int blk_trace_startstop(struct request_queue *q, int start);
extern int blk_trace_remove(struct request_queue *q);
+extern int blk_trace_init_sysfs(struct device *dev);
extern struct attribute_group blk_trace_attr_group;
@@ -210,6 +211,11 @@ extern struct attribute_group blk_trace_attr_group;
# define blk_trace_startstop(q, start) (-ENOTTY)
# define blk_trace_remove(q) (-ENOTTY)
# define blk_add_trace_msg(q, fmt, ...) do { } while (0)
+static inline int blk_trace_init_sysfs(struct device *dev)
+{
+ return 0;
+}
+
#endif /* CONFIG_BLK_DEV_IO_TRACE */
#endif /* __KERNEL__ */
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index d109898..8e7c5da 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -1644,3 +1644,8 @@ out:
return ret ? ret : count;
}
+int blk_trace_init_sysfs(struct device *dev)
+{
+ return sysfs_create_group(&dev->kobj, &blk_trace_attr_group);
+}
+
Commit-ID: 31c786d452a13d0170622632ae52ccbc8a5a4d74
Gitweb: http://git.kernel.org/tip/31c786d452a13d0170622632ae52ccbc8a5a4d74
Author: Shawn Du <[email protected]>
AuthorDate: Tue, 14 Apr 2009 13:58:56 +0800
Committer: Ingo Molnar <[email protected]>
CommitDate: Wed, 15 Apr 2009 09:38:27 +0200
blktrace: support per-partition tracing
Though one can specify '-d /dev/sda1' when using blktrace, it still
traces the whole sda.
To support per-partition tracing, when we start tracing, we initialize
bt->start_lba and bt->end_lba to the start and end sector of that
partition.
Note some actions are per device, thus we don't filter 0-sector events.
The original patch and discussion can be found here:
http://marc.info/?l=linux-btrace&m=122949374214540&w=2
Signed-off-by: Shawn Du <[email protected]>
Signed-off-by: Li Zefan <[email protected]>
Acked-by: "Theodore Ts'o" <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Jens Axboe <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
---
block/compat_ioctl.c | 2 +-
drivers/scsi/sg.c | 1 +
include/linux/blktrace_api.h | 24 +++++++++++++-----------
kernel/trace/blktrace.c | 29 +++++++++++++++++++++--------
4 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index f87615d..f8c218c 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -568,7 +568,7 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg)
memcpy(&buts.name, &cbuts.name, 32);
mutex_lock(&bdev->bd_mutex);
- ret = do_blk_trace_setup(q, b, bdev->bd_dev, &buts);
+ ret = do_blk_trace_setup(q, b, bdev->bd_dev, bdev, &buts);
mutex_unlock(&bdev->bd_mutex);
if (ret)
return ret;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 82312df..49c9873 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1065,6 +1065,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
return blk_trace_setup(sdp->device->request_queue,
sdp->disk->disk_name,
MKDEV(SCSI_GENERIC_MAJOR, sdp->index),
+ NULL,
(char *)arg);
case BLKTRACESTART:
return blk_trace_startstop(sdp->device->request_queue, 1);
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index d960889..267edc4 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -165,8 +165,9 @@ struct blk_trace {
extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *);
extern void blk_trace_shutdown(struct request_queue *);
-extern int do_blk_trace_setup(struct request_queue *q,
- char *name, dev_t dev, struct blk_user_trace_setup *buts);
+extern int do_blk_trace_setup(struct request_queue *q, char *name,
+ dev_t dev, struct block_device *bdev,
+ struct blk_user_trace_setup *buts);
extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
/**
@@ -193,6 +194,7 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
extern void blk_add_driver_data(struct request_queue *q, struct request *rq,
void *data, size_t len);
extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+ struct block_device *bdev,
char __user *arg);
extern int blk_trace_startstop(struct request_queue *q, int start);
extern int blk_trace_remove(struct request_queue *q);
@@ -200,15 +202,15 @@ extern int blk_trace_remove(struct request_queue *q);
extern struct attribute_group blk_trace_attr_group;
#else /* !CONFIG_BLK_DEV_IO_TRACE */
-#define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY)
-#define blk_trace_shutdown(q) do { } while (0)
-#define do_blk_trace_setup(q, name, dev, buts) (-ENOTTY)
-#define blk_add_driver_data(q, rq, data, len) do {} while (0)
-#define blk_trace_setup(q, name, dev, arg) (-ENOTTY)
-#define blk_trace_startstop(q, start) (-ENOTTY)
-#define blk_trace_remove(q) (-ENOTTY)
-#define blk_add_trace_msg(q, fmt, ...) do { } while (0)
-
+# define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY)
+# define blk_trace_shutdown(q) do { } while (0)
+# define do_blk_trace_setup(q, name, dev, bdev, buts) (-ENOTTY)
+# define blk_add_driver_data(q, rq, data, len) do {} while (0)
+# define blk_trace_setup(q, name, dev, bdev, arg) (-ENOTTY)
+# define blk_trace_startstop(q, start) (-ENOTTY)
+# define blk_trace_remove(q) (-ENOTTY)
+# define blk_add_trace_msg(q, fmt, ...) do { } while (0)
#endif /* CONFIG_BLK_DEV_IO_TRACE */
+
#endif /* __KERNEL__ */
#endif
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 2b98195..e932654 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -147,7 +147,7 @@ static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
{
if (((bt->act_mask << BLK_TC_SHIFT) & what) == 0)
return 1;
- if (sector < bt->start_lba || sector > bt->end_lba)
+ if (sector && (sector < bt->start_lba || sector > bt->end_lba))
return 1;
if (bt->pid && pid != bt->pid)
return 1;
@@ -192,7 +192,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
what |= MASK_TC_BIT(rw, DISCARD);
pid = tsk->pid;
- if (unlikely(act_log_check(bt, what, sector, pid)))
+ if (act_log_check(bt, what, sector, pid))
return;
cpu = raw_smp_processor_id();
@@ -407,11 +407,13 @@ static struct rchan_callbacks blk_relay_callbacks = {
* Setup everything required to start tracing
*/
int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
- struct blk_user_trace_setup *buts)
+ struct block_device *bdev,
+ struct blk_user_trace_setup *buts)
{
struct blk_trace *old_bt, *bt = NULL;
struct dentry *dir = NULL;
int ret, i;
+ struct hd_struct *part = NULL;
if (!buts->buf_size || !buts->buf_nr)
return -EINVAL;
@@ -480,11 +482,21 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (!bt->act_mask)
bt->act_mask = (u16) -1;
- bt->start_lba = buts->start_lba;
- bt->end_lba = buts->end_lba;
- if (!bt->end_lba)
+ if (bdev)
+ part = bdev->bd_part;
+
+ if (part) {
+ bt->start_lba = part->start_sect;
+ bt->end_lba = part->start_sect + part->nr_sects;
+ } else
bt->end_lba = -1ULL;
+ /* overwrite with user settings */
+ if (buts->start_lba)
+ bt->start_lba = buts->start_lba;
+ if (buts->end_lba)
+ bt->end_lba = buts->end_lba;
+
bt->pid = buts->pid;
bt->trace_state = Blktrace_setup;
@@ -505,6 +517,7 @@ err:
}
int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+ struct block_device *bdev,
char __user *arg)
{
struct blk_user_trace_setup buts;
@@ -514,7 +527,7 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (ret)
return -EFAULT;
- ret = do_blk_trace_setup(q, name, dev, &buts);
+ ret = do_blk_trace_setup(q, name, dev, bdev, &buts);
if (ret)
return ret;
@@ -582,7 +595,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
switch (cmd) {
case BLKTRACESETUP:
bdevname(bdev, b);
- ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
+ ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
break;
case BLKTRACESTART:
start = 1;
Commit-ID: d0deef5b14af7d5bbd0003a0a2a1a32326e20a6d
Gitweb: http://git.kernel.org/tip/d0deef5b14af7d5bbd0003a0a2a1a32326e20a6d
Author: Shawn Du <[email protected]>
AuthorDate: Tue, 14 Apr 2009 13:58:56 +0800
Committer: Ingo Molnar <[email protected]>
CommitDate: Thu, 16 Apr 2009 10:10:57 +0200
blktrace: support per-partition tracing
Though one can specify '-d /dev/sda1' when using blktrace, it still
traces the whole sda.
To support per-partition tracing, when we start tracing, we initialize
bt->start_lba and bt->end_lba to the start and end sector of that
partition.
Note some actions are per device, thus we don't filter 0-sector events.
The original patch and discussion can be found here:
http://marc.info/?l=linux-btrace&m=122949374214540&w=2
Signed-off-by: Shawn Du <[email protected]>
Signed-off-by: Li Zefan <[email protected]>
Acked-by: "Theodore Ts'o" <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Jens Axboe <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
---
block/compat_ioctl.c | 2 +-
drivers/scsi/sg.c | 1 +
include/linux/blktrace_api.h | 24 +++++++++++++-----------
kernel/trace/blktrace.c | 29 +++++++++++++++++++++--------
4 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index f87615d..f8c218c 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -568,7 +568,7 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg)
memcpy(&buts.name, &cbuts.name, 32);
mutex_lock(&bdev->bd_mutex);
- ret = do_blk_trace_setup(q, b, bdev->bd_dev, &buts);
+ ret = do_blk_trace_setup(q, b, bdev->bd_dev, bdev, &buts);
mutex_unlock(&bdev->bd_mutex);
if (ret)
return ret;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 82312df..49c9873 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1065,6 +1065,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
return blk_trace_setup(sdp->device->request_queue,
sdp->disk->disk_name,
MKDEV(SCSI_GENERIC_MAJOR, sdp->index),
+ NULL,
(char *)arg);
case BLKTRACESTART:
return blk_trace_startstop(sdp->device->request_queue, 1);
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index d960889..267edc4 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -165,8 +165,9 @@ struct blk_trace {
extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *);
extern void blk_trace_shutdown(struct request_queue *);
-extern int do_blk_trace_setup(struct request_queue *q,
- char *name, dev_t dev, struct blk_user_trace_setup *buts);
+extern int do_blk_trace_setup(struct request_queue *q, char *name,
+ dev_t dev, struct block_device *bdev,
+ struct blk_user_trace_setup *buts);
extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
/**
@@ -193,6 +194,7 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...);
extern void blk_add_driver_data(struct request_queue *q, struct request *rq,
void *data, size_t len);
extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+ struct block_device *bdev,
char __user *arg);
extern int blk_trace_startstop(struct request_queue *q, int start);
extern int blk_trace_remove(struct request_queue *q);
@@ -200,15 +202,15 @@ extern int blk_trace_remove(struct request_queue *q);
extern struct attribute_group blk_trace_attr_group;
#else /* !CONFIG_BLK_DEV_IO_TRACE */
-#define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY)
-#define blk_trace_shutdown(q) do { } while (0)
-#define do_blk_trace_setup(q, name, dev, buts) (-ENOTTY)
-#define blk_add_driver_data(q, rq, data, len) do {} while (0)
-#define blk_trace_setup(q, name, dev, arg) (-ENOTTY)
-#define blk_trace_startstop(q, start) (-ENOTTY)
-#define blk_trace_remove(q) (-ENOTTY)
-#define blk_add_trace_msg(q, fmt, ...) do { } while (0)
-
+# define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY)
+# define blk_trace_shutdown(q) do { } while (0)
+# define do_blk_trace_setup(q, name, dev, bdev, buts) (-ENOTTY)
+# define blk_add_driver_data(q, rq, data, len) do {} while (0)
+# define blk_trace_setup(q, name, dev, bdev, arg) (-ENOTTY)
+# define blk_trace_startstop(q, start) (-ENOTTY)
+# define blk_trace_remove(q) (-ENOTTY)
+# define blk_add_trace_msg(q, fmt, ...) do { } while (0)
#endif /* CONFIG_BLK_DEV_IO_TRACE */
+
#endif /* __KERNEL__ */
#endif
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 2b98195..e932654 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -147,7 +147,7 @@ static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
{
if (((bt->act_mask << BLK_TC_SHIFT) & what) == 0)
return 1;
- if (sector < bt->start_lba || sector > bt->end_lba)
+ if (sector && (sector < bt->start_lba || sector > bt->end_lba))
return 1;
if (bt->pid && pid != bt->pid)
return 1;
@@ -192,7 +192,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
what |= MASK_TC_BIT(rw, DISCARD);
pid = tsk->pid;
- if (unlikely(act_log_check(bt, what, sector, pid)))
+ if (act_log_check(bt, what, sector, pid))
return;
cpu = raw_smp_processor_id();
@@ -407,11 +407,13 @@ static struct rchan_callbacks blk_relay_callbacks = {
* Setup everything required to start tracing
*/
int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
- struct blk_user_trace_setup *buts)
+ struct block_device *bdev,
+ struct blk_user_trace_setup *buts)
{
struct blk_trace *old_bt, *bt = NULL;
struct dentry *dir = NULL;
int ret, i;
+ struct hd_struct *part = NULL;
if (!buts->buf_size || !buts->buf_nr)
return -EINVAL;
@@ -480,11 +482,21 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (!bt->act_mask)
bt->act_mask = (u16) -1;
- bt->start_lba = buts->start_lba;
- bt->end_lba = buts->end_lba;
- if (!bt->end_lba)
+ if (bdev)
+ part = bdev->bd_part;
+
+ if (part) {
+ bt->start_lba = part->start_sect;
+ bt->end_lba = part->start_sect + part->nr_sects;
+ } else
bt->end_lba = -1ULL;
+ /* overwrite with user settings */
+ if (buts->start_lba)
+ bt->start_lba = buts->start_lba;
+ if (buts->end_lba)
+ bt->end_lba = buts->end_lba;
+
bt->pid = buts->pid;
bt->trace_state = Blktrace_setup;
@@ -505,6 +517,7 @@ err:
}
int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+ struct block_device *bdev,
char __user *arg)
{
struct blk_user_trace_setup buts;
@@ -514,7 +527,7 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (ret)
return -EFAULT;
- ret = do_blk_trace_setup(q, name, dev, &buts);
+ ret = do_blk_trace_setup(q, name, dev, bdev, &buts);
if (ret)
return ret;
@@ -582,7 +595,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
switch (cmd) {
case BLKTRACESETUP:
bdevname(bdev, b);
- ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
+ ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
break;
case BLKTRACESTART:
start = 1;
Commit-ID: 9908c30997b8a73c95f836170b9998dae9aa3f4a
Gitweb: http://git.kernel.org/tip/9908c30997b8a73c95f836170b9998dae9aa3f4a
Author: Li Zefan <[email protected]>
AuthorDate: Tue, 14 Apr 2009 13:59:34 +0800
Committer: Ingo Molnar <[email protected]>
CommitDate: Thu, 16 Apr 2009 10:10:58 +0200
blktrace: support per-partition tracing for ftrace plugin
The previous patch adds support to trace a single partition for
relay+ioctl blktrace, and this patch is for ftrace plugin blktrace:
# echo 1 > /sys/block/sda/sda7/enable
# cat start_lba
102398373
# cat end_lba
102703545
Signed-off-by: Li Zefan <[email protected]>
Acked-by: "Theodore Ts'o" <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Shawn Du <[email protected]>
Cc: Jens Axboe <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
---
kernel/trace/blktrace.c | 39 +++++++++++++++++++++++++--------------
1 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index e932654..d109898 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -403,6 +403,23 @@ static struct rchan_callbacks blk_relay_callbacks = {
.remove_buf_file = blk_remove_buf_file_callback,
};
+static void blk_trace_setup_lba(struct blk_trace *bt,
+ struct block_device *bdev)
+{
+ struct hd_struct *part = NULL;
+
+ if (bdev)
+ part = bdev->bd_part;
+
+ if (part) {
+ bt->start_lba = part->start_sect;
+ bt->end_lba = part->start_sect + part->nr_sects;
+ } else {
+ bt->start_lba = 0;
+ bt->end_lba = -1ULL;
+ }
+}
+
/*
* Setup everything required to start tracing
*/
@@ -413,7 +430,6 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
struct blk_trace *old_bt, *bt = NULL;
struct dentry *dir = NULL;
int ret, i;
- struct hd_struct *part = NULL;
if (!buts->buf_size || !buts->buf_nr)
return -EINVAL;
@@ -482,14 +498,7 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
if (!bt->act_mask)
bt->act_mask = (u16) -1;
- if (bdev)
- part = bdev->bd_part;
-
- if (part) {
- bt->start_lba = part->start_sect;
- bt->end_lba = part->start_sect + part->nr_sects;
- } else
- bt->end_lba = -1ULL;
+ blk_trace_setup_lba(bt, bdev);
/* overwrite with user settings */
if (buts->start_lba)
@@ -1370,7 +1379,8 @@ static int blk_trace_remove_queue(struct request_queue *q)
/*
* Setup everything required to start tracing
*/
-static int blk_trace_setup_queue(struct request_queue *q, dev_t dev)
+static int blk_trace_setup_queue(struct request_queue *q,
+ struct block_device *bdev)
{
struct blk_trace *old_bt, *bt = NULL;
int ret = -ENOMEM;
@@ -1383,9 +1393,10 @@ static int blk_trace_setup_queue(struct request_queue *q, dev_t dev)
if (!bt->msg_data)
goto free_bt;
- bt->dev = dev;
+ bt->dev = bdev->bd_dev;
bt->act_mask = (u16)-1;
- bt->end_lba = -1ULL;
+
+ blk_trace_setup_lba(bt, bdev);
old_bt = xchg(&q->blk_trace, bt);
if (old_bt != NULL) {
@@ -1602,7 +1613,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
if (attr == &dev_attr_enable) {
if (value)
- ret = blk_trace_setup_queue(q, bdev->bd_dev);
+ ret = blk_trace_setup_queue(q, bdev);
else
ret = blk_trace_remove_queue(q);
goto out_unlock_bdev;
@@ -1610,7 +1621,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
ret = 0;
if (q->blk_trace == NULL)
- ret = blk_trace_setup_queue(q, bdev->bd_dev);
+ ret = blk_trace_setup_queue(q, bdev);
if (ret == 0) {
if (attr == &dev_attr_act_mask)
Commit-ID: 1d54ad6da9192fed5dd3b60224d9f2dfea0dcd82
Gitweb: http://git.kernel.org/tip/1d54ad6da9192fed5dd3b60224d9f2dfea0dcd82
Author: Li Zefan <[email protected]>
AuthorDate: Tue, 14 Apr 2009 14:00:05 +0800
Committer: Ingo Molnar <[email protected]>
CommitDate: Thu, 16 Apr 2009 10:10:59 +0200
blktrace: add trace/ to /sys/block/sda
Impact: allow ftrace-plugin blktrace to trace device-mapper devices
To trace a single partition:
# echo 1 > /sys/block/sda/sda1/enable
To trace the whole sda instead:
# echo 1 > /sys/block/sda/enable
Thus we also fix an issue reported by Ted, that ftrace-plugin blktrace
can't be used to trace device-mapper devices.
Now:
# echo 1 > /sys/block/dm-0/trace/enable
echo: write error: No such device or address
# mount -t ext4 /dev/dm-0 /mnt
# echo 1 > /sys/block/dm-0/trace/enable
# echo blk > /debug/tracing/current_tracer
Reported-by: Theodore Tso <[email protected]>
Signed-off-by: Li Zefan <[email protected]>
Acked-by: "Theodore Ts'o" <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Shawn Du <[email protected]>
Cc: Jens Axboe <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
---
block/blk-sysfs.c | 7 ++++++-
include/linux/blktrace_api.h | 6 ++++++
kernel/trace/blktrace.c | 5 +++++
3 files changed, 17 insertions(+), 1 deletions(-)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 73f36be..8653d71 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -387,16 +387,21 @@ struct kobj_type blk_queue_ktype = {
int blk_register_queue(struct gendisk *disk)
{
int ret;
+ struct device *dev = disk_to_dev(disk);
struct request_queue *q = disk->queue;
if (WARN_ON(!q))
return -ENXIO;
+ ret = blk_trace_init_sysfs(dev);
+ if (ret)
+ return ret;
+
if (!q->request_fn)
return 0;
- ret = kobject_add(&q->kobj, kobject_get(&disk_to_dev(disk)->kobj),
+ ret = kobject_add(&q->kobj, kobject_get(&dev->kobj),
"%s", "queue");
if (ret < 0)
return ret;
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 267edc4..62763c9 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -198,6 +198,7 @@ extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
char __user *arg);
extern int blk_trace_startstop(struct request_queue *q, int start);
extern int blk_trace_remove(struct request_queue *q);
+extern int blk_trace_init_sysfs(struct device *dev);
extern struct attribute_group blk_trace_attr_group;
@@ -210,6 +211,11 @@ extern struct attribute_group blk_trace_attr_group;
# define blk_trace_startstop(q, start) (-ENOTTY)
# define blk_trace_remove(q) (-ENOTTY)
# define blk_add_trace_msg(q, fmt, ...) do { } while (0)
+static inline int blk_trace_init_sysfs(struct device *dev)
+{
+ return 0;
+}
+
#endif /* CONFIG_BLK_DEV_IO_TRACE */
#endif /* __KERNEL__ */
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index d109898..8e7c5da 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -1644,3 +1644,8 @@ out:
return ret ? ret : count;
}
+int blk_trace_init_sysfs(struct device *dev)
+{
+ return sysfs_create_group(&dev->kobj, &blk_trace_attr_group);
+}
+