v2:
The main change in this version is Bjorn's pointing out that pm_runtime_*
inside of the gdsc_enable/gdsc_disable path would be recursive and cause a
lockdep splat. Dmitry alluded to this too.
Bjorn pointed to stuff being done lower in the gdsc_register() routine that
might be a starting point.
I iterated around that idea and came up with patch #3. When a gdsc has no
parent and the pd_list is non-NULL then attach that orphan GDSC to the
clock controller power-domain list.
Existing subdomain code in gdsc_register() will connect the parent GDSCs in
the clock-controller to the clock-controller subdomain, the new code here
does that same job for a list of power-domains the clock controller depends
on.
To Dmitry's point about MMCX and MCX dependencies for the registers inside
of the clock controller, I have switched off all references in a test dtsi
and confirmed that accessing the clock-controller regs themselves isn't
required.
On the second point I also verified my test branch with lockdep on which
was a concern with the pm_domain version of this solution but I wanted to
cover it anyway with the new approach for completeness sake.
Here's the item-by-item list of changes:
- Adds a patch to capture pm_genpd_add_subdomain() result code - Bryan
- Changes changelog of second patch to remove singleton and generally
to make the commit log easier to understand - Bjorn
- Uses demv_pm_domain_attach_list - Vlad
- Changes error check to if (ret < 0 && ret != -EEXIST) - Vlad
- Retains passing &pd_data instead of NULL - because NULL doesn't do
the same thing - Bryan/Vlad
- Retains standalone function qcom_cc_pds_attach() because the pd_data
enumeration looks neater in a standalone function - Bryan/Vlad
- Drops pm_runtime in favour of gdsc_add_subdomain_list() for each
power-domain in the pd_list.
The pd_list will be whatever is pointed to by power-domains = <>
in the dtsi - Bjorn
- Link to v1: https://lore.kernel.org/r/20241118-b4-linux-next-24-11-18-clock-multiple-po…
v1:
On x1e80100 and it's SKUs the Camera Clock Controller - CAMCC has
multiple power-domains which power it. Usually with a single power-domain
the core platform code will automatically switch on the singleton
power-domain for you. If you have multiple power-domains for a device, in
this case the clock controller, you need to switch those power-domains
on/off yourself.
The clock controllers can also contain Global Distributed
Switch Controllers - GDSCs which themselves can be referenced from dtsi
nodes ultimately triggering a gdsc_en() in drivers/clk/qcom/gdsc.c.
As an example:
cci0: cci@ac4a000 {
power-domains = <&camcc TITAN_TOP_GDSC>;
};
This series adds the support to attach a power-domain list to the
clock-controllers and the GDSCs those controllers provide so that in the
case of the above example gdsc_toggle_logic() will trigger the power-domain
list with pm_runtime_resume_and_get() and pm_runtime_put_sync()
respectively.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue(a)linaro.org>
---
Bryan O'Donoghue (3):
clk: qcom: gdsc: Capture pm_genpd_add_subdomain result code
clk: qcom: common: Add support for power-domain attachment
driver: clk: qcom: Support attaching subdomain list to multiple parents
drivers/clk/qcom/common.c | 21 +++++++++++++++++++++
drivers/clk/qcom/gdsc.c | 41 +++++++++++++++++++++++++++++++++++++++--
drivers/clk/qcom/gdsc.h | 1 +
3 files changed, 61 insertions(+), 2 deletions(-)
---
base-commit: 744cf71b8bdfcdd77aaf58395e068b7457634b2c
change-id: 20241118-b4-linux-next-24-11-18-clock-multiple-power-domains-a5f994dc452a
Best regards,
--
Bryan O'Donoghue <bryan.odonoghue(a)linaro.org>
[BUG]
Btrfs will fail generic/750 randomly if its sector size is smaller than
page size.
One of the warning looks like this:
------------[ cut here ]------------
WARNING: CPU: 1 PID: 90263 at fs/btrfs/ordered-data.c:360 can_finish_ordered_extent+0x33c/0x390 [btrfs]
CPU: 1 UID: 0 PID: 90263 Comm: kworker/u18:1 Tainted: G OE 6.12.0-rc3-custom+ #79
Workqueue: events_unbound btrfs_async_reclaim_metadata_space [btrfs]
pc : can_finish_ordered_extent+0x33c/0x390 [btrfs]
lr : can_finish_ordered_extent+0xdc/0x390 [btrfs]
Call trace:
can_finish_ordered_extent+0x33c/0x390 [btrfs]
btrfs_mark_ordered_io_finished+0x130/0x2b8 [btrfs]
extent_writepage+0xfc/0x338 [btrfs]
extent_write_cache_pages+0x1d4/0x4b8 [btrfs]
btrfs_writepages+0x94/0x158 [btrfs]
do_writepages+0x74/0x190
filemap_fdatawrite_wbc+0x88/0xc8
start_delalloc_inodes+0x180/0x3b0 [btrfs]
btrfs_start_delalloc_roots+0x17c/0x288 [btrfs]
shrink_delalloc+0x11c/0x280 [btrfs]
flush_space+0x27c/0x310 [btrfs]
btrfs_async_reclaim_metadata_space+0xcc/0x208 [btrfs]
process_one_work+0x228/0x670
worker_thread+0x1bc/0x360
kthread+0x100/0x118
ret_from_fork+0x10/0x20
irq event stamp: 9784200
hardirqs last enabled at (9784199): [<ffffd21ec54dc01c>] _raw_spin_unlock_irqrestore+0x74/0x80
hardirqs last disabled at (9784200): [<ffffd21ec54db374>] _raw_spin_lock_irqsave+0x8c/0xa0
softirqs last enabled at (9784148): [<ffffd21ec472ff44>] handle_softirqs+0x45c/0x4b0
softirqs last disabled at (9784141): [<ffffd21ec46d01e4>] __do_softirq+0x1c/0x28
---[ end trace 0000000000000000 ]---
BTRFS critical (device dm-2): bad ordered extent accounting, root=5 ino=1492 OE offset=1654784 OE len=57344 to_dec=49152 left=0
[CAUSE]
There are several error paths not properly handling during folio
writeback:
1) Partially submitted folio
During extent_writepage_io() if some error happened (the only
possible case is submit_one_sector() failed to grab an extent map),
then we can have partially submitted folio.
Since extent_writepage_io() failed, we need to call
btrfs_mark_ordered_io_finished() to cleanup the submitted range.
But we will call btrfs_mark_ordered_io_finished() for submitted range
too, causing double accounting.
2) Partially created ordered extents
We cal also fail at writepage_delalloc(), which will stop creating
new ordered extents if it hit any error from
btrfs_run_delalloc_range().
In that case, we will call btrfs_mark_ordered_io_finished() for
ranges where there is no ordered extent at all.
Both bugs are only affecting sector size < page size cases.
[FIX]
- Introduce a new member btrfs_bio_ctrl::last_submitted
This will trace the last sector submitted through
extent_writepage_io().
So for the above extent_writepage() case, we will know exactly which
sectors are submitted and should not do the ordered extent accounting.
- Clear the submit_bitmap for ranges where no ordered extent is created
So if btrfs_run_delalloc_range() failed for a range, it will be not
cleaned up.
- Introduce a helper cleanup_ordered_extents()
This will do a sector-by-sector cleanup with
btrfs_bio_ctrl::last_submitted and btrfs_bio_ctrl::submit_bitmap into
consideartion.
Using @last_submitted is to avoid double accounting on the submitted
ranges.
Meanwhile using @submit_bitmap is to avoid touching ranges going
through compression.
cc: stable(a)vger.kernel.org # 5.15+
Signed-off-by: Qu Wenruo <wqu(a)suse.com>
---
fs/btrfs/extent_io.c | 54 ++++++++++++++++++++++++++++++++++++++------
1 file changed, 47 insertions(+), 7 deletions(-)
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index e629d2ee152a..1c2246d36672 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -108,6 +108,14 @@ struct btrfs_bio_ctrl {
* This is to avoid touching ranges covered by compression/inline.
*/
unsigned long submit_bitmap;
+
+ /*
+ * The end (exclusive) of the last submitted range in the folio.
+ *
+ * This is for sector size < page size case where we may hit error
+ * half way.
+ */
+ u64 last_submitted;
};
static void submit_one_bio(struct btrfs_bio_ctrl *bio_ctrl)
@@ -1254,11 +1262,18 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
/*
* We have some ranges that's going to be submitted asynchronously
- * (compression or inline). These range have their own control
+ * (compression or inline, ret > 0). These range have their own control
* on when to unlock the pages. We should not touch them
- * anymore, so clear the range from the submission bitmap.
+ * anymore.
+ *
+ * We can also have some ranges where we didn't even call
+ * btrfs_run_delalloc_range() (as previous run failed, ret < 0).
+ * These error ranges should not be submitted nor cleaned up as
+ * there is no ordered extent allocated for them.
+ *
+ * For either cases, we should clear the submit_bitmap.
*/
- if (ret > 0) {
+ if (ret) {
unsigned int start_bit = (found_start - page_start) >>
fs_info->sectorsize_bits;
unsigned int end_bit = (min(page_end + 1, found_start + found_len) -
@@ -1435,6 +1450,7 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,
ret = submit_one_sector(inode, folio, cur, bio_ctrl, i_size);
if (ret < 0)
goto out;
+ bio_ctrl->last_submitted = cur + fs_info->sectorsize;
submitted_io = true;
}
out:
@@ -1453,6 +1469,24 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,
return ret;
}
+static void cleanup_ordered_extents(struct btrfs_inode *inode,
+ struct folio *folio, u64 file_pos,
+ u64 num_bytes, unsigned long *bitmap)
+{
+ struct btrfs_fs_info *fs_info = inode->root->fs_info;
+ unsigned int cur_bit = (file_pos - folio_pos(folio)) >> fs_info->sectorsize_bits;
+
+ for_each_set_bit_from(cur_bit, bitmap, fs_info->sectors_per_page) {
+ u64 cur_pos = folio_pos(folio) + (cur_bit << fs_info->sectorsize_bits);
+
+ if (cur_pos >= file_pos + num_bytes)
+ break;
+
+ btrfs_mark_ordered_io_finished(inode, folio, cur_pos,
+ fs_info->sectorsize, false);
+ }
+}
+
/*
* the writepage semantics are similar to regular writepage. extent
* records are inserted to lock ranges in the tree, and as dirty areas
@@ -1492,6 +1526,7 @@ static int extent_writepage(struct folio *folio, struct btrfs_bio_ctrl *bio_ctrl
* The proper bitmap can only be initialized until writepage_delalloc().
*/
bio_ctrl->submit_bitmap = (unsigned long)-1;
+ bio_ctrl->last_submitted = page_start;
ret = set_folio_extent_mapped(folio);
if (ret < 0)
goto done;
@@ -1511,8 +1546,10 @@ static int extent_writepage(struct folio *folio, struct btrfs_bio_ctrl *bio_ctrl
done:
if (ret) {
- btrfs_mark_ordered_io_finished(BTRFS_I(inode), folio,
- page_start, PAGE_SIZE, !ret);
+ cleanup_ordered_extents(BTRFS_I(inode), folio,
+ bio_ctrl->last_submitted,
+ page_start + PAGE_SIZE - bio_ctrl->last_submitted,
+ &bio_ctrl->submit_bitmap);
mapping_set_error(folio->mapping, ret);
}
@@ -2288,14 +2325,17 @@ void extent_write_locked_range(struct inode *inode, const struct folio *locked_f
* extent_writepage_io() will do the truncation correctly.
*/
bio_ctrl.submit_bitmap = (unsigned long)-1;
+ bio_ctrl.last_submitted = cur;
ret = extent_writepage_io(BTRFS_I(inode), folio, cur, cur_len,
&bio_ctrl, i_size);
if (ret == 1)
goto next_page;
if (ret) {
- btrfs_mark_ordered_io_finished(BTRFS_I(inode), folio,
- cur, cur_len, !ret);
+ cleanup_ordered_extents(BTRFS_I(inode), folio,
+ bio_ctrl.last_submitted,
+ cur_end + 1 - bio_ctrl.last_submitted,
+ &bio_ctrl.submit_bitmap);
mapping_set_error(mapping, ret);
}
btrfs_folio_end_lock(fs_info, folio, cur, cur_len);
--
2.47.0
If:
1) the user requested USO, but
2) there is not enough payload for GSO to kick in, and
3) the egress device doesn't offer checksum offload, then
we want to compute the L4 checksum in software early on.
In the case when we are not taking the GSO path, but it has been requested,
the software checksum fallback in skb_segment doesn't get a chance to
compute the full checksum, if the egress device can't do it. As a result we
end up sending UDP datagrams with only a partial checksum filled in, which
the peer will discard.
Fixes: 10154dbded6d ("udp: Allow GSO transmit from devices with no checksum offload")
Reported-by: Ivan Babrou <ivan(a)cloudflare.com>
Signed-off-by: Jakub Sitnicki <jakub(a)cloudflare.com>
Acked-by: Willem de Bruijn <willemdebruijn.kernel(a)gmail.com>
Cc: stable(a)vger.kernel.org
---
Changes in v2:
- Fix typo in patch description
- Link to v1: https://lore.kernel.org/r/20241010-uso-swcsum-fixup-v1-1-a63fbd0a414c@cloud…
---
net/ipv4/udp.c | 4 +++-
net/ipv6/udp.c | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 8accbf4cb295..2849b273b131 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -951,8 +951,10 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4,
skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4;
skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(datalen,
cork->gso_size);
+
+ /* Don't checksum the payload, skb will get segmented */
+ goto csum_partial;
}
- goto csum_partial;
}
if (is_udplite) /* UDP-Lite */
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 52dfbb2ff1a8..0cef8ae5d1ea 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1266,8 +1266,10 @@ static int udp_v6_send_skb(struct sk_buff *skb, struct flowi6 *fl6,
skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4;
skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(datalen,
cork->gso_size);
+
+ /* Don't checksum the payload, skb will get segmented */
+ goto csum_partial;
}
- goto csum_partial;
}
if (is_udplite)
From: Dave Stevenson <dave.stevenson(a)raspberrypi.com>
[ Upstream commit 014eccc9da7bfc76a3107fceea37dd60f1d63630 ]
The HVS can change AXI request mode based on how full the COB
FIFOs are.
Until now the vc4 driver has been relying on the firmware to
have set these to sensible values.
With HVS channel 2 now being used for live video, change the
panic mode for all channels to be explicitly set by the driver,
and the same for all channels.
Reviewed-by: Maxime Ripard <mripard(a)kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-7-dave…
Signed-off-by: Dave Stevenson <dave.stevenson(a)raspberrypi.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
drivers/gpu/drm/vc4/vc4_hvs.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index f8f2fc3d15f73..64a02e29b7cb1 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -688,6 +688,17 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1);
dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
+ /* Set AXI panic mode.
+ * VC4 panics when < 2 lines in FIFO.
+ * VC5 panics when less than 1 line in the FIFO.
+ */
+ dispctrl &= ~(SCALER_DISPCTRL_PANIC0_MASK |
+ SCALER_DISPCTRL_PANIC1_MASK |
+ SCALER_DISPCTRL_PANIC2_MASK);
+ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC0);
+ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1);
+ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
+
HVS_WRITE(SCALER_DISPCTRL, dispctrl);
ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
--
2.43.0
From: Dave Stevenson <dave.stevenson(a)raspberrypi.com>
[ Upstream commit 014eccc9da7bfc76a3107fceea37dd60f1d63630 ]
The HVS can change AXI request mode based on how full the COB
FIFOs are.
Until now the vc4 driver has been relying on the firmware to
have set these to sensible values.
With HVS channel 2 now being used for live video, change the
panic mode for all channels to be explicitly set by the driver,
and the same for all channels.
Reviewed-by: Maxime Ripard <mripard(a)kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-7-dave…
Signed-off-by: Dave Stevenson <dave.stevenson(a)raspberrypi.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
drivers/gpu/drm/vc4/vc4_hvs.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 3856ac289d380..69b2936a5f4ad 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -729,6 +729,17 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1);
dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
+ /* Set AXI panic mode.
+ * VC4 panics when < 2 lines in FIFO.
+ * VC5 panics when less than 1 line in the FIFO.
+ */
+ dispctrl &= ~(SCALER_DISPCTRL_PANIC0_MASK |
+ SCALER_DISPCTRL_PANIC1_MASK |
+ SCALER_DISPCTRL_PANIC2_MASK);
+ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC0);
+ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1);
+ dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
+
HVS_WRITE(SCALER_DISPCTRL, dispctrl);
ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
--
2.43.0
From: Dom Cobley <popcornmix(a)gmail.com>
[ Upstream commit b4e5646178e86665f5caef2894578600f597098a ]
We regularly get dmesg error reports of:
[ 18.184066] hdmi-audio-codec hdmi-audio-codec.3.auto: ASoC: error at snd_soc_dai_startup on i2s-hifi: -19
[ 18.184098] MAI: soc_pcm_open() failed (-19)
These are generated for any disconnected hdmi interface when pulseaudio
attempts to open the associated ALSA device (numerous times). Each open
generates a kernel error message, generating general log spam.
The error messages all come from _soc_pcm_ret in sound/soc/soc-pcm.c#L39
which suggests returning ENOTSUPP, rather that ENODEV will be quiet.
And indeed it is.
Signed-off-by: Dom Cobley <popcornmix(a)gmail.com>
Reviewed-by: Maxime Ripard <mripard(a)kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240621152055.4180873-5-dave…
Signed-off-by: Dave Stevenson <dave.stevenson(a)raspberrypi.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index c6e986f71a26f..7cabfa1b883d2 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -2392,7 +2392,7 @@ static int vc4_hdmi_audio_startup(struct device *dev, void *data)
}
if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) {
- ret = -ENODEV;
+ ret = -ENOTSUPP;
goto out_dev_exit;
}
--
2.43.0