
On Aug 16 Takashi Iwai wrote:
On Sat, 15 Aug 2015 12:15:54 +0200, Stefan Richter wrote:
On Aug 13 Takashi Sakamoto wrote:
On Aug 13 2015 15:31, Takashi Iwai wrote:
On Thu, 13 Aug 2015 02:19:59 +0200, Takashi Sakamoto wrote:
- generation = port->parent->generation;
- smp_rmb(); /* node_id vs. generation */
Why this barrier is needed?
Oops. I forgot to refine it after copying from the other place. Exactly, it's not need here.
- fw_send_request(port->parent->card, &port->transaction, type,
port->parent->node_id, generation,
port->parent->max_speed, port->addr,
port->buf, port->len, async_midi_port_callback,
port);
+}
The barrier is normally needed because:
[there is a dependency between node_ID and generation and]
- The node_ID:generation tuple is accessed in the Linux firewire stack in a lockless manner:
[...]
Thanks, that clarifies. But wouldn't it be more helpful to have some macro than open-coding at each place?
I agree that a cooked-up accessor via <linux/firewire.h> would be good, but I have no immediate idea how that accessor should look like. Looking at the various uses of fw_send_request [http://lxr.free-electrons.com/ident?i=fw_send_request], it's clear that this API between protocol drivers and firewire-core is quite low-level and flexible by nature. In particular, the different users of the API take node_id:generation from different sources.¹
As mentioned, another way would be to fuse node_id:generation into a single atomic datum throughout all firewire drivers. I.e. instead of ensuring the proper access order everytime, just access both data simultaneously everytime. Not having tried this yet, I am not sure which way would be more readable. ------------ ¹) Those differences between fw_send_request users are typically due to bus reset handling in highlevel drivers on top of firewire-core's bus reset handling. [firewire-core::bus reset handler] - analyze bus topology - write fw_device instances' node_id:generation tuple - notify protocol drivers [protocol_driver::bus reset handler] - perform protocol-specific reconnection procedure - write protocol_driver_device instance's node_id:generation tuple [protocol_driver::outbound IO] - read protocol_driver_device instance's node_id:generation tuple - send request Here the request is not only guaranteed to hit the topologically correct target, it is also guaranteed to hit only while in a protocol-specific connected state. (Requests with a stale generation won't go out to the bus.)