Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package pipewire for openSUSE:Factory checked in at 2023-09-12 21:02:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/pipewire (Old) and /work/SRC/openSUSE:Factory/.pipewire.new.1766 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "pipewire" Tue Sep 12 21:02:05 2023 rev:94 rq:1110286 version:0.3.79 Changes: -------- --- /work/SRC/openSUSE:Factory/pipewire/pipewire.changes 2023-08-31 13:43:03.546521197 +0200 +++ /work/SRC/openSUSE:Factory/.pipewire.new.1766/pipewire.changes 2023-09-12 21:02:10.750668492 +0200 @@ -1,0 +2,12 @@ +Mon Sep 11 09:56:03 UTC 2023 - Antonio Larrosa <alarr...@suse.com> + +- Add patch from upstream to fix a regression introduced in 0.3.77 + which made it fail to open a monitor device as source: + * 0001-pulse-server-allow-monitors-when-selecting-source-by-index.patch +- Add patch from upstream to fix a bug which caused 100% cpu usage + under some circumstances: + * 0001-Revert-v4l2-handle-inotify-errors.patch + * 0002-Revert-v4l2-dont-set-inotify-on-_dev.patch + * 0003-spa-v4l2-use-a-separate-watch-for-each-device.patch + +------------------------------------------------------------------- New: ---- 0001-Revert-v4l2-handle-inotify-errors.patch 0001-pulse-server-allow-monitors-when-selecting-source-by-index.patch 0002-Revert-v4l2-dont-set-inotify-on-_dev.patch 0003-spa-v4l2-use-a-separate-watch-for-each-device.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ pipewire.spec ++++++ --- /var/tmp/diff_new_pack.gs2rml/_old 2023-09-12 21:02:12.398727276 +0200 +++ /var/tmp/diff_new_pack.gs2rml/_new 2023-09-12 21:02:12.402727420 +0200 @@ -70,6 +70,11 @@ Source99: baselibs.conf # PATCH-FIX-OPENSUSE reduce-meson-dependency.patch Patch0: reduce-meson-dependency.patch +Patch1: 0001-pulse-server-allow-monitors-when-selecting-source-by-index.patch +Patch2: 0001-Revert-v4l2-handle-inotify-errors.patch +Patch3: 0002-Revert-v4l2-dont-set-inotify-on-_dev.patch +Patch4: 0003-spa-v4l2-use-a-separate-watch-for-each-device.patch + BuildRequires: docutils BuildRequires: doxygen BuildRequires: fdupes @@ -382,6 +387,10 @@ sed -ie "s/version : '0.3.72'/version : '%{version}'/" %{P:0} %patch0 -p1 %endif +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 %build %if %{pkg_vcmp gcc < 8} ++++++ 0001-Revert-v4l2-handle-inotify-errors.patch ++++++ >From 1110dbb7c1a179558db72daaa099a8c23a2a1351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20P=C5=91cze?= <po...@protonmail.com> Date: Thu, 7 Sep 2023 01:51:10 +0200 Subject: [PATCH] Revert "v4l2: handle inotify errors" This reverts commit 07b8954dc864ab38d69fecae0b8fd2b5c6d18251. --- spa/plugins/v4l2/v4l2-udev.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/spa/plugins/v4l2/v4l2-udev.c b/spa/plugins/v4l2/v4l2-udev.c index 464acf6fca..0fdcf165ca 100644 --- a/spa/plugins/v4l2/v4l2-udev.c +++ b/spa/plugins/v4l2/v4l2-udev.c @@ -393,19 +393,6 @@ static void process_device(struct impl *impl, uint32_t action, struct udev_devic } } -static int stop_inotify(struct device *dev) -{ - struct impl *impl = dev->impl; - if (dev->notify.fd == -1) - return 0; - spa_log_info(impl->log, "stop inotify for /dev/video%u", dev->id); - spa_loop_remove_source(impl->main_loop, &dev->notify); - close(dev->notify.fd); - dev->notify.fd = -1; - return 0; -} - - static void impl_on_notify_events(struct spa_source *source) { struct device *dev = source->data; @@ -415,12 +402,7 @@ static void impl_on_notify_events(struct spa_source *source) struct inotify_event e; /* for appropriate alignment */ } buf; - if (source->rmask & (SPA_IO_ERR | SPA_IO_HUP)) { - spa_log_warn(impl->log, "notify error on /dev/video%u", dev->id); - stop_inotify(dev); - return; - } - while (source->rmask & SPA_IO_IN) { + while (true) { ssize_t len; const struct inotify_event *event; void *p, *e; @@ -487,6 +469,18 @@ static int start_inotify(struct device *dev) return 0; } +static int stop_inotify(struct device *dev) +{ + struct impl *impl = dev->impl; + if (dev->notify.fd == -1) + return 0; + spa_log_info(impl->log, "stop inotify for /dev/video%u", dev->id); + spa_loop_remove_source(impl->main_loop, &dev->notify); + close(dev->notify.fd); + dev->notify.fd = -1; + return 0; +} + static void impl_on_fd_events(struct spa_source *source) { struct impl *impl = source->data; -- GitLab ++++++ 0001-pulse-server-allow-monitors-when-selecting-source-by-index.patch ++++++ >From 89fab13c77ba35fd617bd77afd29d373e9fbab4d Mon Sep 17 00:00:00 2001 From: Wim Taymans <wtaym...@redhat.com> Date: Wed, 30 Aug 2023 09:59:37 +0200 Subject: [PATCH] pulse-server: allow monitors when selecting source by index Fixes #3476 --- src/modules/module-protocol-pulse/pulse-server.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index 09e4a8d2ee..593f47da56 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -2505,8 +2505,12 @@ static struct pw_manager_object *find_device(struct client *client, allow_monitor = true; } } - } else if (index == SPA_ID_INVALID) + } else if (index != SPA_ID_INVALID) { + if (!sink) + allow_monitor = true; + } else { return NULL; + } spa_zero(sel); -- GitLab ++++++ 0002-Revert-v4l2-dont-set-inotify-on-_dev.patch ++++++ ++++ 612 lines (skipped) ++++++ 0003-spa-v4l2-use-a-separate-watch-for-each-device.patch ++++++ >From 3bbccccd05e65fd0c5e6196343fa3a18f1484c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20P=C5=91cze?= <po...@protonmail.com> Date: Thu, 7 Sep 2023 02:10:04 +0200 Subject: [PATCH] spa: v4l2: use a separate watch for each device Instead of watching /dev, use a separate watch for each device. This is supposed to achieve the same result as the now reverted 88f0dbd6fcd0a412fc4bece22afdc3ba0151e4cf ("v4l2: don't set inotify on /dev"): Doing inotify on /dev is not a good idea because we will be woken up by a lot of unrelated events. There is a report of a performance regression on some IO benchmark because of lock contention within the fsnotify subsystem due to this. Instead, just watch for attribute changes on the /dev/videoX files directly. We are only interested in attribute changes, udev should notify us when the file is added or removed. Fixes #3439 --- spa/plugins/v4l2/v4l2-udev.c | 85 +++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/spa/plugins/v4l2/v4l2-udev.c b/spa/plugins/v4l2/v4l2-udev.c index 3c2504dcb6..e1c844ba53 100644 --- a/spa/plugins/v4l2/v4l2-udev.c +++ b/spa/plugins/v4l2/v4l2-udev.c @@ -35,6 +35,7 @@ struct device { uint32_t id; struct udev_device *dev; + int inotify_wd; unsigned int accessible:1; unsigned int ignored:1; unsigned int emitted:1; @@ -80,6 +81,28 @@ static int impl_udev_close(struct impl *this) return 0; } +static void start_watching_device(struct impl *this, struct device *device) +{ + if (this->notify.fd < 0 || device->inotify_wd >= 0) + return; + + char path[64]; + snprintf(path, sizeof(path), "/dev/video%" PRIu32, device->id); + + device->inotify_wd = inotify_add_watch(this->notify.fd, path, IN_ATTRIB); +} + +static void stop_watching_device(struct impl *this, struct device *device) +{ + if (device->inotify_wd < 0) + return; + + spa_assert(this->notify.fd >= 0); + + inotify_rm_watch(this->notify.fd, device->inotify_wd); + device->inotify_wd = -1; +} + static struct device *add_device(struct impl *this, uint32_t id, struct udev_device *dev) { struct device *device; @@ -91,6 +114,10 @@ static struct device *add_device(struct impl *this, uint32_t id, struct udev_dev device->id = id; udev_device_ref(dev); device->dev = dev; + device->inotify_wd = -1; + + start_watching_device(this, device); + return device; } @@ -106,16 +133,15 @@ static struct device *find_device(struct impl *this, uint32_t id) static void remove_device(struct impl *this, struct device *device) { - udev_device_unref(device->dev); + device->dev = udev_device_unref(device->dev); + stop_watching_device(this, device); *device = this->devices[--this->n_devices]; } static void clear_devices(struct impl *this) { - uint32_t i; - for (i = 0; i < this->n_devices; i++) - udev_device_unref(this->devices[i].dev); - this->n_devices = 0; + while (this->n_devices > 0) + remove_device(this, &this->devices[0]); } static uint32_t get_device_id(struct impl *this, struct udev_device *dev) @@ -381,6 +407,10 @@ static int stop_inotify(struct impl *this) if (this->notify.fd == -1) return 0; spa_log_info(this->log, "stop inotify"); + + for (size_t i = 0; i < this->n_devices; i++) + stop_watching_device(this, &this->devices[i]); + spa_loop_remove_source(this->main_loop, &this->notify); close(this->notify.fd); this->notify.fd = -1; @@ -389,7 +419,6 @@ static int stop_inotify(struct impl *this) static void impl_on_notify_events(struct spa_source *source) { - bool deleted = false; struct impl *this = source->data; union { unsigned char name[sizeof(struct inotify_event) + NAME_MAX + 1]; @@ -411,35 +440,33 @@ static void impl_on_notify_events(struct spa_source *source) for (p = &buf; p < e; p = SPA_PTROFF(p, sizeof(struct inotify_event) + event->len, void)) { - unsigned int id; - struct device *device; - event = (const struct inotify_event *) p; if ((event->mask & IN_ATTRIB)) { - bool access; - if (sscanf(event->name, "video%u", &id) != 1) - continue; - if ((device = find_device(this, id)) == NULL) - continue; - access = check_access(this, device); + struct device *device = NULL; + + for (size_t i = 0; i < this->n_devices; i++) { + if (this->devices[i].inotify_wd == event->wd) { + device = &this->devices[i]; + break; + } + } + + spa_assert(device); + + bool access = check_access(this, device); if (access && !device->emitted) process_device(this, ACTION_ADD, device->dev); else if (!access && device->emitted) process_device(this, ACTION_DISABLE, device->dev); } - /* /dev/ might have been removed */ - if ((event->mask & (IN_DELETE_SELF | IN_MOVE_SELF))) - deleted = true; } } - if (deleted) - stop_inotify(this); } static int start_inotify(struct impl *this) { - int res, notify_fd; + int notify_fd; if (this->notify.fd != -1) return 0; @@ -447,19 +474,6 @@ static int start_inotify(struct impl *this) if ((notify_fd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK)) < 0) return -errno; - res = inotify_add_watch(notify_fd, "/dev", - IN_ATTRIB | IN_CLOSE_WRITE | IN_DELETE_SELF | IN_MOVE_SELF); - if (res < 0) { - res = -errno; - close(notify_fd); - - if (res == -ENOENT) { - spa_log_debug(this->log, "/dev/ does not exist yet"); - return 0; - } - spa_log_error(this->log, "inotify_add_watch() failed: %s", spa_strerror(res)); - return res; - } spa_log_info(this->log, "start inotify"); this->notify.func = impl_on_notify_events; this->notify.data = this; @@ -468,6 +482,9 @@ static int start_inotify(struct impl *this) spa_loop_add_source(this->main_loop, &this->notify); + for (size_t i = 0; i < this->n_devices; i++) + start_watching_device(this, &this->devices[i]); + return 0; } -- GitLab