diff options
author | Dave Jiang <dave.jiang@intel.com> | 2016-02-10 17:00:26 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2016-02-15 12:36:53 -0500 |
commit | cd60cd96137f6cb3ea82cace9225626619e7a52d (patch) | |
tree | 1593eea76792cc7de7f51552958170e9550e28a7 | |
parent | 679cfbf79b4eb7d7d81195e6b9ab98106fd78a54 (diff) |
dmaengine: IOATDMA: Removing descriptor ring reshape
Moving to contingous memory backed descriptor rings. This makes is really
difficult and complex to do reshape. Going to remove this as I don't think
we need to do it anymore.
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r-- | drivers/dma/ioat/dma.c | 143 | ||||
-rw-r--r-- | drivers/dma/ioat/dma.h | 5 | ||||
-rw-r--r-- | drivers/dma/ioat/init.c | 10 |
3 files changed, 1 insertions, 157 deletions
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 7a04c16a0bfa..9c4d3b20f520 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c | |||
@@ -332,9 +332,6 @@ ioat_alloc_ring(struct dma_chan *c, int order, gfp_t flags) | |||
332 | int descs = 1 << order; | 332 | int descs = 1 << order; |
333 | int i; | 333 | int i; |
334 | 334 | ||
335 | if (order > ioat_get_max_alloc_order()) | ||
336 | return NULL; | ||
337 | |||
338 | /* allocate the array to hold the software ring */ | 335 | /* allocate the array to hold the software ring */ |
339 | ring = kcalloc(descs, sizeof(*ring), flags); | 336 | ring = kcalloc(descs, sizeof(*ring), flags); |
340 | if (!ring) | 337 | if (!ring) |
@@ -362,114 +359,6 @@ ioat_alloc_ring(struct dma_chan *c, int order, gfp_t flags) | |||
362 | return ring; | 359 | return ring; |
363 | } | 360 | } |
364 | 361 | ||
365 | static bool reshape_ring(struct ioatdma_chan *ioat_chan, int order) | ||
366 | { | ||
367 | /* reshape differs from normal ring allocation in that we want | ||
368 | * to allocate a new software ring while only | ||
369 | * extending/truncating the hardware ring | ||
370 | */ | ||
371 | struct dma_chan *c = &ioat_chan->dma_chan; | ||
372 | const u32 curr_size = ioat_ring_size(ioat_chan); | ||
373 | const u16 active = ioat_ring_active(ioat_chan); | ||
374 | const u32 new_size = 1 << order; | ||
375 | struct ioat_ring_ent **ring; | ||
376 | u32 i; | ||
377 | |||
378 | if (order > ioat_get_max_alloc_order()) | ||
379 | return false; | ||
380 | |||
381 | /* double check that we have at least 1 free descriptor */ | ||
382 | if (active == curr_size) | ||
383 | return false; | ||
384 | |||
385 | /* when shrinking, verify that we can hold the current active | ||
386 | * set in the new ring | ||
387 | */ | ||
388 | if (active >= new_size) | ||
389 | return false; | ||
390 | |||
391 | /* allocate the array to hold the software ring */ | ||
392 | ring = kcalloc(new_size, sizeof(*ring), GFP_NOWAIT); | ||
393 | if (!ring) | ||
394 | return false; | ||
395 | |||
396 | /* allocate/trim descriptors as needed */ | ||
397 | if (new_size > curr_size) { | ||
398 | /* copy current descriptors to the new ring */ | ||
399 | for (i = 0; i < curr_size; i++) { | ||
400 | u16 curr_idx = (ioat_chan->tail+i) & (curr_size-1); | ||
401 | u16 new_idx = (ioat_chan->tail+i) & (new_size-1); | ||
402 | |||
403 | ring[new_idx] = ioat_chan->ring[curr_idx]; | ||
404 | set_desc_id(ring[new_idx], new_idx); | ||
405 | } | ||
406 | |||
407 | /* add new descriptors to the ring */ | ||
408 | for (i = curr_size; i < new_size; i++) { | ||
409 | u16 new_idx = (ioat_chan->tail+i) & (new_size-1); | ||
410 | |||
411 | ring[new_idx] = ioat_alloc_ring_ent(c, GFP_NOWAIT); | ||
412 | if (!ring[new_idx]) { | ||
413 | while (i--) { | ||
414 | u16 new_idx = (ioat_chan->tail+i) & | ||
415 | (new_size-1); | ||
416 | |||
417 | ioat_free_ring_ent(ring[new_idx], c); | ||
418 | } | ||
419 | kfree(ring); | ||
420 | return false; | ||
421 | } | ||
422 | set_desc_id(ring[new_idx], new_idx); | ||
423 | } | ||
424 | |||
425 | /* hw link new descriptors */ | ||
426 | for (i = curr_size-1; i < new_size; i++) { | ||
427 | u16 new_idx = (ioat_chan->tail+i) & (new_size-1); | ||
428 | struct ioat_ring_ent *next = | ||
429 | ring[(new_idx+1) & (new_size-1)]; | ||
430 | struct ioat_dma_descriptor *hw = ring[new_idx]->hw; | ||
431 | |||
432 | hw->next = next->txd.phys; | ||
433 | } | ||
434 | } else { | ||
435 | struct ioat_dma_descriptor *hw; | ||
436 | struct ioat_ring_ent *next; | ||
437 | |||
438 | /* copy current descriptors to the new ring, dropping the | ||
439 | * removed descriptors | ||
440 | */ | ||
441 | for (i = 0; i < new_size; i++) { | ||
442 | u16 curr_idx = (ioat_chan->tail+i) & (curr_size-1); | ||
443 | u16 new_idx = (ioat_chan->tail+i) & (new_size-1); | ||
444 | |||
445 | ring[new_idx] = ioat_chan->ring[curr_idx]; | ||
446 | set_desc_id(ring[new_idx], new_idx); | ||
447 | } | ||
448 | |||
449 | /* free deleted descriptors */ | ||
450 | for (i = new_size; i < curr_size; i++) { | ||
451 | struct ioat_ring_ent *ent; | ||
452 | |||
453 | ent = ioat_get_ring_ent(ioat_chan, ioat_chan->tail+i); | ||
454 | ioat_free_ring_ent(ent, c); | ||
455 | } | ||
456 | |||
457 | /* fix up hardware ring */ | ||
458 | hw = ring[(ioat_chan->tail+new_size-1) & (new_size-1)]->hw; | ||
459 | next = ring[(ioat_chan->tail+new_size) & (new_size-1)]; | ||
460 | hw->next = next->txd.phys; | ||
461 | } | ||
462 | |||
463 | dev_dbg(to_dev(ioat_chan), "%s: allocated %d descriptors\n", | ||
464 | __func__, new_size); | ||
465 | |||
466 | kfree(ioat_chan->ring); | ||
467 | ioat_chan->ring = ring; | ||
468 | ioat_chan->alloc_order = order; | ||
469 | |||
470 | return true; | ||
471 | } | ||
472 | |||
473 | /** | 362 | /** |
474 | * ioat_check_space_lock - verify space and grab ring producer lock | 363 | * ioat_check_space_lock - verify space and grab ring producer lock |
475 | * @ioat: ioat,3 channel (ring) to operate on | 364 | * @ioat: ioat,3 channel (ring) to operate on |
@@ -478,9 +367,6 @@ static bool reshape_ring(struct ioatdma_chan *ioat_chan, int order) | |||
478 | int ioat_check_space_lock(struct ioatdma_chan *ioat_chan, int num_descs) | 367 | int ioat_check_space_lock(struct ioatdma_chan *ioat_chan, int num_descs) |
479 | __acquires(&ioat_chan->prep_lock) | 368 | __acquires(&ioat_chan->prep_lock) |
480 | { | 369 | { |
481 | bool retry; | ||
482 | |||
483 | retry: | ||
484 | spin_lock_bh(&ioat_chan->prep_lock); | 370 | spin_lock_bh(&ioat_chan->prep_lock); |
485 | /* never allow the last descriptor to be consumed, we need at | 371 | /* never allow the last descriptor to be consumed, we need at |
486 | * least one free at all times to allow for on-the-fly ring | 372 | * least one free at all times to allow for on-the-fly ring |
@@ -493,24 +379,8 @@ int ioat_check_space_lock(struct ioatdma_chan *ioat_chan, int num_descs) | |||
493 | ioat_chan->produce = num_descs; | 379 | ioat_chan->produce = num_descs; |
494 | return 0; /* with ioat->prep_lock held */ | 380 | return 0; /* with ioat->prep_lock held */ |
495 | } | 381 | } |
496 | retry = test_and_set_bit(IOAT_RESHAPE_PENDING, &ioat_chan->state); | ||
497 | spin_unlock_bh(&ioat_chan->prep_lock); | 382 | spin_unlock_bh(&ioat_chan->prep_lock); |
498 | 383 | ||
499 | /* is another cpu already trying to expand the ring? */ | ||
500 | if (retry) | ||
501 | goto retry; | ||
502 | |||
503 | spin_lock_bh(&ioat_chan->cleanup_lock); | ||
504 | spin_lock_bh(&ioat_chan->prep_lock); | ||
505 | retry = reshape_ring(ioat_chan, ioat_chan->alloc_order + 1); | ||
506 | clear_bit(IOAT_RESHAPE_PENDING, &ioat_chan->state); | ||
507 | spin_unlock_bh(&ioat_chan->prep_lock); | ||
508 | spin_unlock_bh(&ioat_chan->cleanup_lock); | ||
509 | |||
510 | /* if we were able to expand the ring retry the allocation */ | ||
511 | if (retry) | ||
512 | goto retry; | ||
513 | |||
514 | dev_dbg_ratelimited(to_dev(ioat_chan), | 384 | dev_dbg_ratelimited(to_dev(ioat_chan), |
515 | "%s: ring full! num_descs: %d (%x:%x:%x)\n", | 385 | "%s: ring full! num_descs: %d (%x:%x:%x)\n", |
516 | __func__, num_descs, ioat_chan->head, | 386 | __func__, num_descs, ioat_chan->head, |
@@ -823,19 +693,6 @@ static void check_active(struct ioatdma_chan *ioat_chan) | |||
823 | 693 | ||
824 | if (test_and_clear_bit(IOAT_CHAN_ACTIVE, &ioat_chan->state)) | 694 | if (test_and_clear_bit(IOAT_CHAN_ACTIVE, &ioat_chan->state)) |
825 | mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); | 695 | mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); |
826 | else if (ioat_chan->alloc_order > ioat_get_alloc_order()) { | ||
827 | /* if the ring is idle, empty, and oversized try to step | ||
828 | * down the size | ||
829 | */ | ||
830 | reshape_ring(ioat_chan, ioat_chan->alloc_order - 1); | ||
831 | |||
832 | /* keep shrinking until we get back to our minimum | ||
833 | * default size | ||
834 | */ | ||
835 | if (ioat_chan->alloc_order > ioat_get_alloc_order()) | ||
836 | mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); | ||
837 | } | ||
838 | |||
839 | } | 696 | } |
840 | 697 | ||
841 | void ioat_timer_event(unsigned long data) | 698 | void ioat_timer_event(unsigned long data) |
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index f471092440d3..5f2f9fbcf184 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h | |||
@@ -100,7 +100,6 @@ struct ioatdma_chan { | |||
100 | #define IOAT_COMPLETION_ACK 1 | 100 | #define IOAT_COMPLETION_ACK 1 |
101 | #define IOAT_RESET_PENDING 2 | 101 | #define IOAT_RESET_PENDING 2 |
102 | #define IOAT_KOBJ_INIT_FAIL 3 | 102 | #define IOAT_KOBJ_INIT_FAIL 3 |
103 | #define IOAT_RESHAPE_PENDING 4 | ||
104 | #define IOAT_RUN 5 | 103 | #define IOAT_RUN 5 |
105 | #define IOAT_CHAN_ACTIVE 6 | 104 | #define IOAT_CHAN_ACTIVE 6 |
106 | struct timer_list timer; | 105 | struct timer_list timer; |
@@ -302,10 +301,6 @@ static inline bool is_ioat_bug(unsigned long err) | |||
302 | } | 301 | } |
303 | 302 | ||
304 | #define IOAT_MAX_ORDER 16 | 303 | #define IOAT_MAX_ORDER 16 |
305 | #define ioat_get_alloc_order() \ | ||
306 | (min(ioat_ring_alloc_order, IOAT_MAX_ORDER)) | ||
307 | #define ioat_get_max_alloc_order() \ | ||
308 | (min(ioat_ring_max_alloc_order, IOAT_MAX_ORDER)) | ||
309 | 304 | ||
310 | static inline u32 ioat_ring_size(struct ioatdma_chan *ioat_chan) | 305 | static inline u32 ioat_ring_size(struct ioatdma_chan *ioat_chan) |
311 | { | 306 | { |
diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c index b02b63b719db..66369204896a 100644 --- a/drivers/dma/ioat/init.c +++ b/drivers/dma/ioat/init.c | |||
@@ -136,14 +136,6 @@ int ioat_pending_level = 4; | |||
136 | module_param(ioat_pending_level, int, 0644); | 136 | module_param(ioat_pending_level, int, 0644); |
137 | MODULE_PARM_DESC(ioat_pending_level, | 137 | MODULE_PARM_DESC(ioat_pending_level, |
138 | "high-water mark for pushing ioat descriptors (default: 4)"); | 138 | "high-water mark for pushing ioat descriptors (default: 4)"); |
139 | int ioat_ring_alloc_order = 8; | ||
140 | module_param(ioat_ring_alloc_order, int, 0644); | ||
141 | MODULE_PARM_DESC(ioat_ring_alloc_order, | ||
142 | "ioat+: allocate 2^n descriptors per channel (default: 8 max: 16)"); | ||
143 | int ioat_ring_max_alloc_order = IOAT_MAX_ORDER; | ||
144 | module_param(ioat_ring_max_alloc_order, int, 0644); | ||
145 | MODULE_PARM_DESC(ioat_ring_max_alloc_order, | ||
146 | "ioat+: upper limit for ring size (default: 16)"); | ||
147 | static char ioat_interrupt_style[32] = "msix"; | 139 | static char ioat_interrupt_style[32] = "msix"; |
148 | module_param_string(ioat_interrupt_style, ioat_interrupt_style, | 140 | module_param_string(ioat_interrupt_style, ioat_interrupt_style, |
149 | sizeof(ioat_interrupt_style), 0644); | 141 | sizeof(ioat_interrupt_style), 0644); |
@@ -712,7 +704,7 @@ static int ioat_alloc_chan_resources(struct dma_chan *c) | |||
712 | writel(((u64)ioat_chan->completion_dma) >> 32, | 704 | writel(((u64)ioat_chan->completion_dma) >> 32, |
713 | ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH); | 705 | ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH); |
714 | 706 | ||
715 | order = ioat_get_alloc_order(); | 707 | order = IOAT_MAX_ORDER; |
716 | ring = ioat_alloc_ring(c, order, GFP_KERNEL); | 708 | ring = ioat_alloc_ring(c, order, GFP_KERNEL); |
717 | if (!ring) | 709 | if (!ring) |
718 | return -ENOMEM; | 710 | return -ENOMEM; |