Commit f30e6d3e419bfb5540fa82ba7eca01d578556e6b

Authored by Stefan Richter
1 parent 020abf03cd

firewire: octlet AT payloads can be stack-allocated

We do not need slab allocations anymore in order to satisfy
streaming DMA mapping constraints, thanks to commit da28947e7e36
"firewire: ohci: avoid separate DMA mapping for small AT payloads".

(Besides, the slab-allocated buffers that firewire-core, firewire-sbp2,
and firedtv used to provide for 8-byte write and lock requests were
still not fully portable since they crossed cacheline boundaries or
shared a cacheline with unrelated CPU-accessed data.  snd-firewire-lib
got this aspect right by using an extra kmalloc/ kfree just for the
8-byte transaction buffer.)

This change replaces kmalloc'ed lock transaction scratch buffers in
firewire-core, firedtv, and snd-firewire-lib by local stack allocations.
Perhaps the most notable result of the change is simpler locking because
there is no need to serialize usages of preallocated per-device buffers
anymore.  Also, allocations and deallocations are simpler.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Acked-by: Clemens Ladisch <clemens@ladisch.de>

Showing 9 changed files with 30 additions and 52 deletions Side-by-side Diff

drivers/firewire/core-card.c
... ... @@ -258,8 +258,7 @@
258 258  
259 259 if (!card->broadcast_channel_allocated) {
260 260 fw_iso_resource_manage(card, generation, 1ULL << 31,
261   - &channel, &bandwidth, true,
262   - card->bm_transaction_data);
  261 + &channel, &bandwidth, true);
263 262 if (channel != 31) {
264 263 fw_notify("failed to allocate broadcast channel\n");
265 264 return;
... ... @@ -294,6 +293,7 @@
294 293 bool root_device_is_cmc;
295 294 bool irm_is_1394_1995_only;
296 295 bool keep_this_irm;
  296 + __be32 transaction_data[2];
297 297  
298 298 spin_lock_irq(&card->lock);
299 299  
300 300  
301 301  
... ... @@ -355,21 +355,21 @@
355 355 goto pick_me;
356 356 }
357 357  
358   - card->bm_transaction_data[0] = cpu_to_be32(0x3f);
359   - card->bm_transaction_data[1] = cpu_to_be32(local_id);
  358 + transaction_data[0] = cpu_to_be32(0x3f);
  359 + transaction_data[1] = cpu_to_be32(local_id);
360 360  
361 361 spin_unlock_irq(&card->lock);
362 362  
363 363 rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
364 364 irm_id, generation, SCODE_100,
365 365 CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
366   - card->bm_transaction_data, 8);
  366 + transaction_data, 8);
367 367  
368 368 if (rcode == RCODE_GENERATION)
369 369 /* Another bus reset, BM work has been rescheduled. */
370 370 goto out;
371 371  
372   - bm_id = be32_to_cpu(card->bm_transaction_data[0]);
  372 + bm_id = be32_to_cpu(transaction_data[0]);
373 373  
374 374 spin_lock_irq(&card->lock);
375 375 if (rcode == RCODE_COMPLETE && generation == card->generation)
376 376  
... ... @@ -490,11 +490,11 @@
490 490 /*
491 491 * Make sure that the cycle master sends cycle start packets.
492 492 */
493   - card->bm_transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR);
  493 + transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR);
494 494 rcode = fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST,
495 495 root_id, generation, SCODE_100,
496 496 CSR_REGISTER_BASE + CSR_STATE_SET,
497   - card->bm_transaction_data, 4);
  497 + transaction_data, 4);
498 498 if (rcode == RCODE_GENERATION)
499 499 goto out;
500 500 }
drivers/firewire/core-cdev.c
... ... @@ -141,7 +141,6 @@
141 141 int generation;
142 142 u64 channels;
143 143 s32 bandwidth;
144   - __be32 transaction_data[2];
145 144 struct iso_resource_event *e_alloc, *e_dealloc;
146 145 };
147 146  
... ... @@ -1229,8 +1228,7 @@
1229 1228 r->channels, &channel, &bandwidth,
1230 1229 todo == ISO_RES_ALLOC ||
1231 1230 todo == ISO_RES_REALLOC ||
1232   - todo == ISO_RES_ALLOC_ONCE,
1233   - r->transaction_data);
  1231 + todo == ISO_RES_ALLOC_ONCE);
1234 1232 /*
1235 1233 * Is this generation outdated already? As long as this resource sticks
1236 1234 * in the idr, it will be scheduled again for a newer generation or at
drivers/firewire/core-iso.c
... ... @@ -196,9 +196,10 @@
196 196 */
197 197  
198 198 static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
199   - int bandwidth, bool allocate, __be32 data[2])
  199 + int bandwidth, bool allocate)
200 200 {
201 201 int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0;
  202 + __be32 data[2];
202 203  
203 204 /*
204 205 * On a 1394a IRM with low contention, try < 1 is enough.
205 206  
... ... @@ -233,9 +234,10 @@
233 234 }
234 235  
235 236 static int manage_channel(struct fw_card *card, int irm_id, int generation,
236   - u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
  237 + u32 channels_mask, u64 offset, bool allocate)
237 238 {
238 239 __be32 bit, all, old;
  240 + __be32 data[2];
239 241 int channel, ret = -EIO, retry = 5;
240 242  
241 243 old = all = allocate ? cpu_to_be32(~0) : 0;
... ... @@ -284,7 +286,7 @@
284 286 }
285 287  
286 288 static void deallocate_channel(struct fw_card *card, int irm_id,
287   - int generation, int channel, __be32 buffer[2])
  289 + int generation, int channel)
288 290 {
289 291 u32 mask;
290 292 u64 offset;
... ... @@ -293,7 +295,7 @@
293 295 offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI :
294 296 CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO;
295 297  
296   - manage_channel(card, irm_id, generation, mask, offset, false, buffer);
  298 + manage_channel(card, irm_id, generation, mask, offset, false);
297 299 }
298 300  
299 301 /**
... ... @@ -322,7 +324,7 @@
322 324 */
323 325 void fw_iso_resource_manage(struct fw_card *card, int generation,
324 326 u64 channels_mask, int *channel, int *bandwidth,
325   - bool allocate, __be32 buffer[2])
  327 + bool allocate)
326 328 {
327 329 u32 channels_hi = channels_mask; /* channels 31...0 */
328 330 u32 channels_lo = channels_mask >> 32; /* channels 63...32 */
329 331  
... ... @@ -335,11 +337,11 @@
335 337 if (channels_hi)
336 338 c = manage_channel(card, irm_id, generation, channels_hi,
337 339 CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI,
338   - allocate, buffer);
  340 + allocate);
339 341 if (channels_lo && c < 0) {
340 342 c = manage_channel(card, irm_id, generation, channels_lo,
341 343 CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO,
342   - allocate, buffer);
  344 + allocate);
343 345 if (c >= 0)
344 346 c += 32;
345 347 }
346 348  
... ... @@ -351,14 +353,13 @@
351 353 if (*bandwidth == 0)
352 354 return;
353 355  
354   - ret = manage_bandwidth(card, irm_id, generation, *bandwidth,
355   - allocate, buffer);
  356 + ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate);
356 357 if (ret < 0)
357 358 *bandwidth = 0;
358 359  
359 360 if (allocate && ret < 0) {
360 361 if (c >= 0)
361   - deallocate_channel(card, irm_id, generation, c, buffer);
  362 + deallocate_channel(card, irm_id, generation, c);
362 363 *channel = ret;
363 364 }
364 365 }
drivers/firewire/core-transaction.c
... ... @@ -326,8 +326,8 @@
326 326 * It will contain tag, channel, and sy data instead of a node ID then.
327 327 *
328 328 * The payload buffer at @data is going to be DMA-mapped except in case of
329   - * quadlet-sized payload or of local (loopback) requests. Hence make sure that
330   - * the buffer complies with the restrictions for DMA-mapped memory. The
  329 + * @length <= 8 or of local (loopback) requests. Hence make sure that the
  330 + * buffer complies with the restrictions of the streaming DMA mapping API.
331 331 * @payload must not be freed before the @callback is called.
332 332 *
333 333 * In case of request types without payload, @data is NULL and @length is 0.
... ... @@ -411,7 +411,8 @@
411 411 *
412 412 * Returns the RCODE. See fw_send_request() for parameter documentation.
413 413 * Unlike fw_send_request(), @data points to the payload of the request or/and
414   - * to the payload of the response.
  414 + * to the payload of the response. DMA mapping restrictions apply to outbound
  415 + * request payloads of >= 8 bytes but not to inbound response payloads.
415 416 */
416 417 int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
417 418 int generation, int speed, unsigned long long offset,
drivers/media/dvb/firewire/firedtv-avc.c
... ... @@ -1320,14 +1320,10 @@
1320 1320 {
1321 1321 int ret;
1322 1322  
1323   - mutex_lock(&fdtv->avc_mutex);
1324   -
1325 1323 ret = fdtv_read(fdtv, addr, data);
1326 1324 if (ret < 0)
1327 1325 dev_err(fdtv->device, "CMP: read I/O error\n");
1328 1326  
1329   - mutex_unlock(&fdtv->avc_mutex);
1330   -
1331 1327 return ret;
1332 1328 }
1333 1329  
1334 1330  
... ... @@ -1335,18 +1331,9 @@
1335 1331 {
1336 1332 int ret;
1337 1333  
1338   - mutex_lock(&fdtv->avc_mutex);
1339   -
1340   - /* data[] is stack-allocated and should not be DMA-mapped. */
1341   - memcpy(fdtv->avc_data, data, 8);
1342   -
1343   - ret = fdtv_lock(fdtv, addr, fdtv->avc_data);
  1334 + ret = fdtv_lock(fdtv, addr, data);
1344 1335 if (ret < 0)
1345 1336 dev_err(fdtv->device, "CMP: lock I/O error\n");
1346   - else
1347   - memcpy(data, fdtv->avc_data, 8);
1348   -
1349   - mutex_unlock(&fdtv->avc_mutex);
1350 1337  
1351 1338 return ret;
1352 1339 }
include/linux/firewire.h
... ... @@ -125,7 +125,6 @@
125 125 struct delayed_work bm_work; /* bus manager job */
126 126 int bm_retries;
127 127 int bm_generation;
128   - __be32 bm_transaction_data[2];
129 128 int bm_node_id;
130 129 bool bm_abdicate;
131 130  
... ... @@ -447,7 +446,7 @@
447 446 void fw_iso_context_destroy(struct fw_iso_context *ctx);
448 447 void fw_iso_resource_manage(struct fw_card *card, int generation,
449 448 u64 channels_mask, int *channel, int *bandwidth,
450   - bool allocate, __be32 buffer[2]);
  449 + bool allocate);
451 450  
452 451 #endif /* _LINUX_FIREWIRE_H */
sound/firewire/cmp.c
... ... @@ -49,10 +49,9 @@
49 49 enum bus_reset_handling bus_reset_handling)
50 50 {
51 51 struct fw_device *device = fw_parent_device(c->resources.unit);
52   - __be32 *buffer = c->resources.buffer;
53 52 int generation = c->resources.generation;
54 53 int rcode, errors = 0;
55   - __be32 old_arg;
  54 + __be32 old_arg, buffer[2];
56 55 int err;
57 56  
58 57 buffer[0] = c->last_pcr_value;
sound/firewire/iso-resources.c
... ... @@ -11,7 +11,6 @@
11 11 #include <linux/jiffies.h>
12 12 #include <linux/mutex.h>
13 13 #include <linux/sched.h>
14   -#include <linux/slab.h>
15 14 #include <linux/spinlock.h>
16 15 #include "iso-resources.h"
17 16  
... ... @@ -25,10 +24,6 @@
25 24 */
26 25 int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit)
27 26 {
28   - r->buffer = kmalloc(2 * 4, GFP_KERNEL);
29   - if (!r->buffer)
30   - return -ENOMEM;
31   -
32 27 r->channels_mask = ~0uLL;
33 28 r->unit = fw_unit_get(unit);
34 29 mutex_init(&r->mutex);
... ... @@ -44,7 +39,6 @@
44 39 void fw_iso_resources_destroy(struct fw_iso_resources *r)
45 40 {
46 41 WARN_ON(r->allocated);
47   - kfree(r->buffer);
48 42 mutex_destroy(&r->mutex);
49 43 fw_unit_put(r->unit);
50 44 }
... ... @@ -131,7 +125,7 @@
131 125  
132 126 bandwidth = r->bandwidth + r->bandwidth_overhead;
133 127 fw_iso_resource_manage(card, r->generation, r->channels_mask,
134   - &channel, &bandwidth, true, r->buffer);
  128 + &channel, &bandwidth, true);
135 129 if (channel == -EAGAIN) {
136 130 mutex_unlock(&r->mutex);
137 131 goto retry_after_bus_reset;
... ... @@ -184,7 +178,7 @@
184 178 bandwidth = r->bandwidth + r->bandwidth_overhead;
185 179  
186 180 fw_iso_resource_manage(card, r->generation, 1uLL << r->channel,
187   - &channel, &bandwidth, true, r->buffer);
  181 + &channel, &bandwidth, true);
188 182 /*
189 183 * When another bus reset happens, pretend that the allocation
190 184 * succeeded; we will try again for the new generation later.
... ... @@ -220,7 +214,7 @@
220 214 if (r->allocated) {
221 215 bandwidth = r->bandwidth + r->bandwidth_overhead;
222 216 fw_iso_resource_manage(card, r->generation, 1uLL << r->channel,
223   - &channel, &bandwidth, false, r->buffer);
  217 + &channel, &bandwidth, false);
224 218 if (channel < 0)
225 219 dev_err(&r->unit->device,
226 220 "isochronous resource deallocation failed\n");
sound/firewire/iso-resources.h
... ... @@ -24,7 +24,6 @@
24 24 unsigned int bandwidth_overhead;
25 25 int generation; /* in which allocation is valid */
26 26 bool allocated;
27   - __be32 *buffer;
28 27 };
29 28  
30 29 int fw_iso_resources_init(struct fw_iso_resources *r,