Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: core: Free range of buffers

Improve __vb2_queue_free() and __vb2_free_mem() to free
range of buffers and not only the last few buffers.
Introduce starting index to be flexible on range and change the loops
according to this parameter.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Acked-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>

authored by

Benjamin Gaignard and committed by
Hans Verkuil
5fb19f20 a286b083

+26 -30
+26 -30
drivers/media/common/videobuf2/videobuf2-core.c
··· 540 540 } 541 541 542 542 /* 543 - * __vb2_free_mem() - release all video buffer memory for a given queue 543 + * __vb2_free_mem() - release video buffer memory for a given range of 544 + * buffers in a given queue 544 545 */ 545 - static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers) 546 + static void __vb2_free_mem(struct vb2_queue *q, unsigned int start, unsigned int count) 546 547 { 547 - unsigned int buffer; 548 + unsigned int i; 548 549 struct vb2_buffer *vb; 549 - unsigned int q_num_buffers = vb2_get_num_buffers(q); 550 550 551 - for (buffer = q_num_buffers - buffers; buffer < q_num_buffers; 552 - ++buffer) { 553 - vb = vb2_get_buffer(q, buffer); 551 + for (i = start; i < start + count; i++) { 552 + vb = vb2_get_buffer(q, i); 554 553 if (!vb) 555 554 continue; 556 555 ··· 564 565 } 565 566 566 567 /* 567 - * __vb2_queue_free() - free buffers at the end of the queue - video memory and 568 + * __vb2_queue_free() - free @count buffers from @start index of the queue - video memory and 568 569 * related information, if no buffers are left return the queue to an 569 570 * uninitialized state. Might be called even if the queue has already been freed. 570 571 */ 571 - static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) 572 + static void __vb2_queue_free(struct vb2_queue *q, unsigned int start, unsigned int count) 572 573 { 573 - unsigned int buffer; 574 - unsigned int q_num_buffers = vb2_get_num_buffers(q); 574 + unsigned int i; 575 575 576 576 lockdep_assert_held(&q->mmap_lock); 577 577 578 578 /* Call driver-provided cleanup function for each buffer, if provided */ 579 - for (buffer = q_num_buffers - buffers; buffer < q_num_buffers; 580 - ++buffer) { 581 - struct vb2_buffer *vb = vb2_get_buffer(q, buffer); 579 + for (i = start; i < start + count; i++) { 580 + struct vb2_buffer *vb = vb2_get_buffer(q, i); 582 581 583 582 if (vb && vb->planes[0].mem_priv) 584 583 call_void_vb_qop(vb, buf_cleanup, vb); 585 584 } 586 585 587 586 /* Release video buffer memory */ 588 - __vb2_free_mem(q, buffers); 587 + __vb2_free_mem(q, start, count); 589 588 590 589 #ifdef CONFIG_VIDEO_ADV_DEBUG 591 590 /* 592 591 * Check that all the calls were balanced during the life-time of this 593 592 * queue. If not then dump the counters to the kernel log. 594 593 */ 595 - if (q_num_buffers) { 594 + if (vb2_get_num_buffers(q)) { 596 595 bool unbalanced = q->cnt_start_streaming != q->cnt_stop_streaming || 597 596 q->cnt_prepare_streaming != q->cnt_unprepare_streaming || 598 597 q->cnt_wait_prepare != q->cnt_wait_finish; ··· 616 619 q->cnt_stop_streaming = 0; 617 620 q->cnt_unprepare_streaming = 0; 618 621 } 619 - for (buffer = 0; buffer < vb2_get_num_buffers(q); buffer++) { 620 - struct vb2_buffer *vb = vb2_get_buffer(q, buffer); 622 + for (i = start; i < start + count; i++) { 623 + struct vb2_buffer *vb = vb2_get_buffer(q, i); 621 624 bool unbalanced; 622 625 623 626 if (!vb) ··· 634 637 635 638 if (unbalanced) { 636 639 pr_info("unbalanced counters for queue %p, buffer %d:\n", 637 - q, buffer); 640 + q, i); 638 641 if (vb->cnt_buf_init != vb->cnt_buf_cleanup) 639 642 pr_info(" buf_init: %u buf_cleanup: %u\n", 640 643 vb->cnt_buf_init, vb->cnt_buf_cleanup); ··· 668 671 #endif 669 672 670 673 /* Free vb2 buffers */ 671 - for (buffer = q_num_buffers - buffers; buffer < q_num_buffers; 672 - ++buffer) { 673 - struct vb2_buffer *vb = vb2_get_buffer(q, buffer); 674 + for (i = start; i < start + count; i++) { 675 + struct vb2_buffer *vb = vb2_get_buffer(q, i); 674 676 675 677 if (!vb) 676 678 continue; ··· 709 713 static bool __buffers_in_use(struct vb2_queue *q) 710 714 { 711 715 unsigned int buffer; 712 - for (buffer = 0; buffer < vb2_get_num_buffers(q); ++buffer) { 716 + for (buffer = 0; buffer < q->max_num_buffers; ++buffer) { 713 717 struct vb2_buffer *vb = vb2_get_buffer(q, buffer); 714 718 715 719 if (!vb) ··· 895 899 * queued without ever calling STREAMON. 896 900 */ 897 901 __vb2_queue_cancel(q); 898 - __vb2_queue_free(q, q_num_bufs); 902 + __vb2_queue_free(q, 0, q->max_num_buffers); 899 903 mutex_unlock(&q->mmap_lock); 900 904 901 905 q->is_busy = 0; ··· 997 1001 * from already queued buffers and it will reset q->memory to 998 1002 * VB2_MEMORY_UNKNOWN. 999 1003 */ 1000 - __vb2_queue_free(q, allocated_buffers); 1004 + __vb2_queue_free(q, first_index, allocated_buffers); 1001 1005 mutex_unlock(&q->mmap_lock); 1002 1006 return ret; 1003 1007 } ··· 1122 1126 * from already queued buffers and it will reset q->memory to 1123 1127 * VB2_MEMORY_UNKNOWN. 1124 1128 */ 1125 - __vb2_queue_free(q, allocated_buffers); 1129 + __vb2_queue_free(q, *first_index, allocated_buffers); 1126 1130 mutex_unlock(&q->mmap_lock); 1127 1131 return -ENOMEM; 1128 1132 } ··· 1737 1741 * Forcefully reclaim buffers if the driver did not 1738 1742 * correctly return them to vb2. 1739 1743 */ 1740 - for (i = 0; i < vb2_get_num_buffers(q); ++i) { 1744 + for (i = 0; i < q->max_num_buffers; ++i) { 1741 1745 vb = vb2_get_buffer(q, i); 1742 1746 1743 1747 if (!vb) ··· 2143 2147 * to vb2 in stop_streaming(). 2144 2148 */ 2145 2149 if (WARN_ON(atomic_read(&q->owned_by_drv_count))) { 2146 - for (i = 0; i < vb2_get_num_buffers(q); i++) { 2150 + for (i = 0; i < q->max_num_buffers; i++) { 2147 2151 struct vb2_buffer *vb = vb2_get_buffer(q, i); 2148 2152 2149 2153 if (!vb) ··· 2187 2191 * call to __fill_user_buffer() after buf_finish(). That order can't 2188 2192 * be changed, so we can't move the buf_finish() to __vb2_dqbuf(). 2189 2193 */ 2190 - for (i = 0; i < vb2_get_num_buffers(q); i++) { 2194 + for (i = 0; i < q->max_num_buffers; i++) { 2191 2195 struct vb2_buffer *vb; 2192 2196 struct media_request *req; 2193 2197 ··· 2614 2618 __vb2_cleanup_fileio(q); 2615 2619 __vb2_queue_cancel(q); 2616 2620 mutex_lock(&q->mmap_lock); 2617 - __vb2_queue_free(q, vb2_get_num_buffers(q)); 2621 + __vb2_queue_free(q, 0, q->max_num_buffers); 2618 2622 vb2_core_free_buffers_storage(q); 2619 2623 q->is_busy = 0; 2620 2624 mutex_unlock(&q->mmap_lock);