Skip to content

Commit e97fb38

Browse files
committed
firewire: core: move workqueue handler from 1394 OHCI driver to core function
In current implementation, the work item for isochronous context executes the same procedure of fw_iso_context_flush_completions() internally. There is a space to refactor the implementation. This commit calls fw_iso_context_flush_completions() in the work item. It obsoletes fw_iso_context_init_work(). It also obsoletes a pair of disable_work_sync() and enable_work() since the usage of test_and_set_bit_lock() mediates concurrent call already. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Sakamoto <[email protected]>
1 parent 7b71392 commit e97fb38

File tree

3 files changed

+12
-64
lines changed

3 files changed

+12
-64
lines changed

drivers/firewire/core-iso.c

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,13 @@ size_t fw_iso_buffer_lookup(struct fw_iso_buffer *buffer, dma_addr_t completed)
131131
return 0;
132132
}
133133

134+
static void flush_completions_work(struct work_struct *work)
135+
{
136+
struct fw_iso_context *ctx = container_of(work, struct fw_iso_context, work);
137+
138+
fw_iso_context_flush_completions(ctx);
139+
}
140+
134141
struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
135142
int type, int channel, int speed, size_t header_size,
136143
fw_iso_callback_t callback, void *callback_data)
@@ -149,6 +156,7 @@ struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
149156
ctx->header_size = header_size;
150157
ctx->callback.sc = callback;
151158
ctx->callback_data = callback_data;
159+
INIT_WORK(&ctx->work, flush_completions_work);
152160

153161
trace_isoc_outbound_allocate(ctx, channel, speed);
154162
trace_isoc_inbound_single_allocate(ctx, channel, header_size);
@@ -218,29 +226,15 @@ EXPORT_SYMBOL(fw_iso_context_queue_flush);
218226
* to process the context asynchronously, fw_iso_context_schedule_flush_completions() is available
219227
* instead.
220228
*
221-
* Context: Process context. May sleep due to disable_work_sync().
229+
* Context: Process context.
222230
*/
223231
int fw_iso_context_flush_completions(struct fw_iso_context *ctx)
224232
{
225-
int err;
226-
227233
trace_isoc_outbound_flush_completions(ctx);
228234
trace_isoc_inbound_single_flush_completions(ctx);
229235
trace_isoc_inbound_multiple_flush_completions(ctx);
230236

231-
might_sleep();
232-
233-
// Avoid dead lock due to programming mistake.
234-
if (WARN_ON_ONCE(current_work() == &ctx->work))
235-
return 0;
236-
237-
disable_work_sync(&ctx->work);
238-
239-
err = ctx->card->driver->flush_iso_completions(ctx);
240-
241-
enable_work(&ctx->work);
242-
243-
return err;
237+
return ctx->card->driver->flush_iso_completions(ctx);
244238
}
245239
EXPORT_SYMBOL(fw_iso_context_flush_completions);
246240

drivers/firewire/core.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,6 @@ int fw_iso_buffer_alloc(struct fw_iso_buffer *buffer, int page_count);
159159
int fw_iso_buffer_map_dma(struct fw_iso_buffer *buffer, struct fw_card *card,
160160
enum dma_data_direction direction);
161161

162-
static inline void fw_iso_context_init_work(struct fw_iso_context *ctx, work_func_t func)
163-
{
164-
INIT_WORK(&ctx->work, func);
165-
}
166-
167162

168163
/* -topology */
169164

drivers/firewire/ohci.c

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,47 +1182,6 @@ static void context_tasklet(unsigned long data)
11821182
}
11831183
}
11841184

1185-
static void ohci_isoc_context_work(struct work_struct *work)
1186-
{
1187-
struct fw_iso_context *base = container_of(work, struct fw_iso_context, work);
1188-
struct iso_context *isoc_ctx = container_of(base, struct iso_context, base);
1189-
struct context *ctx = &isoc_ctx->context;
1190-
struct descriptor *d, *last;
1191-
u32 address;
1192-
int z;
1193-
struct descriptor_buffer *desc;
1194-
1195-
desc = list_entry(ctx->buffer_list.next, struct descriptor_buffer, list);
1196-
last = ctx->last;
1197-
while (last->branch_address != 0) {
1198-
struct descriptor_buffer *old_desc = desc;
1199-
1200-
address = le32_to_cpu(last->branch_address);
1201-
z = address & 0xf;
1202-
address &= ~0xf;
1203-
ctx->current_bus = address;
1204-
1205-
// If the branch address points to a buffer outside of the current buffer, advance
1206-
// to the next buffer.
1207-
if (address < desc->buffer_bus || address >= desc->buffer_bus + desc->used)
1208-
desc = list_entry(desc->list.next, struct descriptor_buffer, list);
1209-
d = desc->buffer + (address - desc->buffer_bus) / sizeof(*d);
1210-
last = find_branch_descriptor(d, z);
1211-
1212-
if (!ctx->callback(ctx, d, last))
1213-
break;
1214-
1215-
if (old_desc != desc) {
1216-
// If we've advanced to the next buffer, move the previous buffer to the
1217-
// free list.
1218-
old_desc->used = 0;
1219-
guard(spinlock_irqsave)(&ctx->ohci->lock);
1220-
list_move_tail(&old_desc->list, &ctx->buffer_list);
1221-
}
1222-
ctx->last = last;
1223-
}
1224-
}
1225-
12261185
/*
12271186
* Allocate a new buffer and add it to the list of free buffers for this
12281187
* context. Must be called with ohci->lock held.
@@ -3169,7 +3128,6 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
31693128
ret = context_init(&ctx->context, ohci, regs, callback);
31703129
if (ret < 0)
31713130
goto out_with_header;
3172-
fw_iso_context_init_work(&ctx->base, ohci_isoc_context_work);
31733131

31743132
if (type == FW_ISO_CONTEXT_RECEIVE_MULTICHANNEL) {
31753133
set_multichannel_mask(ohci, 0);
@@ -3624,7 +3582,8 @@ static int ohci_flush_iso_completions(struct fw_iso_context *base)
36243582
int ret = 0;
36253583

36263584
if (!test_and_set_bit_lock(0, &ctx->flushing_completions)) {
3627-
ohci_isoc_context_work(&base->work);
3585+
// Note that tasklet softIRQ is not used to process isochronous context anymore.
3586+
context_tasklet((unsigned long)&ctx->context);
36283587

36293588
switch (base->type) {
36303589
case FW_ISO_CONTEXT_TRANSMIT:

0 commit comments

Comments
 (0)