Re: [PATCH] usb: dwc3: debugfs: add snapshot to dump requests trbs events
Hi, On Tue, Apr 29, 2014 at 11:10:42AM -0500, Felipe Balbi wrote: Hi, On Tue, Apr 29, 2014 at 05:21:42PM -0400, Zhuang Jin Can wrote: On Mon, Apr 28, 2014 at 10:55:36AM -0500, Felipe Balbi wrote: On Mon, Apr 28, 2014 at 04:49:23PM -0400, Zhuang Jin Can wrote: Adds a debugfs file snapshot to dump dwc3 requests, trbs and events. you need to explain what are you trying to provide to our users here. What problem are you trying to solve ? The interface enables users to easily peek into requests, trbs and events to know the current transfer state of each request. If an transfer is stuck, user can use the interface to check why it's stuck (e.g. Is it because a gadget doesn't queued the request? Or it's queued but it's not primed to the controller? Or It's primed to the controller but the TRBs and events indicate the transfer never completes?). User can immediately narrow down the issue without enabling verbose log or reproduce the issue again. It's helpful when we need to deal with some hard-to-reproduce bugs or timing sensitive bugs can't be reproduced with verbose log enabled. this should be part of the commit log in some shape or form. Yes. As ep0 requests are more complex than others. It's not included in this patch. For ep0, you could at least print the endpoint phase we are currently in and if we have requests in flight or not. Agree. Will add it in [PATCH v2]. tks + seq_puts(s, busy_slot--|\n); + seq_puts(s,\\\n); + } + if (i == (dep-free_slot DWC3_TRB_MASK)) { + seq_puts(s, free_slot--|\n); + seq_puts(s,\\\n); + } + seq_printf(s, trb[%02d](dma@0x%pad): %08x(bpl), %08x(bph), %08x(size), %08x(ctrl)\n, I'm not sure you need to print out the TRB address. bpl, bph, size and ctrl are desired though. printing out the TRB DMA address helps user to locate the start TRB of a request. I admit that we can achive the same purose using the start_slot of the request. I'll remove it in [PATCH v2]. thanks + i, dep-trb_pool_dma + i * sizeof(*trb), + trb-bpl, trb-bph, trb-size, trb-ctrl); this will be pretty difficult to parse by a human. I would rather see you creating one directory per TRB (and also one directory per endpoint) which holds the details for that entity, so that it looks like: dwc3 |-- current_state (or perhaps a better name, but snapshot isn't very good either) Actually, it's hard to find a perfect name. current_state or snapshot doesn't make too much difference to me. If current_state makes more sense to you, I can change to use this name. Or let me know if you have a better suggestion. the name is important as we will have to deal with it for the next 50 years. We also need to think about someone starting out on dwc3 5 years from now or a QA engineer in whatever OEM trying to provide details of the failure for the development team. It needs to be well thought out. I don't have a better idea but snapshot gives me the idea that we will end up with a copy of everything which we can revisit at any time and that's not true. If we read this file twice there's no guarantee it'll contain the same information. Let's discuss the name later after I explain more about the motivation. [Motivation] The patch is inspired from echi-dbg.c debugfs. It contains four files async, bandwidth, periodic and registers. The registers functions as what regdump does in dwc3. And the patch implements a snapshot to do the similar things done by async and periodic. Because a way to inspect the content of data structures (i.e. TRBs, Events) interacting with the controller is really important for debugging, especially for HW issues. It just simply provides you a interface to check what's currently in TRBs and event buffers (and nothing more, no more guarantees). In EHCI, async and periodic also can't guarantee you the reliable data, as you can't prevent the controller from writing the interacting data structures (unless you stop it). It's developer's decision to how to analyze the data. They're not perfect, but simple and helpful. As far as I see, it's useful for below senarios: 1. Bugs can't be reproduced with VERBOSE_DEBUG, as printk introduces timing effect. Some HW bugs are timing sensitive, even a single printk will prevent you from reproducing the issue. With snapshot, we can check the TRBs, events, requests to see the final status to get more clues to triage an issue. 2. Some bugs are hard to reproduce, and can be seen once or twice after many devices running for a long time. (e.g. MTBF runing with ADB). And they most often uses the builds with debugfs available, ask them to turn on VERBOSE_DEBUG and run the
Re: [PATCH] usb: dwc3: debugfs: add snapshot to dump requests trbs events
Hi, On Thu, May 01, 2014 at 01:06:25AM -0400, Zhuang Jin Can wrote: Hi, On Tue, Apr 29, 2014 at 11:10:42AM -0500, Felipe Balbi wrote: Hi, On Tue, Apr 29, 2014 at 05:21:42PM -0400, Zhuang Jin Can wrote: On Mon, Apr 28, 2014 at 10:55:36AM -0500, Felipe Balbi wrote: On Mon, Apr 28, 2014 at 04:49:23PM -0400, Zhuang Jin Can wrote: Adds a debugfs file snapshot to dump dwc3 requests, trbs and events. you need to explain what are you trying to provide to our users here. What problem are you trying to solve ? The interface enables users to easily peek into requests, trbs and events to know the current transfer state of each request. If an transfer is stuck, user can use the interface to check why it's stuck (e.g. Is it because a gadget doesn't queued the request? Or it's queued but it's not primed to the controller? Or It's primed to the controller but the TRBs and events indicate the transfer never completes?). User can immediately narrow down the issue without enabling verbose log or reproduce the issue again. It's helpful when we need to deal with some hard-to-reproduce bugs or timing sensitive bugs can't be reproduced with verbose log enabled. this should be part of the commit log in some shape or form. Yes. As ep0 requests are more complex than others. It's not included in this patch. For ep0, you could at least print the endpoint phase we are currently in and if we have requests in flight or not. Agree. Will add it in [PATCH v2]. tks + seq_puts(s, busy_slot--|\n); + seq_puts(s,\\\n); + } + if (i == (dep-free_slot DWC3_TRB_MASK)) { + seq_puts(s, free_slot--|\n); + seq_puts(s,\\\n); + } + seq_printf(s, trb[%02d](dma@0x%pad): %08x(bpl), %08x(bph), %08x(size), %08x(ctrl)\n, I'm not sure you need to print out the TRB address. bpl, bph, size and ctrl are desired though. printing out the TRB DMA address helps user to locate the start TRB of a request. I admit that we can achive the same purose using the start_slot of the request. I'll remove it in [PATCH v2]. thanks + i, dep-trb_pool_dma + i * sizeof(*trb), + trb-bpl, trb-bph, trb-size, trb-ctrl); this will be pretty difficult to parse by a human. I would rather see you creating one directory per TRB (and also one directory per endpoint) which holds the details for that entity, so that it looks like: dwc3 |-- current_state (or perhaps a better name, but snapshot isn't very good either) Actually, it's hard to find a perfect name. current_state or snapshot doesn't make too much difference to me. If current_state makes more sense to you, I can change to use this name. Or let me know if you have a better suggestion. the name is important as we will have to deal with it for the next 50 years. We also need to think about someone starting out on dwc3 5 years from now or a QA engineer in whatever OEM trying to provide details of the failure for the development team. It needs to be well thought out. I don't have a better idea but snapshot gives me the idea that we will end up with a copy of everything which we can revisit at any time and that's not true. If we read this file twice there's no guarantee it'll contain the same information. Let's discuss the name later after I explain more about the motivation. [Motivation] The patch is inspired from echi-dbg.c debugfs. It contains four files async, bandwidth, periodic and registers. The registers functions as what regdump does in dwc3. And the patch implements a snapshot to do the similar things done by async and periodic. Because a way to inspect the content of data structures (i.e. TRBs, Events) interacting with the controller is really important for debugging, especially for HW issues. It just simply provides you a interface to check what's currently in TRBs and event buffers (and nothing more, no more guarantees). In EHCI, async and periodic also can't guarantee you the reliable data, as you can't prevent the controller from writing the interacting data structures (unless you stop it). It's developer's decision to how to analyze the data. They're not perfect, but simple and helpful. As far as I see, it's useful for below senarios: 1. Bugs can't be reproduced with VERBOSE_DEBUG, as printk introduces timing effect. Some HW bugs are timing sensitive, even a single printk will prevent you from reproducing the issue. With snapshot, we can check the TRBs, events, requests to see the final status to get more clues to triage an issue. 2. Some bugs are hard to reproduce, and can be seen once or
Re: [PATCH] usb: dwc3: debugfs: add snapshot to dump requests trbs events
On Wed, Apr 30, 2014 at 12:14:42PM -0500, Felipe Balbi wrote: sorry but your patch is not good for acceptance in mainline. Thanks your time. Jincan -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: dwc3: debugfs: add snapshot to dump requests trbs events
On Mon, Apr 28, 2014 at 10:55:36AM -0500, Felipe Balbi wrote: On Mon, Apr 28, 2014 at 04:49:23PM -0400, Zhuang Jin Can wrote: Adds a debugfs file snapshot to dump dwc3 requests, trbs and events. you need to explain what are you trying to provide to our users here. What problem are you trying to solve ? The interface enables users to easily peek into requests, trbs and events to know the current transfer state of each request. If an transfer is stuck, user can use the interface to check why it's stuck (e.g. Is it because a gadget doesn't queued the request? Or it's queued but it's not primed to the controller? Or It's primed to the controller but the TRBs and events indicate the transfer never completes?). User can immediately narrow down the issue without enabling verbose log or reproduce the issue again. It's helpful when we need to deal with some hard-to-reproduce bugs or timing sensitive bugs can't be reproduced with verbose log enabled. As ep0 requests are more complex than others. It's not included in this patch. For ep0, you could at least print the endpoint phase we are currently in and if we have requests in flight or not. Agree. Will add it in [PATCH v2]. Signed-off-by: Zhuang Jin Can jin.can.zhu...@intel.com --- drivers/usb/dwc3/core.h|4 + drivers/usb/dwc3/debugfs.c | 192 drivers/usb/dwc3/gadget.h | 41 ++ 3 files changed, 237 insertions(+) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 57332e3..9d04ddd 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -849,6 +849,10 @@ struct dwc3_event_devt { u32 type:4; u32 reserved15_12:4; u32 event_info:9; + +#define DEVT_EVTINFO_SUPERSPEED(1 4) +#define DEVT_EVTINFO_HIRD(n) (((n) (0xf 5)) 5) + u32 reserved31_25:7; } __packed; diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 9ac37fe..078d147 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -618,6 +618,191 @@ static const struct file_operations dwc3_link_state_fops = { .release= single_release, }; +static void dwc3_dump_requests(struct seq_file *s, struct list_head *head, + const char *list_name) +{ + struct dwc3_request *req; + + if (list_empty(head)) { + seq_printf(s, list %s is empty\n, list_name); + return; + } + + seq_printf(s, list %s:\n, list_name); + list_for_each_entry(req, head, list) { + struct usb_request *request = req-request; + + seq_printf(s, usb_request@0x%p: buf@0x%p(dma@0x%pad), len=%d\n, + request, request-buf, request-dma, + request-length); + + if (req-queued) + seq_printf(s, \tstatus=%d: actual=%d; start_slot=%u: trb@0x%p(dma@0x%pad)\n, + request-status, request-actual, + req-start_slot, req-trb, + req-trb_dma); + } +} + +static void dwc3_dump_trbs(struct seq_file *s, struct dwc3_ep *dep) +{ + struct dwc3_trb *trb; + int i; + + seq_printf(s, busy_slot = %u, free_slot = %u\n, + dep-busy_slot DWC3_TRB_MASK, + dep-free_slot DWC3_TRB_MASK); + + for (i = 0; i DWC3_TRB_NUM; i++) { + trb = dep-trb_pool[i]; + if (i == (dep-busy_slot DWC3_TRB_MASK)) { I really dislike these Yoda Conditionals. Fix this up. Agree. Will fix it in [PATCH v2]. + seq_puts(s, busy_slot--|\n); + seq_puts(s,\\\n); + } + if (i == (dep-free_slot DWC3_TRB_MASK)) { + seq_puts(s, free_slot--|\n); + seq_puts(s,\\\n); + } + seq_printf(s, trb[%02d](dma@0x%pad): %08x(bpl), %08x(bph), %08x(size), %08x(ctrl)\n, I'm not sure you need to print out the TRB address. bpl, bph, size and ctrl are desired though. printing out the TRB DMA address helps user to locate the start TRB of a request. I admit that we can achive the same purose using the start_slot of the request. I'll remove it in [PATCH v2]. + i, dep-trb_pool_dma + i * sizeof(*trb), + trb-bpl, trb-bph, trb-size, trb-ctrl); this will be pretty difficult to parse by a human. I would rather see you creating one directory per TRB (and also one directory per endpoint) which holds the details for that entity, so that it looks like: dwc3 |-- current_state (or perhaps a better name, but snapshot isn't very good either) Actually, it's hard to find a perfect name. current_state or snapshot doesn't make too much difference to me. If current_state makes more
Re: [PATCH] usb: dwc3: debugfs: add snapshot to dump requests trbs events
Hi, On Tue, Apr 29, 2014 at 05:21:42PM -0400, Zhuang Jin Can wrote: On Mon, Apr 28, 2014 at 10:55:36AM -0500, Felipe Balbi wrote: On Mon, Apr 28, 2014 at 04:49:23PM -0400, Zhuang Jin Can wrote: Adds a debugfs file snapshot to dump dwc3 requests, trbs and events. you need to explain what are you trying to provide to our users here. What problem are you trying to solve ? The interface enables users to easily peek into requests, trbs and events to know the current transfer state of each request. If an transfer is stuck, user can use the interface to check why it's stuck (e.g. Is it because a gadget doesn't queued the request? Or it's queued but it's not primed to the controller? Or It's primed to the controller but the TRBs and events indicate the transfer never completes?). User can immediately narrow down the issue without enabling verbose log or reproduce the issue again. It's helpful when we need to deal with some hard-to-reproduce bugs or timing sensitive bugs can't be reproduced with verbose log enabled. this should be part of the commit log in some shape or form. As ep0 requests are more complex than others. It's not included in this patch. For ep0, you could at least print the endpoint phase we are currently in and if we have requests in flight or not. Agree. Will add it in [PATCH v2]. tks + seq_puts(s, busy_slot--|\n); + seq_puts(s,\\\n); + } + if (i == (dep-free_slot DWC3_TRB_MASK)) { + seq_puts(s, free_slot--|\n); + seq_puts(s,\\\n); + } + seq_printf(s, trb[%02d](dma@0x%pad): %08x(bpl), %08x(bph), %08x(size), %08x(ctrl)\n, I'm not sure you need to print out the TRB address. bpl, bph, size and ctrl are desired though. printing out the TRB DMA address helps user to locate the start TRB of a request. I admit that we can achive the same purose using the start_slot of the request. I'll remove it in [PATCH v2]. thanks + i, dep-trb_pool_dma + i * sizeof(*trb), + trb-bpl, trb-bph, trb-size, trb-ctrl); this will be pretty difficult to parse by a human. I would rather see you creating one directory per TRB (and also one directory per endpoint) which holds the details for that entity, so that it looks like: dwc3 |-- current_state (or perhaps a better name, but snapshot isn't very good either) Actually, it's hard to find a perfect name. current_state or snapshot doesn't make too much difference to me. If current_state makes more sense to you, I can change to use this name. Or let me know if you have a better suggestion. the name is important as we will have to deal with it for the next 50 years. We also need to think about someone starting out on dwc3 5 years from now or a QA engineer in whatever OEM trying to provide details of the failure for the development team. It needs to be well thought out. I don't have a better idea but snapshot gives me the idea that we will end up with a copy of everything which we can revisit at any time and that's not true. If we read this file twice there's no guarantee it'll contain the same information. |-- ep2 | |-- direction | |-- maxpacket | |-- number | |-- state | |-- stream_capable | |-- type | |-- trbs | | |-- trb0 | | | |-- bph | | | |-- bpl | | | |-- ctrl | | | |-- size | | |-- trb1 | | | |-- bph | | | |-- bpl | | | |-- ctrl | | | |-- size | | |-- trb2 | | | |-- bph | | | |-- bpl | | | |-- ctrl | | | |-- size | | |-- trb3 | | | |-- bph | | | |-- bpl | | | |-- ctrl | | | |-- size . . . . . . . . . | |-- request0 | | |-- direction | | |-- mapped | | |-- queued | | |-- trb0(symlink to actual trb directory) | | |-- ep2 (symlink to actual ep2 directory) | | |-- usbrequest | | |-- actual | | |-- length | | |-- no_interrupt | | |-- num_mapped_sgs | | |-- num_sgs | | |-- short_not_ok | | |-- status | | |-- stream_id | | |-- zero | |-- request1 | | |-- direction | | |-- mapped | | |-- queued | | |-- trb1(symlink to actual trb directory) | | |-- ep2 (symlink to actual ep2 directory) | | |-- usbrequest | | |-- actual | | |-- length | | |-- no_interrupt | | |-- num_mapped_sgs | | |-- num_sgs | | |-- short_not_ok
Re: [PATCH] usb: dwc3: debugfs: add snapshot to dump requests trbs events
On Mon, Apr 28, 2014 at 04:49:23PM -0400, Zhuang Jin Can wrote: Adds a debugfs file snapshot to dump dwc3 requests, trbs and events. you need to explain what are you trying to provide to our users here. What problem are you trying to solve ? As ep0 requests are more complex than others. It's not included in this patch. For ep0, you could at least print the endpoint phase we are currently in and if we have requests in flight or not. Signed-off-by: Zhuang Jin Can jin.can.zhu...@intel.com --- drivers/usb/dwc3/core.h|4 + drivers/usb/dwc3/debugfs.c | 192 drivers/usb/dwc3/gadget.h | 41 ++ 3 files changed, 237 insertions(+) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 57332e3..9d04ddd 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -849,6 +849,10 @@ struct dwc3_event_devt { u32 type:4; u32 reserved15_12:4; u32 event_info:9; + +#define DEVT_EVTINFO_SUPERSPEED (1 4) +#define DEVT_EVTINFO_HIRD(n) (((n) (0xf 5)) 5) + u32 reserved31_25:7; } __packed; diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 9ac37fe..078d147 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -618,6 +618,191 @@ static const struct file_operations dwc3_link_state_fops = { .release= single_release, }; +static void dwc3_dump_requests(struct seq_file *s, struct list_head *head, + const char *list_name) +{ + struct dwc3_request *req; + + if (list_empty(head)) { + seq_printf(s, list %s is empty\n, list_name); + return; + } + + seq_printf(s, list %s:\n, list_name); + list_for_each_entry(req, head, list) { + struct usb_request *request = req-request; + + seq_printf(s, usb_request@0x%p: buf@0x%p(dma@0x%pad), len=%d\n, + request, request-buf, request-dma, + request-length); + + if (req-queued) + seq_printf(s, \tstatus=%d: actual=%d; start_slot=%u: trb@0x%p(dma@0x%pad)\n, + request-status, request-actual, + req-start_slot, req-trb, + req-trb_dma); + } +} + +static void dwc3_dump_trbs(struct seq_file *s, struct dwc3_ep *dep) +{ + struct dwc3_trb *trb; + int i; + + seq_printf(s, busy_slot = %u, free_slot = %u\n, + dep-busy_slot DWC3_TRB_MASK, + dep-free_slot DWC3_TRB_MASK); + + for (i = 0; i DWC3_TRB_NUM; i++) { + trb = dep-trb_pool[i]; + if (i == (dep-busy_slot DWC3_TRB_MASK)) { I really dislike these Yoda Conditionals. Fix this up. + seq_puts(s, busy_slot--|\n); + seq_puts(s,\\\n); + } + if (i == (dep-free_slot DWC3_TRB_MASK)) { + seq_puts(s, free_slot--|\n); + seq_puts(s,\\\n); + } + seq_printf(s, trb[%02d](dma@0x%pad): %08x(bpl), %08x(bph), %08x(size), %08x(ctrl)\n, I'm not sure you need to print out the TRB address. bpl, bph, size and ctrl are desired though. + i, dep-trb_pool_dma + i * sizeof(*trb), + trb-bpl, trb-bph, trb-size, trb-ctrl); this will be pretty difficult to parse by a human. I would rather see you creating one directory per TRB (and also one directory per endpoint) which holds the details for that entity, so that it looks like: dwc3 |-- current_state (or perhaps a better name, but snapshot isn't very good either) |-- ep2 | |-- direction | |-- maxpacket | |-- number | |-- state | |-- stream_capable | |-- type | |-- trbs | | |-- trb0 | | | |-- bph | | | |-- bpl | | | |-- ctrl | | | |-- size | | |-- trb1 | | | |-- bph | | | |-- bpl | | | |-- ctrl | | | |-- size | | |-- trb2 | | | |-- bph | | | |-- bpl | | | |-- ctrl | | | |-- size | | |-- trb3 | | | |-- bph | | | |-- bpl | | | |-- ctrl | | | |-- size . . . . . . . . . | |-- request0 | | |-- direction | | |-- mapped | | |-- queued | | |-- trb0(symlink to actual trb directory) | | |-- ep2 (symlink to actual ep2 directory) | | |-- usbrequest | | |-- actual | | |-- length | | |-- no_interrupt | | |-- num_mapped_sgs | | |-- num_sgs | | |-- short_not_ok | | |-- status | | |--
RE: [PATCH] usb: dwc3: debugfs: add snapshot to dump requests trbs events
From: linux-usb-ow...@vger.kernel.org [mailto:linux-usb-ow...@vger.kernel.org] On Behalf Of Felipe Balbi Sent: Monday, April 28, 2014 8:56 AM On Mon, Apr 28, 2014 at 04:49:23PM -0400, Zhuang Jin Can wrote: Adds a debugfs file snapshot to dump dwc3 requests, trbs and events. snip + for (i = 0; i evt-length; i += 4) { + event.raw = *(u32 *) (evt-buf + i); + if (i == evt-lpos) { + seq_puts(s, lpos---|\n); + seq_puts(s,\\\n); + } + seq_printf(s, event[%d]: %08x , i, event.raw); + + if (event.type.is_devspec) + dwc3_dump_dev_event(s, event.devt); + else + dwc3_dump_ep_event(s, event.depevt); + seq_puts(s, \n); + } how well have you tested this ? I'm not entirely sure you should be reading the event buffer at any time you want, though I might be wrong. Just FYI, it is fine to read from the event buffer memory at any time. But of course, if you happen to read from a location at the same time the core is writing to it, you may read either the old value or the new, depending on the timing. So the results might not be 100% reliable. -- Paul -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: dwc3: debugfs: add snapshot to dump requests trbs events
On Mon, Apr 28, 2014 at 07:58:43PM +, Paul Zimmerman wrote: From: linux-usb-ow...@vger.kernel.org [mailto:linux-usb-ow...@vger.kernel.org] On Behalf Of Felipe Balbi Sent: Monday, April 28, 2014 8:56 AM On Mon, Apr 28, 2014 at 04:49:23PM -0400, Zhuang Jin Can wrote: Adds a debugfs file snapshot to dump dwc3 requests, trbs and events. snip + for (i = 0; i evt-length; i += 4) { + event.raw = *(u32 *) (evt-buf + i); + if (i == evt-lpos) { + seq_puts(s, lpos---|\n); + seq_puts(s,\\\n); + } + seq_printf(s, event[%d]: %08x , i, event.raw); + + if (event.type.is_devspec) + dwc3_dump_dev_event(s, event.devt); + else + dwc3_dump_ep_event(s, event.depevt); + seq_puts(s, \n); + } how well have you tested this ? I'm not entirely sure you should be reading the event buffer at any time you want, though I might be wrong. Just FYI, it is fine to read from the event buffer memory at any time. But of course, if you happen to read from a location at the same time the core is writing to it, you may read either the old value or the new, depending on the timing. So the results might not be 100% reliable. Thanks, based on this I'll stick to my use-a-ring-buffer-to-store-last-5-events suggestion :-) -- balbi signature.asc Description: Digital signature