Add a flight data recorder for scsi commands
A message that is not in the archive (sent off-list or not yet received): [email protected]
RFC PATCH 1/1 Add a flight data recorder for scsi commands
Here is a fun patch in an early state. Essentially I want to trace scsi commands, which has already been done long ago. The problem I have is that I care about all the scsi commands for one particular device - without knowing in advance which device it will be. Once I know the device in question, I want to dump the last X commands.
The existing tracing is covering all commands to all devices. So either I have to oversize my trace buffer and dump way too much, or I will miss the stuff I am interested in most of the time. Hence my per-device trace buffer (called fdr to avoid namespace collisions).
Steven, is there some magic 2-line patch that would also give me what I want without having to reinvent all your infrastructure and doing such a bad job?
Jörn
--
It is better to die of hunger having lived without grief and fear, than to live with a troubled spirit amid abundance.
-- Epictetus
And dump the fdr whenever we run into a timeout. If the timeout is caused by a crashed target and the target crash is triggered by a weird command sent by us, we might want to know which commands we send out.
--- drivers/scsi/scsi.c | 31 +++++++++++++++++++++++++++++++ drivers/scsi/scsi_error.c | 38 ++++++++++++++++++++++++++++++++++++++ drivers/scsi/scsi_scan.c | 1 + include/scsi/scsi_device.h | 13 +++++++++++++ 4 files changed, 83 insertions(+)
drivers/scsi/scsi.c +31 -0
@@ -647,6 +647,36 @@ void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd) }EXPORT_SYMBOL (scsi_cmd_get_serial); +static void fdr_add (struct fdr_ring *ring,struct fdr_entry *entry) +{ +struct fdr_entry *old; +unsigned long flags; +int index; + +spin_lock_irqsave (&ring->fdr_lock, flags); + index = ring->last_entry +1 ; +if (index >=ARRAY_SIZE (ring->entry)) + index =0 ; + old = ring->entry[index]; + ring->entry[index] = entry; + ring->last_entry = index; +spin_unlock_irqrestore (&ring->fdr_lock, flags); +kfree (old); +} + +static void fdr_scsi_cmd (struct scsi_cmnd *cmd) +{ +struct fdr_entry *new; + + new =kmalloc (sizeof (*new) + cmd->cmd_len,GFP_KERNEL ); +if (!new) +return ; + new->ts_nsec =local_clock (); + new->size = cmd->cmd_len; +memcpy (new->data, cmd->cmnd, new->size); +fdr_add (&cmd->device->fdr, new); +} +/** * scsi_dispatch_command - Dispatch a command to the low-level driver. * @cmd: command block we are dispatching.
@@ -747,6 +777,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)scsi_done (cmd); }else {trace_scsi_dispatch_cmd_start (cmd); +fdr_scsi_cmd (cmd); cmd->scsi_done = scsi_done; rtn = host->hostt->queuecommand (host, cmd); }
drivers/scsi/scsi_error.c +38 -0
@@ -132,6 +132,41 @@ static void queue_for_eh(struct Scsi_Host *shost, struct scsi_cmnd *scmd)schedule_work (&scmd->abort_work); } +static void scsi_fdr_dump (struct fdr_entry *entry) +{ +char buf[64 +8 +2 ]; +unsigned long ts = entry->ts_nsec; +unsigned long rem_nsec; + + rem_nsec =do_div (ts,1000000000 ); +hex_dump_to_buffer (entry->data, entry->size,32 ,8 , buf,sizeof (buf),0 ); +pr_info ("%6lu.%06lu: %s\n" , ts, rem_nsec, buf); +} + +static void fdr_dump (struct fdr_ring *ring,void (*dump) (struct fdr_entry * entry)) +{ +struct fdr_entry *entry; +unsigned long flags; +int i; + +spin_lock_irqsave (&ring->fdr_lock, flags); +for (i = ring->last_entry +1 ; i <ARRAY_SIZE (ring->entry); i++) { + entry = ring->entry[i]; + ring->entry[i] =NULL ; +if (entry) +dump (entry); +kfree (entry); + } +for (i =0 ; i < ring->last_entry; i++) { + entry = ring->entry[i]; + ring->entry[i] =NULL ; +if (entry) +dump (entry); +kfree (entry); + } +spin_unlock_irqrestore (&ring->fdr_lock, flags); +} +/** * scsi_times_out - Timeout function for normal scsi commands. * @req: request that is timing out.
@@ -148,6 +183,9 @@ enum blk_eh_timer_return scsi_times_out(struct request *req)enum blk_eh_timer_return rtn =BLK_EH_NOT_HANDLED ;struct Scsi_Host *host = scmd->device->host; +sdev_printk (KERN_INFO , scmd->device,"dumping cdb recorder\n" ); +fdr_dump (&scmd->device->fdr, scsi_fdr_dump); +trace_scsi_dispatch_cmd_timeout (scmd);scsi_log_completion (scmd,TIMEOUT_ERROR );
drivers/scsi/scsi_scan.c +1 -0
@@ -252,6 +252,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,INIT_LIST_HEAD (&sdev->starved_entry);INIT_LIST_HEAD (&sdev->event_list);spin_lock_init (&sdev->list_lock); +spin_lock_init (&sdev->fdr.fdr_lock);INIT_WORK (&sdev->event_work, scsi_evt_thread);INIT_WORK (&sdev->requeue_work, scsi_requeue_run_queue);/* Limit scsi messages per device */
include/scsi/scsi_device.h +13 -0
@@ -97,6 +97,18 @@ enum scsi_err_inj_duration { };#endif /* CONFIG_SCSI_ERROR_INJECTOR */ +struct fdr_entry { +unsigned long ts_nsec; +u32 size; +u8 data[0 ]; +}; + +struct fdr_ring { +spinlock_t fdr_lock; +int last_entry; +struct fdr_entry *entry[1000 ]; +}; +struct scsi_device {struct Scsi_Host *host;struct request_queue *request_queue;
@@ -222,6 +234,7 @@ struct scsi_device {struct scsi_dh_data *scsi_dh_data;enum scsi_device_state sdev_state;struct ratelimit_state sdev_ratelimit; +struct fdr_ring fdr;unsigned long sdev_data[0 ]; } __attribute__((aligned(sizeof(unsigned long))));
Signature · 5 lines
1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 11 lines · Jörn Engel
Here is a fun patch in an early state. Essentially I want to trace scsi commands, which has already been done long ago. The problem I have is that I care about all the scsi commands for one particular device - without knowing in advance which device it will be. Once I know the device in question, I want to dump the last X commands.
The existing tracing is covering all commands to all devices. So either I have to oversize my trace buffer and dump way too much, or I will miss the stuff I am interested in most of the time. Hence my per-device trace buffer (called fdr to avoid namespace collisions).
Sounds like a useful idea..
However, it adds another kmalloc + spin_lock -> spin_unlock in the fast path for each struct scsi_cmnd I/O dispatch, which is exactly what the scsi-mq prototype code is trying to avoid at all costs.
So that said, this logic should be disabled (by default) with some manner of sysfs attribute in /sys/class/scsi_device (or some other mechanism) that allows it to be enabled/disabled on a per struct scsi_device basis.
I imagine that is already on your TODO, but given the gaping hole in SCSI performance vs. raw block that scsi-mq is attempting to address, I just wanted to make sure. ;)
Thanks,
--nab
Quoted 165 lines
Steven, is there some magic 2-line patch that would also give me what I want without having to reinvent all your infrastructure and doing such a bad job?
Jörn
--
It is better to die of hunger having lived without grief and fear, than to live with a troubled spirit amid abundance.
-- EpictetusAnd dump the fdr whenever we run into a timeout. If the timeout is caused by a crashed target and the target crash is triggered by a weird command sent by us, we might want to know which commands we send out.
Signed-off-by Joern Engel <[email protected]>--- drivers/scsi/scsi.c | 31 +++++++++++++++++++++++++++++++ drivers/scsi/scsi_error.c | 38 ++++++++++++++++++++++++++++++++++++++ drivers/scsi/scsi_scan.c | 1 + include/scsi/scsi_device.h | 13 +++++++++++++ 4 files changed, 83 insertions(+)drivers/scsi/scsi.c +31
-0@@ -647,6 +647,36 @@ void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd) }EXPORT_SYMBOL (scsi_cmd_get_serial); +static void fdr_add (struct fdr_ring *ring,struct fdr_entry *entry) +{ +struct fdr_entry *old; +unsigned long flags; +int index; + +spin_lock_irqsave (&ring->fdr_lock, flags); + index = ring->last_entry +1 ; +if (index >=ARRAY_SIZE (ring->entry)) + index =0 ; + old = ring->entry[index]; + ring->entry[index] = entry; + ring->last_entry = index; +spin_unlock_irqrestore (&ring->fdr_lock, flags); +kfree (old); +} + +static void fdr_scsi_cmd (struct scsi_cmnd *cmd) +{ +struct fdr_entry *new; + + new =kmalloc (sizeof (*new) + cmd->cmd_len,GFP_KERNEL ); +if (!new) +return ; + new->ts_nsec =local_clock (); + new->size = cmd->cmd_len; +memcpy (new->data, cmd->cmnd, new->size); +fdr_add (&cmd->device->fdr, new); +} +/** * scsi_dispatch_command - Dispatch a command to the low-level driver. * @cmd: command block we are dispatching. @@ -747,6 +777,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)scsi_done (cmd); }else {trace_scsi_dispatch_cmd_start (cmd); +fdr_scsi_cmd (cmd); cmd->scsi_done = scsi_done; rtn = host->hostt->queuecommand (host, cmd); }drivers/scsi/scsi_error.c +38
-0@@ -132,6 +132,41 @@ static void queue_for_eh(struct Scsi_Host *shost, struct scsi_cmnd *scmd)schedule_work (&scmd->abort_work); } +static void scsi_fdr_dump (struct fdr_entry *entry) +{ +char buf[64 +8 +2 ]; +unsigned long ts = entry->ts_nsec; +unsigned long rem_nsec; + + rem_nsec =do_div (ts,1000000000 ); +hex_dump_to_buffer (entry->data, entry->size,32 ,8 , buf,sizeof (buf),0 ); +pr_info ("%6lu.%06lu: %s\n" , ts, rem_nsec, buf); +} + +static void fdr_dump (struct fdr_ring *ring,void (*dump) (struct fdr_entry * entry)) +{ +struct fdr_entry *entry; +unsigned long flags; +int i; + +spin_lock_irqsave (&ring->fdr_lock, flags); +for (i = ring->last_entry +1 ; i <ARRAY_SIZE (ring->entry); i++) { + entry = ring->entry[i]; + ring->entry[i] =NULL ; +if (entry) +dump (entry); +kfree (entry); + } +for (i =0 ; i < ring->last_entry; i++) { + entry = ring->entry[i]; + ring->entry[i] =NULL ; +if (entry) +dump (entry); +kfree (entry); + } +spin_unlock_irqrestore (&ring->fdr_lock, flags); +} +/** * scsi_times_out - Timeout function for normal scsi commands. * @req: request that is timing out. @@ -148,6 +183,9 @@ enum blk_eh_timer_return scsi_times_out(struct request *req)enum blk_eh_timer_return rtn =BLK_EH_NOT_HANDLED ;struct Scsi_Host *host = scmd->device->host; +sdev_printk (KERN_INFO , scmd->device,"dumping cdb recorder\n" ); +fdr_dump (&scmd->device->fdr, scsi_fdr_dump); +trace_scsi_dispatch_cmd_timeout (scmd);scsi_log_completion (scmd,TIMEOUT_ERROR );drivers/scsi/scsi_scan.c +1
-0@@ -252,6 +252,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,INIT_LIST_HEAD (&sdev->starved_entry);INIT_LIST_HEAD (&sdev->event_list);spin_lock_init (&sdev->list_lock); +spin_lock_init (&sdev->fdr.fdr_lock);INIT_WORK (&sdev->event_work, scsi_evt_thread);INIT_WORK (&sdev->requeue_work, scsi_requeue_run_queue);/* Limit scsi messages per device */ include/scsi/scsi_device.h +12
-0@@ -97,6 +97,18 @@ enum scsi_err_inj_duration { };#endif /* CONFIG_SCSI_ERROR_INJECTOR */ +struct fdr_entry { +unsigned long ts_nsec; +u32 size; +u8 data[0 ]; +}; + +struct fdr_ring { +spinlock_t fdr_lock; +int last_entry; +struct fdr_entry *entry[1000 ]; +}; +struct scsi_device {struct Scsi_Host *host;struct request_queue *request_queue;
include/scsi/scsi_device.h struct scsi_device { · line 240
Quoted 7 lines
include/scsi/scsi_device.h +1
-0@@ -222,6 +234,7 @@ struct scsi_device {struct scsi_dh_data *scsi_dh_data;enum scsi_device_state sdev_state;struct ratelimit_state sdev_ratelimit; +struct fdr_ring fdr;unsigned long sdev_data[0 ]; } __attribute__((aligned(sizeof(unsigned long))));
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 13 lines · Nicholas A. Bellinger
Quoted 11 lines · Jörn Engel
Here is a fun patch in an early state. Essentially I want to trace scsi commands, which has already been done long ago. The problem I have is that I care about all the scsi commands for one particular device - without knowing in advance which device it will be. Once I know the device in question, I want to dump the last X commands.
The existing tracing is covering all commands to all devices. So either I have to oversize my trace buffer and dump way too much, or I will miss the stuff I am interested in most of the time. Hence my per-device trace buffer (called fdr to avoid namespace collisions).
Quoted 5 lines
Sounds like a useful idea..
However, it adds another kmalloc +
spin_lock->spin_unlockin the fast path for each structscsi_cmndI/O dispatch, which is exactly what the scsi-mq prototype code is trying to avoid at all costs.
Agreed. It shouldn't be too hard to replace the spin_lock with cmpxchg, maybe even rcu. And for the common case, one could reuse the old buffer, getting rid of kmalloc overhead as well.
For the time being I will likely skip the work and see whether the existing patch actually catches something useful. First prove the quick hack to be useful, then optimize the hell out of it.
Jörn
--
No art, however minor, demands less than total dedication if you want to excel in it.
-- Leon Battista Alberti
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 10 lines · Jörn Engel
Here is a fun patch in an early state. Essentially I want to trace scsi commands, which has already been done long ago. The problem I have is that I care about all the scsi commands for one particular device - without knowing in advance which device it will be. Once I know the device in question, I want to dump the last X commands.
The existing tracing is covering all commands to all devices. So either I have to oversize my trace buffer and dump way too much, or I will miss the stuff I am interested in most of the time. Hence my per-device trace buffer (called fdr to avoid namespace collisions).
Isn't this facility something that overlaps with what Wireshark can already do today ? Wireshark can already capture SCSI traces for several transport types (iSCSI, USB, ...). For other transports, e.g. FC, I'd prefer to see Wireshark being extended instead of adding more SCSI tracing mechanisms in the SCSI core.
Best regards,
Bart.
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 6 lines · Bart Van Assche
Isn't this facility something that overlaps with what Wireshark can already do today ? Wireshark can already capture SCSI traces for several transport types (iSCSI, USB, ...). For other transports, e.g. FC, I'd prefer to see Wireshark being extended instead of adding more SCSI tracing mechanisms in the SCSI core.
Wireshark would be great if there was a reproducable testcase and a developer could sit down for an afternoon and collect some traces. But how would you deal with rare cases that require around a year to reproduce per device and only matter when dealing with many devices?
Jörn
--
Data expands to fill the space available for storage.
-- Parkinson's Law
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 5 lines · On Tue, 27 Aug 2013 18:03:25 -0400 Jörn Engel <[email protected]> wrote:
Here is a fun patch in an early state. Essentially I want to trace scsi commands, which has already been done long ago. The problem I have is that I care about all the scsi commands for one particular device - without knowing in advance which device it will be. Once I know the device in question, I want to dump the last X commands.
Is the device passed to the trace point? If so, you can add a filter on that device. You can even create a separate buffer to just trace that device.
cd /sys/kernel/debug/tracing
mkdir instances/myscsi
echo 'channel==0 && id==0 && lun==0' > \
instances/myscsi/events/scsi/scsi_dispatch_cmd_done/filter
echo 1 > instance/myscsi/events/scsi/scsi_dispatch_cmd_done/enable cat instances/myscsi/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 10/10 #P:4
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
<idle>-0 [000] d.h3 8173.344559: scsi_dispatch_cmd_done: host_no=0 channel=0 id=0 lun=0 data_sgl=1 prot_sgl=0 prot_op=SCSI_PROT_NORMAL cmnd=(READ_10 lba=68117912 txlen=8 protect=0 raw=28 00 04 0f 65 98 00 00 08 00) result=(driver=DRIVER_OK host=DID_OK message=COMMAND_COMPLETE status=SAM_STAT_GOOD)
<idle>-0 [001] d.h3 8173.347743: scsi_dispatch_cmd_done: host_no=0 channel=0 id=0 lun=0 data_sgl=1 prot_sgl=0 prot_op=SCSI_PROT_NORMAL cmnd=(READ_10 lba=68351144 txlen=8 protect=0 raw=28 00 04 12 f4 a8 00 00 08 00) result=(driver=DRIVER_OK host=DID_OK message=COMMAND_COMPLETE status=SAM_STAT_GOOD)
<idle>-0 [000] d.h3 8174.810108: scsi_dispatch_cmd_done: host_no=0 channel=0 id=0 lun=0 data_sgl=1 prot_sgl=0 prot_op=SCSI_PROT_NORMAL cmnd=(READ_10 lba=61301272 txlen=8 protect=0 raw=28 00 03 a7 62 18 00 00 08 00) result=(driver=DRIVER_OK host=DID_OK message=COMMAND_COMPLETE status=SAM_STAT_GOOD)
<idle>-0 [001] d.h3 8174.822038: scsi_dispatch_cmd_done: host_no=0 channel=0 id=0 lun=0 data_sgl=1 prot_sgl=0 prot_op=SCSI_PROT_NORMAL cmnd=(READ_10 lba=48718352 txlen=8 protect=0 raw=28 00 02 e7 62 10 00 00 08 00) result=(driver=DRIVER_OK host=DID_OK message=COMMAND_COMPLETE status=SAM_STAT_GOOD)
<idle>-0 [002] d.h3 8174.827439: scsi_dispatch_cmd_done: host_no=0 channel=0 id=0 lun=0 data_sgl=1 prot_sgl=0 prot_op=SCSI_PROT_NORMAL cmnd=(READ_10 lba=56582672 txlen=8 protect=0 raw=28 00 03 5f 62 10 00 00 08 00) result=(driver=DRIVER_OK host=DID_OK message=COMMAND_COMPLETE status=SAM_STAT_GOOD)
<idle>-0 [003] d.h3 8174.835280: scsi_dispatch_cmd_done:
host_no=0 channel=0 id=0 lun=0 data_sgl=1 prot_sgl=0
prot_op=SCSI_PROT_NORMAL cmnd=(READ_10 lba=82010640 txlIs that something you are talking about?
-- Steve
Quoted 6 lines
The existing tracing is covering all commands to all devices. So either I have to oversize my trace buffer and dump way too much, or I will miss the stuff I am interested in most of the time. Hence my per-device trace buffer (called fdr to avoid namespace collisions).
Quoted 6 lines
Steven, is there some magic 2-line patch that would also give me what I want without having to reinvent all your infrastructure and doing such a bad job?
Jörn
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 9 lines · Steven Rostedt
Quoted 5 lines · On Tue, 27 Aug 2013 18:03:25 -0400 Jörn Engel <[email protected]> wrote:
Here is a fun patch in an early state. Essentially I want to trace scsi commands, which has already been done long ago. The problem I have is that I care about all the scsi commands for one particular device - without knowing in advance which device it will be. Once I know the device in question, I want to dump the last X commands.
Quoted 3 lines
Is the device passed to the trace point? If so, you can add a filter on that device. You can even create a separate buffer to just trace that device.
"without knowing in advance which device it will be"
I have to trace all devices, because I don't know the interesting one ahead of time. And after the fact, I only care about one device. So having per-device trace buffers seems to be The Right Approach(tm).
And having multiple trace buffers is where I cannot easily make my problem fit your infrastructure.
Jörn
--
If you're willing to restrict the flexibility of your approach, you can almost always do something better.
-- John Carmack
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 14 lines · On Tue, 27 Aug 2013 18:41:47 -0400 Jörn Engel <[email protected]> wrote:
Quoted 9 lines · Steven Rostedt
Quoted 5 lines · On Tue, 27 Aug 2013 18:03:25 -0400 Jörn Engel <[email protected]> wrote:
Here is a fun patch in an early state. Essentially I want to trace scsi commands, which has already been done long ago. The problem I have is that I care about all the scsi commands for one particular device - without knowing in advance which device it will be. Once I know the device in question, I want to dump the last X commands.
Quoted 3 lines
Is the device passed to the trace point? If so, you can add a filter on that device. You can even create a separate buffer to just trace that device.
Quoted 8 lines
"without knowing in advance which device it will be"
I have to trace all devices, because I don't know the interesting one ahead of time. And after the fact, I only care about one device. So having per-device trace buffers seems to be The Right Approach(tm).
And having multiple trace buffers is where I cannot easily make my problem fit your infrastructure.
Are you sure about that? Note, I'm not sure you want this as something in production systems to always have on boot, for that, we can modify things a little to help you there. But other than that you can do:
for each device d
mkdir /sys/kernel/debug/tracing/instances/scsi-$d cd /sys/kernel/debug/tracing/instances/scsi-$d echo $filter > events/scsi/*/filter
echo 1 > events/scsi/*/enable
done
The above is a script like pseudo code, just to convey the idea, not something to put in verbatim.
Basically, on boot, you can make a separate buffer for each device, and have a different filter for those events to save to each specific buffer.
Now, this may still not be what you want, but at a minimum, I would not add another hook like you did with the fdr_scsi_cmd(cmd). You know you can hook to the tracepoint directly.
register_trace_scsi_dispatch_cmd_start(fdr_scsi_cmd, NULL);
static void fdr_scsi_cmd(void *data, struct scsi_cmnd *cmd)
{
[...]
}Once you call that register function, the tracepoint will call the function you registered when the tracepoint is hit.
You can also create your own ring buffer with ring_buffer_alloc(), and get a lockless ring buffer as well. All of ftrace is built with lego blocks, so the infrastructure is there even if the general utility isn't exactly what you are looking for.
-- Steve
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 5 lines · Steven Rostedt
Quoted 3 lines · On Tue, 27 Aug 2013 18:41:47 -0400 Jörn Engel <[email protected]> wrote:
"without knowing in advance which device it will be"
Quoted 8 lines
Quoted 6 lines
I have to trace all devices, because I don't know the interesting one ahead of time. And after the fact, I only care about one device. So having per-device trace buffers seems to be The Right Approach(tm).
And having multiple trace buffers is where I cannot easily make my problem fit your infrastructure.
Are you sure about that?
When it comes to my mental shortcomings, I am quite sure about their existence. ;)
Quoted 11 lines
Note, I'm not sure you want this as something
in production systems to always have on boot, for that, we can modify things a little to help you there. But other than that you can do:for each device d
mkdir/sys/kernel/debug/tracing/instances/scsi-$dcd/sys/kernel/debug/tracing/instances/scsi-$decho $filter > events/scsi/*/filter
echo 1 > events/scsi/*/enable
done
Quoted 2 lines
The above is a script like pseudo code, just to convey the idea, not something to put in verbatim.
That does look fairly neat and doable. I am not sure about the performance overhead, though. Would this translate into one big switch or, for large systems, hundreds of "if (some_filter)" lines. The latter would likely be noticeable overhead.
Quoted 7 lines
Now, this may still not be what you want, but at a minimum, I would not add another hook like you did with the
fdr_scsi_cmd(cmd). You know you can hook to the tracepoint directly.register_trace_scsi_dispatch_cmd_start(fdr_scsi_cmd, NULL);
Quoted 7 lines
static void
fdr_scsi_cmd(void *data, struct scsi_cmnd *cmd){ [...] }Once you call that register function, the tracepoint will call the function you registered when the tracepoint is hit.
Hmm. I will ponder that idea for a bit. If we can come up with something merge-worthy, that would be great. If not, I will simply carry my existing patch and not make anyone else pay the cost for it.
Jörn
--
The wise man seeks everything in himself; the ignorant man tries to get everything from somebody else.
-- unknown
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html