Skip to content

Commit f877f1d

Browse files
committed
firewire: core: use mutex to coordinate concurrent calls to flush completions
In current implementation, test_and_set_bit_lock() is used to mediate concurrent calls of ohci_flush_iso_completions(). However, the ad-hoc usage of atomic operations is not preferable. This commit uses mutex_trylock() as the similar operations. The core function is responsible for the mediation, instead of 1394 OHCI driver. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Sakamoto <[email protected]>
1 parent e97fb38 commit f877f1d

File tree

3 files changed

+24
-25
lines changed

3 files changed

+24
-25
lines changed

drivers/firewire/core-iso.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
157157
ctx->callback.sc = callback;
158158
ctx->callback_data = callback_data;
159159
INIT_WORK(&ctx->work, flush_completions_work);
160+
mutex_init(&ctx->flushing_completions_mutex);
160161

161162
trace_isoc_outbound_allocate(ctx, channel, speed);
162163
trace_isoc_inbound_single_allocate(ctx, channel, header_size);
@@ -173,6 +174,8 @@ void fw_iso_context_destroy(struct fw_iso_context *ctx)
173174
trace_isoc_inbound_multiple_destroy(ctx);
174175

175176
ctx->card->driver->free_iso_context(ctx);
177+
178+
mutex_destroy(&ctx->flushing_completions_mutex);
176179
}
177180
EXPORT_SYMBOL(fw_iso_context_destroy);
178181

@@ -226,15 +229,19 @@ EXPORT_SYMBOL(fw_iso_context_queue_flush);
226229
* to process the context asynchronously, fw_iso_context_schedule_flush_completions() is available
227230
* instead.
228231
*
229-
* Context: Process context.
232+
* Context: Process context due to mutex_trylock().
230233
*/
231234
int fw_iso_context_flush_completions(struct fw_iso_context *ctx)
232235
{
233236
trace_isoc_outbound_flush_completions(ctx);
234237
trace_isoc_inbound_single_flush_completions(ctx);
235238
trace_isoc_inbound_multiple_flush_completions(ctx);
236239

237-
return ctx->card->driver->flush_iso_completions(ctx);
240+
scoped_cond_guard(mutex_try, /* nothing to do */, &ctx->flushing_completions_mutex) {
241+
return ctx->card->driver->flush_iso_completions(ctx);
242+
}
243+
244+
return 0;
238245
}
239246
EXPORT_SYMBOL(fw_iso_context_flush_completions);
240247

drivers/firewire/ohci.c

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ struct iso_context {
166166
struct context context;
167167
void *header;
168168
size_t header_length;
169-
unsigned long flushing_completions;
170169
u32 mc_buffer_bus;
171170
u16 mc_completed;
172171
u16 last_timestamp;
@@ -3579,31 +3578,23 @@ static void ohci_flush_queue_iso(struct fw_iso_context *base)
35793578
static int ohci_flush_iso_completions(struct fw_iso_context *base)
35803579
{
35813580
struct iso_context *ctx = container_of(base, struct iso_context, base);
3582-
int ret = 0;
35833581

3584-
if (!test_and_set_bit_lock(0, &ctx->flushing_completions)) {
3585-
// Note that tasklet softIRQ is not used to process isochronous context anymore.
3586-
context_tasklet((unsigned long)&ctx->context);
3582+
// Note that tasklet softIRQ is not used to process isochronous context anymore.
3583+
context_tasklet((unsigned long)&ctx->context);
35873584

3588-
switch (base->type) {
3589-
case FW_ISO_CONTEXT_TRANSMIT:
3590-
case FW_ISO_CONTEXT_RECEIVE:
3591-
if (ctx->header_length != 0)
3592-
flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_FLUSH);
3593-
break;
3594-
case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL:
3595-
if (ctx->mc_completed != 0)
3596-
flush_ir_buffer_fill(ctx);
3597-
break;
3598-
default:
3599-
ret = -ENOSYS;
3600-
}
3601-
3602-
clear_bit_unlock(0, &ctx->flushing_completions);
3603-
smp_mb__after_atomic();
3585+
switch (base->type) {
3586+
case FW_ISO_CONTEXT_TRANSMIT:
3587+
case FW_ISO_CONTEXT_RECEIVE:
3588+
if (ctx->header_length != 0)
3589+
flush_iso_completions(ctx, FW_ISO_CONTEXT_COMPLETIONS_CAUSE_FLUSH);
3590+
return 0;
3591+
case FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL:
3592+
if (ctx->mc_completed != 0)
3593+
flush_ir_buffer_fill(ctx);
3594+
return 0;
3595+
default:
3596+
return -ENOSYS;
36043597
}
3605-
3606-
return ret;
36073598
}
36083599

36093600
static const struct fw_card_driver ohci_driver = {

include/linux/firewire.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ union fw_iso_callback {
512512
struct fw_iso_context {
513513
struct fw_card *card;
514514
struct work_struct work;
515+
struct mutex flushing_completions_mutex;
515516
int type;
516517
int channel;
517518
int speed;

0 commit comments

Comments
 (0)