mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
![Takashi Sakamoto](/assets/img/avatar_default.png)
In current implementation, packet processing is done in both of software
IRQ contexts of IR/IT contexts and process contexts.
This is usual interrupt handling of IR/IT context for 1394 OHCI.
(in hardware IRQ context)
irq_handler() (drivers/firewire/ohci.c)
->tasklet_schedule()
(in software IRQ context)
handle_it_packet() or handle_ir_packet_per_buffer() (drivers/firewire/ohci.c)
->flush_iso_completions()
->struct fw_iso_context.callback.sc()
= out_stream_callback() or in_stream_callback()
However, we have another chance for packet processing. It's done in PCM
frame handling via ALSA PCM interfaces.
(in process context)
ioctl(i.e. SNDRV_PCM_IOCTL_HWSYNC)
->snd_pcm_hwsync() (sound/core/pcm_native.c)
->snd_pcm_update_hw_ptr() (sound/core/pcm_lib.c)
->snd_pcm_update_hw_ptr0()
->struct snd_pcm_ops.pointer()
= amdtp_stream_pcm_pointer()
->fw_iso_context_flush_completions() (drivers/firewire/core-iso.c)
->struct fw_card_driver.flush_iso_completions()
= ohci_flush_iso_completions() (drivers/firewire/ohci.c)
->flush_iso_completions()
->struct fw_iso_context.callback.sc()
= out_stream_callback() or in_stream_callback()
This design is for a better granularity of PCM pointer. When ioctl(2) is
executed with some commands for ALSA PCM interface, queued packets are
handled at first. Then, the latest number of handled PCM frames is
reported. The number can represent PCM frames transferred in most near
isochronous cycle.
Current tracepoints include no information to distinguish running contexts.
When tracing the interval of software IRQ context, this is not good.
This commit adds more information for current context. Additionally, the
index of packet processed in one context is added in a case that packet
processing is executed in continuous context of the same kind,
As a result, the output includes 11 fields with additional two fields
to commit 0c95c1d619
("ALSA: firewire-lib: add tracepoints to dump a part
of isochronous packet data"):
17131.9186: out_packet: 07 7494 ffc0 ffc1 00 000700c0 9001a496 058 45 1 13
17131.9186: out_packet: 07 7495 ffc0 ffc1 00 000700c8 9001ba00 058 46 1 14
17131.9186: out_packet: 07 7496 ffc0 ffc1 00 000700d0 9001ffff 002 47 1 15
17131.9189: out_packet: 07 7497 ffc0 ffc1 00 000700d0 9001d36a 058 00 0 00
17131.9189: out_packet: 07 7498 ffc0 ffc1 00 000700d8 9001e8d4 058 01 0 01
17131.9189: out_packet: 07 7499 ffc0 ffc1 00 000700e0 9001023e 058 02 0 00
17131.9206: in_packet: 07 7447 ffc1 ffc0 01 3f070072 9001783d 058 32 1 00
17131.9206: in_packet: 07 7448 ffc1 ffc0 01 3f070072 90ffffff 002 33 1 01
17131.9206: in_packet: 07 7449 ffc1 ffc0 01 3f07007a 900191a8 058 34 1 02
(Here, some common fields are omitted so that a line is within 80
characters.)
The legend is:
- The second of cycle scheduled for the packet
- The count of cycle scheduled for the packet
- The ID of node as source (hex)
- The ID of node as destination (hex)
- The value of isochronous channel
- The first quadlet of CIP header (hex)
- The second quadlet of CIP header (hex)
- The number of included quadlets
- The index of packet in a buffer maintained by this module
- 0 in process context, 1 in IRQ context
- The index of packet processed in the context
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
110 lines
3.2 KiB
C
110 lines
3.2 KiB
C
/*
|
|
* amdtp-stream-trace.h - tracepoint definitions to dump a part of packet data
|
|
*
|
|
* Copyright (c) 2016 Takashi Sakamoto
|
|
* Licensed under the terms of the GNU General Public License, version 2.
|
|
*/
|
|
|
|
#undef TRACE_SYSTEM
|
|
#define TRACE_SYSTEM snd_firewire_lib
|
|
|
|
#if !defined(_AMDTP_STREAM_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
|
#define _AMDTP_STREAM_TRACE_H
|
|
|
|
#include <linux/tracepoint.h>
|
|
|
|
TRACE_EVENT(in_packet,
|
|
TP_PROTO(const struct amdtp_stream *s, u32 cycles, u32 cip_header[2], unsigned int payload_quadlets, unsigned int index),
|
|
TP_ARGS(s, cycles, cip_header, payload_quadlets, index),
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, second)
|
|
__field(unsigned int, cycle)
|
|
__field(int, channel)
|
|
__field(int, src)
|
|
__field(int, dest)
|
|
__field(u32, cip_header0)
|
|
__field(u32, cip_header1)
|
|
__field(unsigned int, payload_quadlets)
|
|
__field(unsigned int, packet_index)
|
|
__field(bool, irq)
|
|
__field(unsigned int, index)
|
|
),
|
|
TP_fast_assign(
|
|
__entry->second = cycles / CYCLES_PER_SECOND;
|
|
__entry->cycle = cycles % CYCLES_PER_SECOND;
|
|
__entry->channel = s->context->channel;
|
|
__entry->src = fw_parent_device(s->unit)->node_id;
|
|
__entry->dest = fw_parent_device(s->unit)->card->node_id;
|
|
__entry->cip_header0 = cip_header[0];
|
|
__entry->cip_header1 = cip_header[1];
|
|
__entry->payload_quadlets = payload_quadlets;
|
|
__entry->packet_index = s->packet_index;
|
|
__entry->irq = in_interrupt();
|
|
__entry->index = index;
|
|
),
|
|
TP_printk(
|
|
"%02u %04u %04x %04x %02d %08x %08x %03u %02u %01u %02u",
|
|
__entry->second,
|
|
__entry->cycle,
|
|
__entry->src,
|
|
__entry->dest,
|
|
__entry->channel,
|
|
__entry->cip_header0,
|
|
__entry->cip_header1,
|
|
__entry->payload_quadlets,
|
|
__entry->packet_index,
|
|
__entry->irq,
|
|
__entry->index)
|
|
);
|
|
|
|
TRACE_EVENT(out_packet,
|
|
TP_PROTO(const struct amdtp_stream *s, u32 cycles, __be32 *cip_header, unsigned int payload_length, unsigned int index),
|
|
TP_ARGS(s, cycles, cip_header, payload_length, index),
|
|
TP_STRUCT__entry(
|
|
__field(unsigned int, second)
|
|
__field(unsigned int, cycle)
|
|
__field(int, channel)
|
|
__field(int, src)
|
|
__field(int, dest)
|
|
__field(u32, cip_header0)
|
|
__field(u32, cip_header1)
|
|
__field(unsigned int, payload_quadlets)
|
|
__field(unsigned int, packet_index)
|
|
__field(bool, irq)
|
|
__field(unsigned int, index)
|
|
),
|
|
TP_fast_assign(
|
|
__entry->second = cycles / CYCLES_PER_SECOND;
|
|
__entry->cycle = cycles % CYCLES_PER_SECOND;
|
|
__entry->channel = s->context->channel;
|
|
__entry->src = fw_parent_device(s->unit)->card->node_id;
|
|
__entry->dest = fw_parent_device(s->unit)->node_id;
|
|
__entry->cip_header0 = be32_to_cpu(cip_header[0]);
|
|
__entry->cip_header1 = be32_to_cpu(cip_header[1]);
|
|
__entry->payload_quadlets = payload_length / 4;
|
|
__entry->packet_index = s->packet_index;
|
|
__entry->irq = in_interrupt();
|
|
__entry->index = index;
|
|
),
|
|
TP_printk(
|
|
"%02u %04u %04x %04x %02d %08x %08x %03u %02u %01u %02u",
|
|
__entry->second,
|
|
__entry->cycle,
|
|
__entry->src,
|
|
__entry->dest,
|
|
__entry->channel,
|
|
__entry->cip_header0,
|
|
__entry->cip_header1,
|
|
__entry->payload_quadlets,
|
|
__entry->packet_index,
|
|
__entry->irq,
|
|
__entry->index)
|
|
);
|
|
|
|
#endif
|
|
|
|
#undef TRACE_INCLUDE_PATH
|
|
#define TRACE_INCLUDE_PATH .
|
|
#undef TRACE_INCLUDE_FILE
|
|
#define TRACE_INCLUDE_FILE amdtp-stream-trace
|
|
#include <trace/define_trace.h>
|