From 3508d1d1a1473ae249d48a7ea7a441ab6424ebd4 Mon Sep 17 00:00:00 2001 From: Dan Vacura Date: Thu, 8 Dec 2022 15:30:21 -0600 Subject: [PATCH 1/3] ANDROID: usb: gadget: uvc: remove duplicate code in unbind The uvc_function_unbind() was calling the same code two times, increasing a timeout that may occur. The duplicate code looks to have come in during the merge of 5.10.117. Remove the duplicate code. Bug: 261895714 Change-Id: I8957048bfad4a9e01baea033de9b628362b2d991 Signed-off-by: Dan Vacura --- drivers/usb/gadget/function/f_uvc.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 607ea0c1bfb3..1fc00cce83fb 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -906,18 +906,6 @@ static void uvc_function_unbind(struct usb_configuration *c, uvcg_dbg(f, "done waiting with ret: %ld\n", wait_ret); } - /* If we know we're connected via v4l2, then there should be a cleanup - * of the device from userspace either via UVC_EVENT_DISCONNECT or - * though the video device removal uevent. Allow some time for the - * application to close out before things get deleted. - */ - if (uvc->func_connected) { - uvcg_dbg(f, "waiting for clean disconnect\n"); - wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue, - uvc->func_connected == false, msecs_to_jiffies(500)); - uvcg_dbg(f, "done waiting with ret: %ld\n", wait_ret); - } - device_remove_file(&uvc->vdev.dev, &dev_attr_function_name); video_unregister_device(&uvc->vdev); v4l2_device_unregister(&uvc->v4l2_dev); From 231c779b62805baaeb84817d9b6fa7885b71d525 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Thu, 8 Dec 2022 15:05:08 +0530 Subject: [PATCH 2/3] ANDROID: dma-buf: Fix build breakage with !CONFIG_DMABUF_SYSFS_STATS The commit c5589c7eec41 ("ANDROID: dma-buf: Add vendor hook for deferred dmabuf sysfs stats release") introduced a build breakage on non-GKI targets which don't have CONFIG_DMABUF_SYSFS_STATS enabled. It is due to invisibility of struct dma_buf_sysfs_entry in the trace hook header file. We can get away with it by moving the header inclusion from trace hook header to vendor hooks driver. Bug: 261818075 Bug: 262666413 Change-Id: Ibb79bd67c9f1b36fe2b5d569ab9369f376a78b77 Signed-off-by: Pavankumar Kondeti (cherry picked from commit 8ad88eae4b6914c512569b10c19e04754def1746) --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/dmabuf.h | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 12066949e275..91288f59a390 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -7,6 +7,7 @@ */ #ifndef __GENKSYMS__ +#include #include #endif diff --git a/include/trace/hooks/dmabuf.h b/include/trace/hooks/dmabuf.h index 8963742273bc..0182960efca2 100644 --- a/include/trace/hooks/dmabuf.h +++ b/include/trace/hooks/dmabuf.h @@ -11,13 +11,7 @@ #include -#ifdef __GENKSYMS__ struct dma_buf_sysfs_entry; -#else -/* struct dma_buf_sysfs_entry */ -#include -#endif - DECLARE_RESTRICTED_HOOK(android_rvh_dma_buf_stats_teardown, TP_PROTO(struct dma_buf_sysfs_entry *sysfs_entry, bool *skip_sysfs_release), TP_ARGS(sysfs_entry, skip_sysfs_release), 1); From 2b4f804f72e8d8157532cf32a679268a7a965ae6 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Thu, 8 Dec 2022 16:16:37 +0530 Subject: [PATCH 3/3] ANDROID: dma-buf: don't re-purpose kobject as work_struct The commit 5aec776ef8c9 ("BACKPORT: ANDROID: dma-buf: Move sysfs work out of DMA-BUF export path) re-purposed kobject as work_struct temporarily to create the sysfs entries asynchronously. The author knows what he is doing and rightly added a build assert if kobject struct size is smaller than the work_struct size. We are hitting this build assert on a non-GKI platform where CONFIG_ANDROID_KABI_RESERVE is not set. Fix this problem by allocating a new union with dma_buf_sysfs_entry structure and temporary structure as members. We only end up allocating more memory (because of union) only when kobject size is smaller than work_struct which the original patch any way assumed would never be true. Bug: 261818147 Bug: 262666413 Change-Id: Ifb089bf80d8a3a44ece9f05fc0b99ee76cb11645 Signed-off-by: Pavankumar Kondeti (cherry picked from commit ce18af9b5d7d0baad2ac3eea4c732d2bf128d690) --- drivers/dma-buf/dma-buf-sysfs-stats.c | 44 +++++++++++++++------------ 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/drivers/dma-buf/dma-buf-sysfs-stats.c b/drivers/dma-buf/dma-buf-sysfs-stats.c index 7ae64cd3dbb8..5c8efa55e3aa 100644 --- a/drivers/dma-buf/dma-buf-sysfs-stats.c +++ b/drivers/dma-buf/dma-buf-sysfs-stats.c @@ -142,15 +142,21 @@ void dma_buf_uninit_sysfs_statistics(void) kset_unregister(dma_buf_stats_kset); } +struct dma_buf_create_sysfs_entry { + struct dma_buf *dmabuf; + struct work_struct work; +}; + +union dma_buf_create_sysfs_work_entry { + struct dma_buf_create_sysfs_entry create_entry; + struct dma_buf_sysfs_entry sysfs_entry; +}; + static void sysfs_add_workfn(struct work_struct *work) { - /* The ABI would have to change for this to be false, but let's be paranoid. */ - _Static_assert(sizeof(struct kobject) >= sizeof(struct work_struct), - "kobject is smaller than work_struct"); - - struct dma_buf_sysfs_entry *sysfs_entry = - container_of((struct kobject *)work, struct dma_buf_sysfs_entry, kobj); - struct dma_buf *dmabuf = sysfs_entry->dmabuf; + struct dma_buf_create_sysfs_entry *create_entry = + container_of(work, struct dma_buf_create_sysfs_entry, work); + struct dma_buf *dmabuf = create_entry->dmabuf; /* * A dmabuf is ref-counted via its file member. If this handler holds the only @@ -161,6 +167,7 @@ static void sysfs_add_workfn(struct work_struct *work) * is released, and that can't happen until the end of this function. */ if (file_count(dmabuf->file) > 1) { + dmabuf->sysfs_entry->dmabuf = dmabuf; /* * kobject_init_and_add expects kobject to be zero-filled, but we have populated it * to trigger this work function. @@ -185,8 +192,8 @@ static void sysfs_add_workfn(struct work_struct *work) int dma_buf_stats_setup(struct dma_buf *dmabuf) { - struct dma_buf_sysfs_entry *sysfs_entry; - struct work_struct *work; + struct dma_buf_create_sysfs_entry *create_entry; + union dma_buf_create_sysfs_work_entry *work_entry; if (!dmabuf || !dmabuf->file) return -EINVAL; @@ -196,21 +203,18 @@ int dma_buf_stats_setup(struct dma_buf *dmabuf) return -EINVAL; } - sysfs_entry = kmalloc(sizeof(struct dma_buf_sysfs_entry), GFP_KERNEL); - if (!sysfs_entry) + work_entry = kmalloc(sizeof(union dma_buf_create_sysfs_work_entry), GFP_KERNEL); + if (!work_entry) return -ENOMEM; - sysfs_entry->dmabuf = dmabuf; - dmabuf->sysfs_entry = sysfs_entry; + dmabuf->sysfs_entry = &work_entry->sysfs_entry; - /* - * The use of kobj as a work_struct is an ugly hack - * to avoid an ABI break in this frozen kernel. - */ - work = (struct work_struct *)&dmabuf->sysfs_entry->kobj; - INIT_WORK(work, sysfs_add_workfn); + create_entry = &work_entry->create_entry; + create_entry->dmabuf = dmabuf; + + INIT_WORK(&create_entry->work, sysfs_add_workfn); get_dma_buf(dmabuf); /* This reference will be dropped in sysfs_add_workfn. */ - schedule_work(work); + schedule_work(&create_entry->work); return 0; }