Linux Documentation
 help / color / mirror / Atom feed
* Re: Invalid link generation for equations
From: Shuah Khan @ 2026-03-25 20:40 UTC (permalink / raw)
  To: Jonathan Corbet, Kevin Brodsky, linux-doc
  Cc: Konstantin Ryabitsev, Mauro Carvalho Chehab, Shuah Khan
In-Reply-To: <87se9nejza.fsf@trenco.lwn.net>

On 3/25/26 14:23, Jonathan Corbet wrote:
> [Adding Konstantin and Mauro, in case anybody has any thoughts...]
> 
> Kevin Brodsky <kevin.brodsky@arm.com> writes:
> 
>> Hi,
>>
>> I have noticed that links to equation images are not generated correctly
>> on docs.kernel.org. For instance, Documentation/mm/memory-model.rst has:
>>
>>      .. math::
>>      
>>         NR\_MEM\_SECTIONS = 2 ^ {(MAX\_PHYSMEM\_BITS - SECTION\_SIZE\_BITS)}
>>
>> The generated HTML [1] shows the source code instead of the rendered
>> equation because the link to the image [2] is broken. [3] does however
>> exist. The issue seems to be that the link is relative to the root, even
>> though we are in a subfolder (mm/ here).
>>
>> Given my non-existent knowledge of Sphinx I have no idea what the fix
>> might be, but I thought I'd report this at least :)
>>
>> - Kevin
>>
>> [1] https://docs.kernel.org/mm/memory-model.html#sparsemem
>> [2]
>> https://docs.kernel.org/mm/_images/math/d99368220bfdedf1a888b1c09eb7236a8c87d079.png
>> [3]
>> https://docs.kernel.org/_images/math/d99368220bfdedf1a888b1c09eb7236a8c87d079.png
> 
> OK, so this is more than passing strange...I can't reproduce that
> problem locally.  The HTML I get is:
> 
>    <img src="../_images/math/d9936822[...]
> 
> On docs.kernel.org, instead:
> 
>    <img src="_images/math/d9936822[...]
> 
> Note the missing "../".
> 
> I will confess that I don't have a great understanding of how imgmath
> works and how that link gets set.  We could "fix" the problem generally
> by setting imgmath_embed=True, but it would be good to understand what's
> actually happening here.

Respect SPHINX_IMGMATH (for html docs only) in Documentation/conf.py
might explain why imgmath_embed=True works?

# Load math renderer:
# For html builder, load imgmath only when its dependencies are met.
# mathjax is the default math renderer since Sphinx 1.8.
have_latex = have_command("latex")
have_dvipng = have_command("dvipng")
load_imgmath = have_latex and have_dvipng

Without setting imgmath_embed=true, math_renderer is mathjax which is
default since Sphinx 1.8

This is based on quick read - I can look into it some more.

thanks,
-- Shuah

^ permalink raw reply

* Re: [PATCH 1/1] leds: Introduce the multi_max_intensity sysfs attribute
From: Jacek Anaszewski @ 2026-03-25 20:41 UTC (permalink / raw)
  To: Armin Wolf, lee, pavel
  Cc: linux-kernel, corbet, skhan, linux-leds, linux-doc, wse, pobrn,
	m.tretter
In-Reply-To: <20260324202751.6486-2-W_Armin@gmx.de>

Hi Armin,

Thanks for the update.

On 3/24/26 9:27 PM, Armin Wolf wrote:
> Some multicolor LEDs support global brightness control in hardware,
> meaning that the maximum intensity of the color components is not
> connected to the maximum global brightness. Such LEDs cannot be
> described properly by the current multicolor LED class interface,
> because it assumes that the maximum intensity of each color component
> is described by the maximum global brightness of the LED.
> 
> Fix this by introducing a new sysfs attribute called
> "multi_max_intensity" holding the maximum intensity values for the
> color components of a multicolor LED class device. Drivers can use
> the new max_intensity field inside struct mc_subled to tell the
> multicolor LED class code about those values. Intensity values written
> by userspace applications will be limited to this maximum value.
> 
> Drivers for multicolor LEDs that do not support global brightness
> control in hardware might still want to use the maximum global LED
> brightness supplied via devicetree as the maximum intensity of each
> individual color component. Such drivers should set max_intensity
> to 0 so that the multicolor LED core can act accordingly.
> 
> The lp50xx and ncp5623 LED drivers already use hardware-based control
> for the global LED brightness. Modify those drivers to correctly
> initalize .max_intensity to avoid being limited to the maximum global
> brightness supplied via devicetree.
> 
> Signed-off-by: Armin Wolf <W_Armin@gmx.de>
> ---
>   .../ABI/testing/sysfs-class-led-multicolor    | 19 ++++++--
>   Documentation/leds/leds-class-multicolor.rst  | 21 ++++++++-
>   drivers/leds/led-class-multicolor.c           | 47 ++++++++++++++++++-
>   drivers/leds/leds-lp50xx.c                    |  1 +
>   drivers/leds/rgb/leds-ncp5623.c               |  4 +-
>   include/linux/led-class-multicolor.h          | 30 +++++++++++-
>   6 files changed, 113 insertions(+), 9 deletions(-)
Reviewed-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>

-- 
Best regards,
Jacek Anaszewski


^ permalink raw reply

* Re: kernel-doc overly verbose with V=0
From: Jacob Keller @ 2026-03-25 20:42 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Jonathan Corbet, Linux Doc Mailing List, Shuah Khan, Randy Dunlap,
	linux-kernel@vger.kernel.org
In-Reply-To: <20260325125020.533f2042@localhost>

On 3/25/2026 4:50 AM, Mauro Carvalho Chehab wrote:
> On Tue, 24 Mar 2026 13:37:39 -0700
> Jacob Keller <jacob.e.keller@intel.com> wrote:
> 
>> Hi,
>>
>> I recently saw some strange behavior with the Python kernel-doc. I was
>> seeing the verbose info lines from the kernel-doc script, i.e.:
>>
>>> Info: ice_ptp_hw.c:5377 Scanning doc for function ice_cgu_get_pin_freq_supp
>>> Info: ice_ptp_hw.c:5406 Scanning doc for function ice_cgu_get_pin_name
>>> Info: ice_ptp_hw.c:5441 Scanning doc for function ice_cgu_state_to_name
>>> Info: ice_ptp_hw.c:5463 Scanning doc for function ice_get_dpll_ref_sw_status
>>> Info: ice_ptp_hw.c:5505 Scanning doc for function ice_set_dpll_ref_sw_status
>>> Info: ice_ptp_hw.c:5544 Scanning doc for function ice_get_cgu_state
>>> Info: ice_ptp_hw.c:5612 Scanning doc for function ice_get_cgu_rclk_pin_info
>>> Info: ice_ptp_hw.c:5671 Scanning doc for function ice_cgu_get_output_pin_state_caps
>>> Info: ice_ptp_hw.c:5733 Scanning doc for function ice_ptp_lock
>>> Info: ice_ptp_hw.c:5770 Scanning doc for function ice_ptp_unlock
>>> Info: ice_ptp_hw.c:5782 Scanning doc for function ice_ptp_init_hw
>>> Info: ice_ptp_hw.c:5811 Scanning doc for function ice_ptp_write_port_cmd
>>> Info: ice_ptp_hw.c:5834 Scanning doc for function ice_ptp_one_port_cmd
>>> Info: ice_ptp_hw.c:5866 Scanning doc for function ice_ptp_port_cmd
>>> Info: ice_ptp_hw.c:5901 Scanning doc for function ice_ptp_tmr_cmd
>>> Info: ice_ptp_hw.c:5934 Scanning doc for function ice_ptp_init_time
>>> Info: ice_ptp_hw.c:5986 Scanning doc for function ice_ptp_write_incval
>>> Info: ice_ptp_hw.c:6035 Scanning doc for function ice_ptp_write_incval_locked
>>> Info: ice_ptp_hw.c:6056 Scanning doc for function ice_ptp_adj_clock
>>> Info: ice_ptp_hw.c:6107 Scanning doc for function ice_read_phy_tstamp
>>> Info: ice_ptp_hw.c:6134 Scanning doc for function ice_clear_phy_tstamp
>>> Info: ice_ptp_hw.c:6164 Scanning doc for function ice_ptp_reset_ts_memory
>>> Info: ice_ptp_hw.c:6183 Scanning doc for function ice_ptp_init_phc
>>> Info: ice_ptp_hw.c:6215 Scanning doc for function ice_get_phy_tx_tstamp_ready
>>> Info: ice_ptp_hw.c:6247 Scanning doc for function ice_check_phy_tx_tstamp_ready
>>> Info: ice_ptp_hw.c:6273 Scanning doc for function ice_ptp_config_sfd
>>> Info: ice_ptp_hw.c:6293 Scanning doc for function refsync_pin_id_valid  
>>
>> I didn't understand why I was seeing this as it should only be happening
>> if running kernel-doc in verbose mode. Then I discovered I had set
>> KBUILD_VERBOSE=0 in my environment.
>>
>> The python kernel-doc implementation reads this in the __init__ for
>> KernelFiles() on line 165:
>>
>>>         if not verbose:
>>>             verbose = bool(os.environ.get("KBUILD_VERBOSE", 0))  
>>
>> After some debugging, I realized this reads KBUILD_VERBOSE as a string,
>> then converts it to a boolean using python's standard rules, so "0"
>> becomes true, which enables the verbose output.
> 
> Looking at tools/docs/sphinx-build-wrapper, it implements verbosity
> by doing:
> 
> 	verbose = bool(os.environ.get("KBUILD_VERBOSE", "") != "")
> 
> which will also have the same problem as the one you detected.
> 

Yep.

> Perhaps the right fix would be to first convert to int then to bool
> on both places, in a way that "" will also be handled properly.
> Perhaps with:
> 
> 	try:
> 	    verbose = bool(int(os.environ.get("KBUILD_VERBOSE", 0)))
> 	except ValueError:
> 	    # Handles an eventual case where verbosity is not a number
> 	    # like KBUILD_VERBOSE=""
> 	    verbose = False
> >> This is in contrast to the (now removed) kernel-doc.pl script which
>> checked the value for a 1:
>>
>>>  if (defined($ENV{'KBUILD_VERBOSE'}) && $ENV{'KBUILD_VERBOSE'} =~ '1')   
>> The same behavior happens if you assign V=0 on the command line or to
>> any other non-empty string, since when V is set on the command line it
>> sets KBUILD_VERBOSE.
> 
> That's funny... we did test make V=0 htmldocs / make V=1 htmldocs 
> 

Strange. The Makefile does this:

ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif

I can see KBUILD_VERBOSE=0 from the top level Makefile, but you're right
it doesn't seem to trigger the environment variable..

> It sounds that the problem is only if you explicitly set it without
> relying on gnu make.
> 

Adding some warn prints I do see the Makefile sets KBUILD_VERBOSE=0 when
you do V=0.. and it has an export clause for KBUILD_VERBOSE

Oh, it might be your particular build doesn't have W=1 so checkdoc isn't
being defined and thus kernel-doc isn't running?

If I do "make W=1 V=0" I do actually see these lines:

> Info: ../drivers/pci/pci.c:3646 Scanning doc for function pci_acs_init
> Info: ../drivers/pci/pci.c:3663 Scanning doc for function pci_enable_atomic_ops_to_root
> Info: ../drivers/pci/pci.c:3746 Scanning doc for function pci_release_region
> Info: ../drivers/pci/pci.c:3772 Scanning doc for function __pci_request_region
> Info: ../drivers/pci/pci.c:3820 Scanning doc for function pci_request_region
> Info: ../drivers/pci/pci.c:3841 Scanning doc for function pci_release_selected_regions
> Info: ../drivers/pci/pci.c:3879 Scanning doc for function pci_request_selected_regions
> Info: ../drivers/pci/pci.c:3894 Scanning doc for function pci_request_selected_regions_exclusive
> Info: ../drivers/pci/pci.c:3910 Scanning doc for function pci_release_regions
> Info: ../drivers/pci/pci.c:3925 Scanning doc for function pci_request_regions
> Info: ../drivers/pci/pci.c:3944 Scanning doc for function pci_request_regions_exclusive
> Info: ../drivers/pci/pci.c:4026 Scanning doc for function pci_remap_iospace
> Info: ../drivers/pci/pci.c:4062 Scanning doc for function pci_unmap_iospace
> Info: ../drivers/pci/pci.c:4097 Scanning doc for function pcibios_setup
> Info: ../drivers/pci/pci.c:4109 Scanning doc for function pcibios_set_master
> Info: ../drivers/pci/pci.c:4136 Scanning doc for function pci_set_master
> Info: ../drivers/pci/pci.c:4150 Scanning doc for function pci_clear_master
> Info: ../drivers/pci/pci.c:4160 Scanning doc for function pci_set_cacheline_size
> Info: ../drivers/pci/pci.c:4198 Scanning doc for function pci_set_mwi
> Info: ../drivers/pci/pci.c:4229 Scanning doc for function pci_try_set_mwi
> Info: ../drivers/pci/pci.c:4248 Scanning doc for function pci_clear_mwi
> Info: ../drivers/pci/pci.c:4268 Scanning doc for function pci_disable_parity
> Info: ../drivers/pci/pci.c:4285 Scanning doc for function pci_intx
> Info: ../drivers/pci/pci.c:4310 Scanning doc for function pci_wait_for_pending_transaction
> Info: ../drivers/pci/pci.c:4326 Scanning doc for function pcie_flr
> Info: ../drivers/pci/pci.c:4366 Scanning doc for function pcie_reset_flr
> Info: ../drivers/pci/pci.c:4443 Scanning doc for function pci_pm_reset
> Info: ../drivers/pci/pci.c:4497 Scanning doc for function pcie_wait_for_link_status
> Info: ../drivers/pci/pci.c:4527 Scanning doc for function pcie_retrain_link
> Info: ../drivers/pci/pci.c:4592 Scanning doc for function pcie_wait_for_link_delay
> Info: ../drivers/pci/pci.c:4642 Scanning doc for function pcie_wait_for_link
> Info: ../drivers/pci/pci.c:4679 Scanning doc for function pci_bridge_wait_for_secondary_bus
> Info: ../drivers/pci/pci.c:4818 Scanning doc for function pci_bridge_secondary_bus_reset
> Info: ../drivers/pci/pci.c:5077 Scanning doc for function __pci_reset_function_locked
> Info: ../drivers/pci/pci.c:5135 Scanning doc for function pci_init_reset_methods
> Info: ../drivers/pci/pci.c:5167 Scanning doc for function pci_reset_function
> Info: ../drivers/pci/pci.c:5214 Scanning doc for function pci_reset_function_locked
> Info: ../drivers/pci/pci.c:5252 Scanning doc for function pci_try_reset_function


>> Of course, I can remove KBUILD_VERBOSE from my environment, I'm not
>> entirely sure when or why I added it.
>>
>> Would think it would make sense to update the kdoc_files.py script to
>> check and interpret the string value the same way the perl script used
>> to? It seems reasonable to me that users might set "V=0" thinking that
>> it disables the verbosity. Other verbosity checks are based on the
>> string containing a 1,
> 
> kernel-doc has a set of "-W" flags to control its verbosity. Direct
> support for KBUILD_VERBOSE was added there just to make it bug-compatible
> with kernel-doc.pl when building via Makefile.
> 

Right.

> Yet, as using it via "make htmldocs" don't use "-W", IMO it makes
> sense to ensure that "-Wall" is enabled if V=1.
> 

We enable -Wall if KBUILD_EXTRA_WARN contains a 2:

ifeq ($(KBUILD_EXTMOD),)
ifneq ($(KBUILD_EXTRA_WARN),)
  cmd_checkdoc = PYTHONDONTWRITEBYTECODE=1 $(PYTHON3) $(KERNELDOC) -none
$(KDOCFLAGS) \
        $(if $(findstring 2, $(KBUILD_EXTRA_WARN)), -Wall) \
        $<
endif
endif

If KBUILD_EXTRA_WARN has 2 we do -Wall, and if its any non-zero value we
enable checkdoc. KBUILD_VERBOSE is handled internally to the script so
not part of the Make invocation.

So V=0 only manifests if KBUILD_EXTRA_WARN is set.

We set KBUILD_EXTRA_WARN in top level:

ifeq ("$(origin W)", "command line")
  KBUILD_EXTRA_WARN := $(W)
endif

export KBUILD_EXTRA_WARN

>> (some even use 2 for even more printing).
> 
> Documentation had support for V=2, but this was dropped on this
> commit:
> 	c0d3b83100c8 ("kbuild: do not print extra logs for V=2")
> 

Looks like there's some stale leftover bits then:

#
# If KBUILD_VERBOSE contains 1, the whole command is echoed.
# If KBUILD_VERBOSE contains 2, the reason for rebuilding is printed.
#
# To put more focus on warnings, be less verbose as default
# Use 'make V=1' to see the full commands
I don't have strong opinions either way.


>> I'm not entirely sure what the best implementation for python is to
>> avoid this misinterpretation, so I haven't drafted a proper patch yet.
> 
> Perhaps something like the patch below (untested).
> 

The patch seems reasonable, though I don't know about the enabling other
errors, as those are controlled by W=2 right now. I don't personally
have objections to enabling them with V as well, but others might?

Thanks,
Jake

^ permalink raw reply

* Re: [PATCH v3] docs: contain horizontal overflow in C API descriptions
From: Rito Rhymes @ 2026-03-25 20:50 UTC (permalink / raw)
  To: Jonathan Corbet, Rito Rhymes, linux-doc; +Cc: Shuah Khan, linux-kernel, rdunlap
In-Reply-To: <87jyuzg2fi.fsf@trenco.lwn.net>

If you could imagine an optimal solution, what would it look like?
Can you describe the layout and/or behavior?

Maybe I can implement it.

Rito

^ permalink raw reply

* Re: Invalid link generation for equations
From: Jonathan Corbet @ 2026-03-25 21:11 UTC (permalink / raw)
  To: Shuah Khan, Kevin Brodsky, linux-doc
  Cc: Konstantin Ryabitsev, Mauro Carvalho Chehab, Shuah Khan
In-Reply-To: <501de93f-65f2-4a45-a84b-d38560cd9e22@linuxfoundation.org>

Shuah Khan <skhan@linuxfoundation.org> writes:

>> OK, so this is more than passing strange...I can't reproduce that
>> problem locally.  The HTML I get is:
>> 
>>    <img src="../_images/math/d9936822[...]
>> 
>> On docs.kernel.org, instead:
>> 
>>    <img src="_images/math/d9936822[...]
>> 
>> Note the missing "../".
>> 
>> I will confess that I don't have a great understanding of how imgmath
>> works and how that link gets set.  We could "fix" the problem generally
>> by setting imgmath_embed=True, but it would be good to understand what's
>> actually happening here.
>
> Respect SPHINX_IMGMATH (for html docs only) in Documentation/conf.py
> might explain why imgmath_embed=True works?
>
> # Load math renderer:
> # For html builder, load imgmath only when its dependencies are met.
> # mathjax is the default math renderer since Sphinx 1.8.
> have_latex = have_command("latex")
> have_dvipng = have_command("dvipng")
> load_imgmath = have_latex and have_dvipng
>
> Without setting imgmath_embed=true, math_renderer is mathjax which is
> default since Sphinx 1.8

We default to imgmath if the requisite utilities (latex, dvipng) are
installed on the system; perhaps that's not ideal, but it's what we have
done for a while.  It all seems to be working as expected, except that
the <img> element has the wrong URI in it.  Strange.

jon

^ permalink raw reply

* Re: [PATCH v3] docs: contain horizontal overflow in C API descriptions
From: Jonathan Corbet @ 2026-03-25 21:14 UTC (permalink / raw)
  To: Rito Rhymes, Rito Rhymes, linux-doc; +Cc: Shuah Khan, linux-kernel, rdunlap
In-Reply-To: <DHC5RBUT88C0.2OACW6VS3CYF2@ritovision.com>

"Rito Rhymes" <rito@ritovision.com> writes:

> If you could imagine an optimal solution, what would it look like?
> Can you describe the layout and/or behavior?

It should wrap so that the entire prototype is visible, but the way that
happens on small screens is definitely ugly.  The trick would be to have
it wrap the way it would for an overly long line in the source.

jon

^ permalink raw reply

* Re: [PATCH V9 5/8] dax: Add dax_operations for use by fs-dax on fsdev dax
From: Dave Jiang @ 2026-03-25 21:28 UTC (permalink / raw)
  To: John Groves, John Groves, Miklos Szeredi, Dan Williams,
	Bernd Schubert, Alison Schofield
  Cc: John Groves, Jonathan Corbet, Shuah Khan, Vishal Verma,
	Matthew Wilcox, Jan Kara, Alexander Viro, David Hildenbrand,
	Christian Brauner, Darrick J . Wong, Randy Dunlap, Jeff Layton,
	Amir Goldstein, Jonathan Cameron, Stefan Hajnoczi, Joanne Koong,
	Josef Bacik, Bagas Sanjaya, Chen Linxuan, James Morse, Fuad Tabba,
	Sean Christopherson, Shivank Garg, Ackerley Tng, Gregory Price,
	Aravind Ramesh, Ajay Joshi, venkataravis@micron.com,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	nvdimm@lists.linux.dev, linux-cxl@vger.kernel.org,
	linux-fsdevel@vger.kernel.org
In-Reply-To: <0100019d1d47e459-48f2a4e6-edab-4002-bde3-2ba642deccaf-000000@email.amazonses.com>



On 3/23/26 5:39 PM, John Groves wrote:
> From: John Groves <John@Groves.net>
> 
> fsdev: Add dax_operations for use by famfs.
> 
> This replicates the functionality from drivers/nvdimm/pmem.c that
> conventional fs-dax file systems (e.g. xfs) use to support dax
> read/write/mmap to a daxdev - without which famfs can't sit atop a
> daxdev.
> 
> - These methods are based on pmem_dax_ops from drivers/nvdimm/pmem.c
> - fsdev_dax_direct_access() returns the hpa, pfn and kva. The kva was
>   newly stored as dev_dax->virt_addr by dev_dax_probe().
> - The hpa/pfn are used for mmap (dax_iomap_fault()), and the kva is used
>   for read/write (dax_iomap_rw())
> - fsdev_dax_recovery_write() and dev_dax_zero_page_range() have not been
>   tested yet. I'm looking for suggestions as to how to test those.
> - dax-private.h: add dev_dax->cached_size, which fsdev needs to
>   remember. The dev_dax size cannot change while a driver is bound
>   (dev_dax_resize returns -EBUSY if dev->driver is set). Caching the size
>   at probe time allows fsdev's direct_access path can use it without
>   acquiring dax_dev_rwsem (which isn't exported anyway).
> 
> Signed-off-by: John Groves <john@groves.net>
> ---
>  drivers/dax/dax-private.h |  1 +
>  drivers/dax/fsdev.c       | 84 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 85 insertions(+)
> 
> diff --git a/drivers/dax/dax-private.h b/drivers/dax/dax-private.h
> index 7a3727d76a68..ee8f3af8387f 100644
> --- a/drivers/dax/dax-private.h
> +++ b/drivers/dax/dax-private.h
> @@ -85,6 +85,7 @@ struct dev_dax {
>  	struct dax_region *region;
>  	struct dax_device *dax_dev;
>  	void *virt_addr;
> +	u64 cached_size;

Just caught this. Need a kdoc entry.

DJ

>  	unsigned int align;
>  	int target_node;
>  	bool dyn_id;
> diff --git a/drivers/dax/fsdev.c b/drivers/dax/fsdev.c
> index c75478d3d548..be3d2b0e8418 100644
> --- a/drivers/dax/fsdev.c
> +++ b/drivers/dax/fsdev.c
> @@ -28,6 +28,85 @@
>   * - No mmap support - all access is through fs-dax/iomap
>   */
>  
> +static void fsdev_write_dax(void *pmem_addr, struct page *page,
> +		unsigned int off, unsigned int len)
> +{
> +	while (len) {
> +		void *mem = kmap_local_page(page);
> +		unsigned int chunk = min_t(unsigned int, len, PAGE_SIZE - off);
> +
> +		memcpy_flushcache(pmem_addr, mem + off, chunk);
> +		kunmap_local(mem);
> +		len -= chunk;
> +		off = 0;
> +		page++;
> +		pmem_addr += chunk;
> +	}
> +}
> +
> +static long __fsdev_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff,
> +			long nr_pages, enum dax_access_mode mode, void **kaddr,
> +			unsigned long *pfn)
> +{
> +	struct dev_dax *dev_dax = dax_get_private(dax_dev);
> +	size_t size = nr_pages << PAGE_SHIFT;
> +	size_t offset = pgoff << PAGE_SHIFT;
> +	void *virt_addr = dev_dax->virt_addr + offset;
> +	phys_addr_t phys;
> +	unsigned long local_pfn;
> +
> +	phys = dax_pgoff_to_phys(dev_dax, pgoff, nr_pages << PAGE_SHIFT);
> +	if (phys == -1) {
> +		dev_dbg(&dev_dax->dev,
> +			"pgoff (%#lx) out of range\n", pgoff);
> +		return -EFAULT;
> +	}
> +
> +	if (kaddr)
> +		*kaddr = virt_addr;
> +
> +	local_pfn = PHYS_PFN(phys);
> +	if (pfn)
> +		*pfn = local_pfn;
> +
> +	/*
> +	 * Use cached_size which was computed at probe time. The size cannot
> +	 * change while the driver is bound (resize returns -EBUSY).
> +	 */
> +	return PHYS_PFN(min(size, dev_dax->cached_size - offset));
> +}
> +
> +static int fsdev_dax_zero_page_range(struct dax_device *dax_dev,
> +			pgoff_t pgoff, size_t nr_pages)
> +{
> +	void *kaddr;
> +
> +	WARN_ONCE(nr_pages > 1, "%s: nr_pages > 1\n", __func__);
> +	__fsdev_dax_direct_access(dax_dev, pgoff, 1, DAX_ACCESS, &kaddr, NULL);
> +	fsdev_write_dax(kaddr, ZERO_PAGE(0), 0, PAGE_SIZE);
> +	return 0;
> +}
> +
> +static long fsdev_dax_direct_access(struct dax_device *dax_dev,
> +		  pgoff_t pgoff, long nr_pages, enum dax_access_mode mode,
> +		  void **kaddr, unsigned long *pfn)
> +{
> +	return __fsdev_dax_direct_access(dax_dev, pgoff, nr_pages, mode,
> +					 kaddr, pfn);
> +}
> +
> +static size_t fsdev_dax_recovery_write(struct dax_device *dax_dev, pgoff_t pgoff,
> +		void *addr, size_t bytes, struct iov_iter *i)
> +{
> +	return _copy_from_iter_flushcache(addr, bytes, i);
> +}
> +
> +static const struct dax_operations dev_dax_ops = {
> +	.direct_access = fsdev_dax_direct_access,
> +	.zero_page_range = fsdev_dax_zero_page_range,
> +	.recovery_write = fsdev_dax_recovery_write,
> +};
> +
>  static void fsdev_cdev_del(void *cdev)
>  {
>  	cdev_del(cdev);
> @@ -167,6 +246,11 @@ static int fsdev_dax_probe(struct dev_dax *dev_dax)
>  		}
>  	}
>  
> +	/* Cache size now; it cannot change while driver is bound */
> +	dev_dax->cached_size = 0;
> +	for (i = 0; i < dev_dax->nr_range; i++)
> +		dev_dax->cached_size += range_len(&dev_dax->ranges[i].range);
> +
>  	/*
>  	 * Use MEMORY_DEVICE_FS_DAX without setting vmemmap_shift, leaving
>  	 * folios at order-0. Unlike device.c (MEMORY_DEVICE_GENERIC), this


^ permalink raw reply

* Re: [PATCH v3] docs: allow long unbroken headings to wrap and prevent overflow
From: Rito Rhymes @ 2026-03-25 21:32 UTC (permalink / raw)
  To: Jonathan Corbet, Rito Rhymes, linux-doc; +Cc: Shuah Khan, linux-kernel, rdunlap
In-Reply-To: <87h5q3g288.fsf@trenco.lwn.net>

One possibility is that the issue may not reproduce if the test is
being done by narrowing the full desktop browser window (rather than
the page's viewport with DevTools opened).

On desktop, the browser's outer window often cannot get as narrow as
many actual mobile screen widths (often bottoming out somewhere around
500-600px), so it may be too wide to expose the problem.

If you check it with DevTools opened and reduce the page's viewport to
a more realistic mobile range, around 380-500px, the issue should be
easier to reproduce in both browsers.

For highest fidelity, I find it most reliable to verify on an actual
mobile device and test the fix by binding the local server on all
interfaces then loading the page directly from the phone.

Let me know if this helps clarify the issue.

Rito

^ permalink raw reply

* Re: Invalid link generation for equations
From: Mauro Carvalho Chehab @ 2026-03-25 21:40 UTC (permalink / raw)
  To: Jonathan Corbet
  Cc: Shuah Khan, Kevin Brodsky, linux-doc, Konstantin Ryabitsev,
	Mauro Carvalho Chehab, Akira Yokosawa
In-Reply-To: <87o6kbehr6.fsf@trenco.lwn.net>

On Wed, 25 Mar 2026 15:11:57 -0600
Jonathan Corbet <corbet@lwn.net> wrote:

> Shuah Khan <skhan@linuxfoundation.org> writes:
> 
> >> OK, so this is more than passing strange...I can't reproduce that
> >> problem locally.  The HTML I get is:
> >> 
> >>    <img src="../_images/math/d9936822[...]
> >> 
> >> On docs.kernel.org, instead:
> >> 
> >>    <img src="_images/math/d9936822[...]
> >> 
> >> Note the missing "../".
> >> 
> >> I will confess that I don't have a great understanding of how imgmath
> >> works and how that link gets set.  We could "fix" the problem generally
> >> by setting imgmath_embed=True, but it would be good to understand what's
> >> actually happening here.  
> >
> > Respect SPHINX_IMGMATH (for html docs only) in Documentation/conf.py
> > might explain why imgmath_embed=True works?
> >
> > # Load math renderer:
> > # For html builder, load imgmath only when its dependencies are met.
> > # mathjax is the default math renderer since Sphinx 1.8.
> > have_latex = have_command("latex")
> > have_dvipng = have_command("dvipng")
> > load_imgmath = have_latex and have_dvipng
> >
> > Without setting imgmath_embed=true, math_renderer is mathjax which is
> > default since Sphinx 1.8  
> 
> We default to imgmath if the requisite utilities (latex, dvipng) are
> installed on the system; perhaps that's not ideal, but it's what we have
> done for a while.  It all seems to be working as expected, except that
> the <img> element has the wrong URI in it.  Strange.

Looking at this changelog from Akira:

	6b0d3e7c5888 ("docs/conf.py: Treat mathjax as fallback math renderer")

It mentions that this is kept due to epub output. On a quick search:

	https://github.com/sphinx-doc/sphinx/issues/1570

I'm not sure how this is handled in PDF, but mathjax seems to be
specific for html output only.
	
Thanks,
Mauro

^ permalink raw reply

* Re: [PATCH v3] docs: allow long unbroken headings to wrap and prevent overflow
From: Rito Rhymes @ 2026-03-25 21:46 UTC (permalink / raw)
  To: Rito Rhymes, Jonathan Corbet, linux-doc; +Cc: Shuah Khan, linux-kernel, rdunlap
In-Reply-To: <DHC6NJM3JZJC.3EIT3YD7O8CDW@ritovision.com>

Also, did you test both pages in the patchlog example?

For me on desktop Chrome, this one overflows a lot with just the
outer window width at its minimum:
https://docs.kernel.org/6.15/userspace-api/gpio/gpio-v2-line-get-values-ioctl.html

And for the other one, it's more clear on a mobile device / DevTools
resizing. This part wraps down `/sys/firmware/acpi/platform_profile`
but then that part itself as an unbroken string doesn't wrap any further
and exceeds mobile screen viewport width causing page-wide overflow:
https://docs.kernel.org/6.15/userspace-api/sysfs-platform_profile.html

I can host some screenshots if that would be helpful. Let me know.

Rito

^ permalink raw reply

* Re: [PATCH v3] docs: allow long unbroken headings to wrap and prevent overflow
From: Jonathan Corbet @ 2026-03-25 22:04 UTC (permalink / raw)
  To: Rito Rhymes, Rito Rhymes, linux-doc; +Cc: Shuah Khan, linux-kernel, rdunlap
In-Reply-To: <DHC6NJM3JZJC.3EIT3YD7O8CDW@ritovision.com>

"Rito Rhymes" <rito@ritovision.com> writes:

> One possibility is that the issue may not reproduce if the test is
> being done by narrowing the full desktop browser window (rather than
> the page's viewport with DevTools opened).
>
> On desktop, the browser's outer window often cannot get as narrow as
> many actual mobile screen widths (often bottoming out somewhere around
> 500-600px), so it may be too wide to expose the problem.
>
> If you check it with DevTools opened and reduce the page's viewport to
> a more realistic mobile range, around 380-500px, the issue should be
> easier to reproduce in both browsers.
>
> For highest fidelity, I find it most reliable to verify on an actual
> mobile device and test the fix by binding the local server on all
> interfaces then loading the page directly from the phone.

I tried on both desktop and mobile screens, both browsers, same results.

jon

^ permalink raw reply

* Re: [PATCH v8 02/10] x86/bhi: Make clear_bhb_loop() effective on newer CPUs
From: Pawan Gupta @ 2026-03-25 22:29 UTC (permalink / raw)
  To: David Laight
  Cc: Jim Mattson, x86, Jon Kohler, Nikolay Borisov, H. Peter Anvin,
	Josh Poimboeuf, David Kaplan, Sean Christopherson,
	Borislav Petkov, Dave Hansen, Peter Zijlstra, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, KP Singh, Jiri Olsa,
	David S. Miller, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
	David Ahern, Martin KaFai Lau, Eduard Zingerman, Song Liu,
	Yonghong Song, John Fastabend, Stanislav Fomichev, Hao Luo,
	Paolo Bonzini, Jonathan Corbet, linux-kernel, kvm, Asit Mallick,
	Tao Zhang, bpf, netdev, linux-doc
In-Reply-To: <20260325194146.29c91953@pumpkin>

On Wed, Mar 25, 2026 at 07:41:46PM +0000, David Laight wrote:
> On Wed, 25 Mar 2026 10:50:58 -0700
> Jim Mattson <jmattson@google.com> wrote:
> 
> > On Tue, Mar 24, 2026 at 11:19 AM Pawan Gupta
> > <pawan.kumar.gupta@linux.intel.com> wrote:
> > >
> > > As a mitigation for BHI, clear_bhb_loop() executes branches that overwrites
> > > the Branch History Buffer (BHB). On Alder Lake and newer parts this
> > > sequence is not sufficient because it doesn't clear enough entries. This
> > > was not an issue because these CPUs have a hardware control (BHI_DIS_S)
> > > that mitigates BHI in kernel.
> > >
> > > BHI variant of VMSCAPE requires isolating branch history between guests and
> > > userspace. Note that there is no equivalent hardware control for userspace.
> > > To effectively isolate branch history on newer CPUs, clear_bhb_loop()
> > > should execute sufficient number of branches to clear a larger BHB.
> > >
> > > Dynamically set the loop count of clear_bhb_loop() such that it is
> > > effective on newer CPUs too. Use the hardware control enumeration
> > > X86_FEATURE_BHI_CTRL to select the appropriate loop count.
> > >
> > > Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
> > > Reviewed-by: Nikolay Borisov <nik.borisov@suse.com>
> > > Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
> > > ---
> > >  arch/x86/entry/entry_64.S   | 21 ++++++++++++++++-----
> > >  arch/x86/net/bpf_jit_comp.c |  7 -------
> > >  2 files changed, 16 insertions(+), 12 deletions(-)
> > >
> > > diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
> > > index 3a180a36ca0e..8128e00ca73f 100644
> > > --- a/arch/x86/entry/entry_64.S
> > > +++ b/arch/x86/entry/entry_64.S
> > > @@ -1535,8 +1535,17 @@ SYM_CODE_END(rewind_stack_and_make_dead)
> > >  SYM_FUNC_START(clear_bhb_loop)
> > >         ANNOTATE_NOENDBR
> > >         push    %rbp
> > > +       /* BPF caller may require %rax to be preserved */
> 
> Since you need a new version change that to 'all registers preserved'.

Ya, thats more accurate.

> > > +       push    %rax  
> > 
> > Shouldn't the "push %rax" come after "mov %rsp, %rbp"?
> 
> Or delete the stack frame :-)
> It is only there for the stack trace-back code.

Hmm, lets keep the stack frame, it might help debug.

^ permalink raw reply

* Re: [PATCH v2] docs: rework footer with semantic markup and responsive layout
From: Rito Rhymes @ 2026-03-25 22:33 UTC (permalink / raw)
  To: Jonathan Corbet, Rito Rhymes, Mauro Carvalho Chehab, linux-doc
  Cc: Shuah Khan, linux-kernel
In-Reply-To: <877bqzg146.fsf@trenco.lwn.net>

We could use a CSS override if the goal were only to change how
the footer looks. But CSS cannot change the footer's semantics for
accessibility, and that's where a fundamental issue lies.

The default theme renders the footer as a generic `div`, and
`class="footer"` does not give it any semantic meaning. Screen
readers and other accessibility tools do not treat that the same as
a real `<footer>` landmark.

To fix that properly, we need to change the markup, either by
rendering a native `<footer>` element or by adding
`role="contentinfo"` to the existing container. That requires
replacing the footer template/component, not just overriding its CSS.

Since the footer appears on every page, I think it's important to
ensure its a11y-friendly, so it makes sense to fix it at the markup
level rather than just overriding the CSS to be mobile-friendly.

Rito

^ permalink raw reply

* Re: [PATCH V9 5/8] dax: Add dax_operations for use by fs-dax on fsdev dax
From: Dave Jiang @ 2026-03-25 22:40 UTC (permalink / raw)
  To: John Groves, John Groves, Miklos Szeredi, Dan Williams,
	Bernd Schubert, Alison Schofield
  Cc: John Groves, Jonathan Corbet, Shuah Khan, Vishal Verma,
	Matthew Wilcox, Jan Kara, Alexander Viro, David Hildenbrand,
	Christian Brauner, Darrick J . Wong, Randy Dunlap, Jeff Layton,
	Amir Goldstein, Jonathan Cameron, Stefan Hajnoczi, Joanne Koong,
	Josef Bacik, Bagas Sanjaya, Chen Linxuan, James Morse, Fuad Tabba,
	Sean Christopherson, Shivank Garg, Ackerley Tng, Gregory Price,
	Aravind Ramesh, Ajay Joshi, venkataravis@micron.com,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	nvdimm@lists.linux.dev, linux-cxl@vger.kernel.org,
	linux-fsdevel@vger.kernel.org
In-Reply-To: <0100019d1d47e459-48f2a4e6-edab-4002-bde3-2ba642deccaf-000000@email.amazonses.com>



On 3/23/26 5:39 PM, John Groves wrote:
> From: John Groves <John@Groves.net>
> 
> fsdev: Add dax_operations for use by famfs.
> 
> This replicates the functionality from drivers/nvdimm/pmem.c that
> conventional fs-dax file systems (e.g. xfs) use to support dax
> read/write/mmap to a daxdev - without which famfs can't sit atop a
> daxdev.
> 
> - These methods are based on pmem_dax_ops from drivers/nvdimm/pmem.c
> - fsdev_dax_direct_access() returns the hpa, pfn and kva. The kva was
>   newly stored as dev_dax->virt_addr by dev_dax_probe().
> - The hpa/pfn are used for mmap (dax_iomap_fault()), and the kva is used
>   for read/write (dax_iomap_rw())
> - fsdev_dax_recovery_write() and dev_dax_zero_page_range() have not been
>   tested yet. I'm looking for suggestions as to how to test those.
> - dax-private.h: add dev_dax->cached_size, which fsdev needs to
>   remember. The dev_dax size cannot change while a driver is bound
>   (dev_dax_resize returns -EBUSY if dev->driver is set). Caching the size
>   at probe time allows fsdev's direct_access path can use it without
>   acquiring dax_dev_rwsem (which isn't exported anyway).
> 
> Signed-off-by: John Groves <john@groves.net>

Couple nits below while I'm stealing code from you.

> ---
>  drivers/dax/dax-private.h |  1 +
>  drivers/dax/fsdev.c       | 84 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 85 insertions(+)
> 
> diff --git a/drivers/dax/dax-private.h b/drivers/dax/dax-private.h
> index 7a3727d76a68..ee8f3af8387f 100644
> --- a/drivers/dax/dax-private.h
> +++ b/drivers/dax/dax-private.h
> @@ -85,6 +85,7 @@ struct dev_dax {
>  	struct dax_region *region;
>  	struct dax_device *dax_dev;
>  	void *virt_addr;
> +	u64 cached_size;
>  	unsigned int align;
>  	int target_node;
>  	bool dyn_id;
> diff --git a/drivers/dax/fsdev.c b/drivers/dax/fsdev.c
> index c75478d3d548..be3d2b0e8418 100644
> --- a/drivers/dax/fsdev.c
> +++ b/drivers/dax/fsdev.c
> @@ -28,6 +28,85 @@
>   * - No mmap support - all access is through fs-dax/iomap
>   */
>  
> +static void fsdev_write_dax(void *pmem_addr, struct page *page,

addr instead of pmem_addr? copy pasta error?

> +		unsigned int off, unsigned int len)
> +{
> +	while (len) {
> +		void *mem = kmap_local_page(page);
> +		unsigned int chunk = min_t(unsigned int, len, PAGE_SIZE - off);
> +
> +		memcpy_flushcache(pmem_addr, mem + off, chunk);
> +		kunmap_local(mem);
> +		len -= chunk;
> +		off = 0;
> +		page++;
> +		pmem_addr += chunk;
> +	}
> +}
> +
> +static long __fsdev_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff,
> +			long nr_pages, enum dax_access_mode mode, void **kaddr,
> +			unsigned long *pfn)
> +{
> +	struct dev_dax *dev_dax = dax_get_private(dax_dev);
> +	size_t size = nr_pages << PAGE_SHIFT;
> +	size_t offset = pgoff << PAGE_SHIFT;
> +	void *virt_addr = dev_dax->virt_addr + offset;
> +	phys_addr_t phys;
> +	unsigned long local_pfn;
> +
> +	phys = dax_pgoff_to_phys(dev_dax, pgoff, nr_pages << PAGE_SHIFT);

you can use 'size' instead here since it's previously computed already.

DJ

> +	if (phys == -1) {
> +		dev_dbg(&dev_dax->dev,
> +			"pgoff (%#lx) out of range\n", pgoff);
> +		return -EFAULT;
> +	}
> +
> +	if (kaddr)
> +		*kaddr = virt_addr;
> +
> +	local_pfn = PHYS_PFN(phys);
> +	if (pfn)
> +		*pfn = local_pfn;
> +
> +	/*
> +	 * Use cached_size which was computed at probe time. The size cannot
> +	 * change while the driver is bound (resize returns -EBUSY).
> +	 */
> +	return PHYS_PFN(min(size, dev_dax->cached_size - offset));
> +}
> +
> +static int fsdev_dax_zero_page_range(struct dax_device *dax_dev,
> +			pgoff_t pgoff, size_t nr_pages)
> +{
> +	void *kaddr;
> +
> +	WARN_ONCE(nr_pages > 1, "%s: nr_pages > 1\n", __func__);
> +	__fsdev_dax_direct_access(dax_dev, pgoff, 1, DAX_ACCESS, &kaddr, NULL);
> +	fsdev_write_dax(kaddr, ZERO_PAGE(0), 0, PAGE_SIZE);
> +	return 0;
> +}
> +
> +static long fsdev_dax_direct_access(struct dax_device *dax_dev,
> +		  pgoff_t pgoff, long nr_pages, enum dax_access_mode mode,
> +		  void **kaddr, unsigned long *pfn)
> +{
> +	return __fsdev_dax_direct_access(dax_dev, pgoff, nr_pages, mode,
> +					 kaddr, pfn);
> +}
> +
> +static size_t fsdev_dax_recovery_write(struct dax_device *dax_dev, pgoff_t pgoff,
> +		void *addr, size_t bytes, struct iov_iter *i)
> +{
> +	return _copy_from_iter_flushcache(addr, bytes, i);
> +}
> +
> +static const struct dax_operations dev_dax_ops = {
> +	.direct_access = fsdev_dax_direct_access,
> +	.zero_page_range = fsdev_dax_zero_page_range,
> +	.recovery_write = fsdev_dax_recovery_write,
> +};
> +
>  static void fsdev_cdev_del(void *cdev)
>  {
>  	cdev_del(cdev);
> @@ -167,6 +246,11 @@ static int fsdev_dax_probe(struct dev_dax *dev_dax)
>  		}
>  	}
>  
> +	/* Cache size now; it cannot change while driver is bound */
> +	dev_dax->cached_size = 0;
> +	for (i = 0; i < dev_dax->nr_range; i++)
> +		dev_dax->cached_size += range_len(&dev_dax->ranges[i].range);
> +
>  	/*
>  	 * Use MEMORY_DEVICE_FS_DAX without setting vmemmap_shift, leaving
>  	 * folios at order-0. Unlike device.c (MEMORY_DEVICE_GENERIC), this


^ permalink raw reply

* Re: [PATCH v8 02/10] x86/bhi: Make clear_bhb_loop() effective on newer CPUs
From: David Laight @ 2026-03-25 22:40 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Pawan Gupta, x86, Jon Kohler, Nikolay Borisov, H. Peter Anvin,
	Josh Poimboeuf, David Kaplan, Sean Christopherson, Dave Hansen,
	Peter Zijlstra, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, KP Singh, Jiri Olsa, David S. Miller,
	Andy Lutomirski, Thomas Gleixner, Ingo Molnar, David Ahern,
	Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
	John Fastabend, Stanislav Fomichev, Hao Luo, Paolo Bonzini,
	Jonathan Corbet, linux-kernel, kvm, Asit Mallick, Tao Zhang, bpf,
	netdev, linux-doc
In-Reply-To: <20260325203759.GCacRHp2t8a7c4Bp6E@fat_crate.local>

On Wed, 25 Mar 2026 21:37:59 +0100
Borislav Petkov <bp@alien8.de> wrote:

> On Tue, Mar 24, 2026 at 03:13:08PM -0700, Pawan Gupta wrote:
...
> > Although call to clear_bhb_loop() will be inserted at the end of the BPF
> > program before it returns, I am not sure if it is safe to assume that
> > trashing registers in the path clear_bhb_loop() -> __clear_bhb_loop() is
> > okay? Especially, when we don't know what code compiler generated for
> > clear_bhb_loop(). BPF experts would know better?  
> 
> The compiler would preserve the regs. If you write it in asm and you adhere to
> the C ABI, you could preserve them too. Shouldn't be too many.

The BPF code that calls it doesn't use the C ABI - it just puts
a call instruction in the code it generates.
Hence all registers must be preserved.

	David

> 
> Thx.
> 
> 


^ permalink raw reply

* Re: [PATCH v2] docs: rework footer with semantic markup and responsive layout
From: Jonathan Corbet @ 2026-03-25 23:06 UTC (permalink / raw)
  To: Rito Rhymes, Rito Rhymes, Mauro Carvalho Chehab, linux-doc
  Cc: Shuah Khan, linux-kernel
In-Reply-To: <DHC7Y88CXPP8.1AXPXN8YUPK1D@ritovision.com>

"Rito Rhymes" <rito@ritovision.com> writes:

> We could use a CSS override if the goal were only to change how
> the footer looks. But CSS cannot change the footer's semantics for
> accessibility, and that's where a fundamental issue lies.
>
> The default theme renders the footer as a generic `div`, and
> `class="footer"` does not give it any semantic meaning. Screen
> readers and other accessibility tools do not treat that the same as
> a real `<footer>` landmark.
>
> To fix that properly, we need to change the markup, either by
> rendering a native `<footer>` element or by adding
> `role="contentinfo"` to the existing container. That requires
> replacing the footer template/component, not just overriding its CSS.
>
> Since the footer appears on every page, I think it's important to
> ensure its a11y-friendly, so it makes sense to fix it at the markup
> level rather than just overriding the CSS to be mobile-friendly.

Please, include the context you are replying to so people can follow the
discussion.

We are not going to fix Sphinx accessibility piecemeal in this way.  If
that is really the objective, I think the right thing is to work with
the Sphinx project directly and come up with a proper plan for all of
their major elements.  Tweaking the footer - the contents of which will
be read by the screen reader and understood just fine - doesn't really
address that problem.

Thanks,

jon

^ permalink raw reply

* Re: [PATCH] riscv: enable HAVE_IOREMAP_PROT
From: Paul Walmsley @ 2026-03-25 23:09 UTC (permalink / raw)
  To: rom.wang
  Cc: Jonathan Corbet, Shuah Khan, Paul Walmsley, Albert Ou,
	Alexandre Ghiti, linux-doc, linux-kernel, linux-riscv,
	Yufeng Wang
In-Reply-To: <20260306112734.108186-1-r4o5m6e8o@163.com>

On Fri, 6 Mar 2026, rom.wang wrote:

> From: Yufeng Wang <wangyufeng@kylinos.cn>
> 
> RISC-V has implemented pte_pgprot() and selects GENERIC_IOREMAP,
> which provides a generic ioremap_prot() implementation. Enable
> HAVE_IOREMAP_PROT to activate generic_access_phys() support, which
> is useful for debugging (e.g., accessing /dev/mem via gdb).
> 
> Also update the architecture support documentation accordingly.
> 
> Signed-off-by: Yufeng Wang <wangyufeng@kylinos.cn>

Thanks, queued for v7.1.


- Paul

^ permalink raw reply

* Re: [PATCH v3 02/24] PCI: Add API to track PCI devices preserved across Live Update
From: Bjorn Helgaas @ 2026-03-25 23:12 UTC (permalink / raw)
  To: David Matlack
  Cc: Alex Williamson, Bjorn Helgaas, Adithya Jayachandran,
	Alexander Graf, Alex Mastro, Andrew Morton, Ankit Agrawal,
	Arnd Bergmann, Askar Safin, Borislav Petkov (AMD), Chris Li,
	Dapeng Mi, David Rientjes, Feng Tang, Jacob Pan, Jason Gunthorpe,
	Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Kees Cook,
	Kevin Tian, kexec, kvm, Leon Romanovsky, Leon Romanovsky,
	linux-doc, linux-kernel, linux-kselftest, linux-mm, linux-pci,
	Li RongQing, Lukas Wunner, Marco Elver, Michał Winiarski,
	Mike Rapoport, Parav Pandit, Pasha Tatashin, Paul E. McKenney,
	Pawan Gupta, Peter Zijlstra (Intel), Pranjal Shrivastava,
	Pratyush Yadav, Raghavendra Rao Ananta, Randy Dunlap,
	Rodrigo Vivi, Saeed Mahameed, Samiullah Khawaja, Shuah Khan,
	Vipin Sharma, Vivek Kasireddy, William Tu, Yi Liu, Zhu Yanjun
In-Reply-To: <20260323235817.1960573-3-dmatlack@google.com>

On Mon, Mar 23, 2026 at 11:57:54PM +0000, David Matlack wrote:
> Add an API to enable the PCI subsystem to participate in a Live Update
> and track all devices that are being preserved by drivers. Since this
> support is still under development, hide it behind a new Kconfig
> PCI_LIVEUPDATE that is marked experimental.

Can you list the interfaces being added here, e.g.,

  pci_liveupdate_register_flb() - register driver's liveupdate_file_handler
  pci_liveupdate_unregister_flb()
  pci_liveupdate_preserve() - preserve device across LU kexec
  pci_liveupdate_unpreserve() - cancel device preservation
  pci_liveupdate_retrieve() - not sure?
  pci_liveupdate_finish()

I think it's nice to have an idea of what pieces to look for before
reading the patch.

> This API will be used in subsequent commits by the vfio-pci driver to
> preserve VFIO devices across Live Update.
> 
> Signed-off-by: David Matlack <dmatlack@google.com>
> ---
>  drivers/pci/Kconfig         |  11 ++
>  drivers/pci/Makefile        |   1 +
>  drivers/pci/liveupdate.c    | 380 ++++++++++++++++++++++++++++++++++++
>  drivers/pci/pci.h           |  14 ++
>  drivers/pci/probe.c         |   2 +
>  include/linux/kho/abi/pci.h |  62 ++++++
>  include/linux/pci.h         |  41 ++++
>  7 files changed, 511 insertions(+)
>  create mode 100644 drivers/pci/liveupdate.c
>  create mode 100644 include/linux/kho/abi/pci.h
> 
> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> index e3f848ffb52a..05307d89c3f4 100644
> --- a/drivers/pci/Kconfig
> +++ b/drivers/pci/Kconfig
> @@ -334,6 +334,17 @@ config VGA_ARB_MAX_GPUS
>  	  Reserves space in the kernel to maintain resource locking for
>  	  multiple GPUS.  The overhead for each GPU is very small.
>  
> +config PCI_LIVEUPDATE
> +	bool "PCI Live Update Support (EXPERIMENTAL)"
> +	depends on PCI && LIVEUPDATE
> +	help
> +	  Support for preserving PCI devices across a Live Update. This option
> +	  should only be enabled by developers working on implementing this
> +	  support. Once enough support as landed in the kernel, this option
> +	  will no longer be marked EXPERIMENTAL.

This would be a good place for a one-sentence explanation of what
"preserving PCI devices" means.  Obviously the physical devices stay
there; what's interesting is that the hardware continues operating
without interruption across the update.

s/support as landed/support has landed/ (maybe no need for this
sentence at all)

> +	  If unsure, say N.
> +
>  source "drivers/pci/hotplug/Kconfig"
>  source "drivers/pci/controller/Kconfig"
>  source "drivers/pci/endpoint/Kconfig"
> diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
> index 41ebc3b9a518..e8d003cb6757 100644
> --- a/drivers/pci/Makefile
> +++ b/drivers/pci/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_PROC_FS)		+= proc.o
>  obj-$(CONFIG_SYSFS)		+= pci-sysfs.o slot.o
>  obj-$(CONFIG_ACPI)		+= pci-acpi.o
>  obj-$(CONFIG_GENERIC_PCI_IOMAP) += iomap.o
> +obj-$(CONFIG_PCI_LIVEUPDATE)	+= liveupdate.o
>  endif
>  
>  obj-$(CONFIG_OF)		+= of.o
> diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
> new file mode 100644
> index 000000000000..bec7b3500057
> --- /dev/null
> +++ b/drivers/pci/liveupdate.c
> @@ -0,0 +1,380 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Copyright (c) 2026, Google LLC.
> + * David Matlack <dmatlack@google.com>
> + */
> +
> +/**
> + * DOC: PCI Live Update
> + *
> + * The PCI subsystem participates in the Live Update process to enable drivers
> + * to preserve their PCI devices across kexec.
> + *
> + * Device preservation across Live Update is built on top of the Live Update
> + * Orchestrator (LUO) support for file preservation across kexec. Userspace
> + * indicates that a device should be preserved by preserving the file associated
> + * with the device with ``ioctl(LIVEUPDATE_SESSION_PRESERVE_FD)``.
> + *
> + * .. note::
> + *    The support for preserving PCI devices across Live Update is currently
> + *    *partial* and should be considered *experimental*. It should only be
> + *    used by developers working on the implementation for the time being.
> + *
> + *    To enable the support, enable ``CONFIG_PCI_LIVEUPDATE``.
> + *
> + * Driver API
> + * ==========
> + *
> + * Drivers that support file-based device preservation must register their
> + * ``liveupdate_file_handler`` with the PCI subsystem by calling
> + * ``pci_liveupdate_register_flb()``. This ensures the PCI subsystem will be
> + * notified whenever a device file is preserved so that ``struct pci_ser``
> + * can be allocated to track all preserved devices. This struct is an ABI
> + * and is eventually handed off to the next kernel via Kexec-Handover (KHO).
> + *
> + * In the "outgoing" kernel (before kexec), drivers should then notify the PCI
> + * subsystem directly whenever the preservation status for a device changes:
> + *
> + *  * ``pci_liveupdate_preserve(pci_dev)``: The device is being preserved.
> + *
> + *  * ``pci_liveupdate_unpreserve(pci_dev)``: The device is no longer being
> + *    preserved (preservation is cancelled).
> + *
> + * In the "incoming" kernel (after kexec), drivers should notify the PCI
> + * subsystem with the following calls:
> + *
> + *  * ``pci_liveupdate_retrieve(pci_dev)``: The device file is being retrieved
> + *    by userspace.

I'm not clear on what this means.  Is this telling the PCI core that
somebody else (userspace?) is doing something?  Why does the PCI core
care?  The name suggests that this interface would retrieve some data
from the PCI core, but that doesn't seem to be what's happening.

> + *
> + *  * ``pci_liveupdate_finish(pci_dev)``: The device is done participating in
> + *    Live Update. After this point the device may no longer be even associated
> + *    with the same driver.

This sets "dev->liveupdate_incoming = false", and the only place we
check that is in pci_liveupdate_retrieve().  In particular, there's
nothing in the driver bind/unbind paths that seems related.  I guess
pci_liveupdate_finish() just means the driver can't call
pci_liveupdate_retrieve() any more?

> + *
> + * Incoming/Outgoing
> + * =================
> + *
> + * The state of each device's participation in Live Update is stored in
> + * ``struct pci_dev``:
> + *
> + *  * ``liveupdate_outgoing``: True if the device is being preserved in the
> + *    outgoing kernel. Set in ``pci_liveupdate_preserve()`` and cleared in
> + *    ``pci_liveupdate_unpreserve()``.
> + *
> + *  * ``liveupdate_incoming``: True if the device is preserved in the incoming
> + *    kernel. Set during probing when the device is first created and cleared
> + *    in ``pci_liveupdate_finish()``.
> + *
> + * Restrictions
> + * ============
> + *
> + * Preserved devices currently have the following restrictions. Each of these
> + * may be relaxed in the future.
> + *
> + *  * The device must not be a Virtual Function (VF).
> + *
> + *  * The device must not be a Physical Function (PF).
> + *
> + * Preservation Behavior
> + * =====================
> + *
> + * The kernel preserves the following state for devices preserved across a Live
> + * Update:
> + *
> + *  * The PCI Segment, Bus, Device, and Function numbers assigned to the device
> + *    are guaranteed to remain the same across Live Update.
> + *
> + * This list will be extended in the future as new support is added.
> + *
> + * Driver Binding
> + * ==============
> + *
> + * It is the driver's responsibility for ensuring that preserved devices are not
> + * released or bound to a different driver for as long as they are preserved. In
> + * practice, this is enforced by LUO taking an extra referenced to the preserved

s/responsibility for ensuring/responsibility to ensure/
s/referenced/reference/

> + * device file for as long as it is preserved.
> + *
> + * However, there is a window of time in the incoming kernel when a device is
> + * first probed and when userspace retrieves the device file with
> + * ``LIVEUPDATE_SESSION_RETRIEVE_FD`` when the device could be bound to any
> + * driver.

  ... window of time in the incoming kernel between a device being
  probed and userspace retrieving the device file ... when the device
  could be bound ...

I'm not sure what it means to retrieve a device file.  It doesn't
sound like the usual Unix "device file" or "special file" in /dev/,
since those aren't "retrieved".

> + * It is currently userspace's responsibility to ensure that the device is bound
> + * to the correct driver in this window.
> + */
> +
> +#include <linux/bsearch.h>
> +#include <linux/io.h>
> +#include <linux/kexec_handover.h>
> +#include <linux/kho/abi/pci.h>
> +#include <linux/liveupdate.h>
> +#include <linux/mutex.h>
> +#include <linux/mm.h>
> +#include <linux/pci.h>
> +#include <linux/sort.h>
> +
> +#include "pci.h"
> +
> +static DEFINE_MUTEX(pci_flb_outgoing_lock);

It'd be handy if there were some excuse to mention "FLB" and expand it
once in the doc above, since I have no idea what it means or where to
look for it.  Maybe unfortunate that it will be pronounced "flub" ;)

> +static int pci_flb_preserve(struct liveupdate_flb_op_args *args)
> +{
> +	struct pci_dev *dev = NULL;
> +	int max_nr_devices = 0;
> +	struct pci_ser *ser;
> +	unsigned long size;
> +
> +	/*
> +	 * Don't both accounting for VFs that could be created after this
> +	 * since preserving VFs is not supported yet. Also don't account
> +	 * for devices that could be hot-plugged after this since preserving
> +	 * hot-plugged devices across Live Update is not yet an expected
> +	 * use-case.

s/Don't both accounting/Don't bother accounting/ ? not sure of intent

I suspect the important thing here is that this allocates space for
preserving X devices, and each subsequent pci_liveupdate_preserve()
call from a driver uses up one of those slots.

My guess is this is just an allocation issue and from that point of
view there's no actual problem with enabling VFs or hot-adding devices
after this point; it's just that pci_liveupdate_preserve() will fail
after X calls.

> +	 */
> +	for_each_pci_dev(dev)
> +		max_nr_devices++;
> +
> +	size = struct_size_t(struct pci_ser, devices, max_nr_devices);
> +
> +	ser = kho_alloc_preserve(size);
> +	if (IS_ERR(ser))
> +		return PTR_ERR(ser);
> +
> +	ser->max_nr_devices = max_nr_devices;
> +
> +	args->obj = ser;
> +	args->data = virt_to_phys(ser);
> +	return 0;
> +}
> +
> +static void pci_flb_unpreserve(struct liveupdate_flb_op_args *args)
> +{
> +	struct pci_ser *ser = args->obj;
> +
> +	WARN_ON_ONCE(ser->nr_devices);

I guess this means somebody (userspace?) called .unpreserve() before
all the drivers that had called pci_liveupdate_preserve() have also
called pci_liveupdate_unpreserve()?

If this is userspace-triggerable, maybe it's worth a meaningful
message including one or more of the device IDs from ser->devices[]?

> +	kho_unpreserve_free(ser);
> +}
> +
> +static int pci_flb_retrieve(struct liveupdate_flb_op_args *args)
> +{
> +	args->obj = phys_to_virt(args->data);
> +	return 0;
> +}
> +
> +static void pci_flb_finish(struct liveupdate_flb_op_args *args)
> +{
> +	kho_restore_free(args->obj);
> +}
> +
> +static struct liveupdate_flb_ops pci_liveupdate_flb_ops = {
> +	.preserve = pci_flb_preserve,
> +	.unpreserve = pci_flb_unpreserve,
> +	.retrieve = pci_flb_retrieve,
> +	.finish = pci_flb_finish,
> +	.owner = THIS_MODULE,
> +};
> +
> +static struct liveupdate_flb pci_liveupdate_flb = {
> +	.ops = &pci_liveupdate_flb_ops,
> +	.compatible = PCI_LUO_FLB_COMPATIBLE,
> +};
> +
> +#define INIT_PCI_DEV_SER(_dev) {		\
> +	.domain = pci_domain_nr((_dev)->bus),	\
> +	.bdf = pci_dev_id(_dev),		\
> +}
> +
> +static int pci_dev_ser_cmp(const void *__a, const void *__b)
> +{
> +	const struct pci_dev_ser *a = __a, *b = __b;
> +
> +	return cmp_int((u64)a->domain << 16 | a->bdf,
> +		       (u64)b->domain << 16 | b->bdf);
> +}
> +
> +static struct pci_dev_ser *pci_ser_find(struct pci_ser *ser,
> +					struct pci_dev *dev)
> +{
> +	const struct pci_dev_ser key = INIT_PCI_DEV_SER(dev);
> +
> +	return bsearch(&key, ser->devices, ser->nr_devices,
> +		       sizeof(key), pci_dev_ser_cmp);
> +}
> +
> +static void pci_ser_delete(struct pci_ser *ser, struct pci_dev *dev)
> +{
> +	struct pci_dev_ser *dev_ser;
> +	int i;
> +
> +	dev_ser = pci_ser_find(ser, dev);
> +
> +	/*
> +	 * This should never happen unless there is a kernel bug or
> +	 * corruption that causes the state in struct pci_ser to get
> +	 * out of sync with struct pci_dev.

Corruption can be a bug anywhere and isn't really worth mentioning,
but the "out of sync" part sounds like it glosses over something
important.

I guess this happens if there was no successful
pci_liveupdate_preserve(X) before calling
pci_liveupdate_unpreserve(X)?  That does sound like a kernel bug (I
suppose a VFIO or other driver bug?), and I would just say what
happened directly instead of calling it "out of sync".

> +	 */
> +	if (pci_WARN_ONCE(dev, !dev_ser, "Cannot find preserved device!"))

Seems like an every-time sort of message if this indicates a driver bug?

It's enough of a hassle to convince myself that pci_WARN_ONCE()
returns the value that caused the warning that I would prefer:

  if (!dev_ser) {
    pci_warn(...) or pci_WARN_ONCE(...)
    return;
  }

> +		return;
> +
> +	for (i = dev_ser - ser->devices; i < ser->nr_devices - 1; i++)
> +		ser->devices[i] = ser->devices[i + 1];
> +
> +	ser->nr_devices--;
> +}
> +
> +int pci_liveupdate_preserve(struct pci_dev *dev)
> +{
> +	struct pci_dev_ser new = INIT_PCI_DEV_SER(dev);
> +	struct pci_ser *ser;
> +	int i, ret;
> +
> +	/* SR-IOV is not supported yet. */
> +	if (dev->is_virtfn || dev->is_physfn)
> +		return -EINVAL;
> +
> +	guard(mutex)(&pci_flb_outgoing_lock);
> +
> +	if (dev->liveupdate_outgoing)
> +		return -EBUSY;
> +
> +	ret = liveupdate_flb_get_outgoing(&pci_liveupdate_flb, (void **)&ser);
> +	if (ret)
> +		return ret;
> +
> +	if (ser->nr_devices == ser->max_nr_devices)
> +		return -E2BIG;
> +
> +	for (i = ser->nr_devices; i > 0; i--) {
> +		struct pci_dev_ser *prev = &ser->devices[i - 1];
> +		int cmp = pci_dev_ser_cmp(&new, prev);
> +
> +		/*
> +		 * This should never happen unless there is a kernel bug or
> +		 * corruption that causes the state in struct pci_ser to get out
> +		 * of sync with struct pci_dev.

Huh.  Same comment as above.  I don't think this is telling me
anything useful.  I guess what happened is we're trying to preserve X
and X is already in "ser", but we should have returned -EBUSY above
for that case.  If we're just saying memory corruption could cause
bugs, I think that's pointless.

Actually I'm not even sure we should check for this.

> +		 */
> +		if (WARN_ON_ONCE(!cmp))
> +			return -EBUSY;
> +
> +		if (cmp > 0)
> +			break;
> +
> +		ser->devices[i] = *prev;
> +	}
> +
> +	ser->devices[i] = new;
> +	ser->nr_devices++;
> +	dev->liveupdate_outgoing = true;
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(pci_liveupdate_preserve);
> +
> +void pci_liveupdate_unpreserve(struct pci_dev *dev)
> +{
> +	struct pci_ser *ser;
> +	int ret;
> +
> +	/* This should never happen unless the caller (driver) is buggy */
> +	if (WARN_ON_ONCE(!dev->liveupdate_outgoing))

Why once?  Is there some situation where we could get a flood?  Since
we have a pci_dev, maybe a pci_warn() that would indicate the driver
and device would be more useful?

> +		return;
> +
> +	guard(mutex)(&pci_flb_outgoing_lock);
> +
> +	ret = liveupdate_flb_get_outgoing(&pci_liveupdate_flb, (void **)&ser);
> +
> +	/* This should never happen unless there is a bug in LUO */
> +	if (WARN_ON_ONCE(ret))

Is LUO completely in-kernel?  I think this warning message would be
kind of obscure if this is something that could be triggered by a
userspace bug.  Also, we do have the pci_dev, which a WARN_ON_ONCE()
doesn't take advantage of at all.

> +		return;
> +
> +	pci_ser_delete(ser, dev);
> +	dev->liveupdate_outgoing = false;
> +}
> +EXPORT_SYMBOL_GPL(pci_liveupdate_unpreserve);
> +
> +static int pci_liveupdate_flb_get_incoming(struct pci_ser **serp)
> +{
> +	int ret;
> +
> +	ret = liveupdate_flb_get_incoming(&pci_liveupdate_flb, (void **)serp);
> +
> +	/* Live Update is not enabled. */
> +	if (ret == -EOPNOTSUPP)
> +		return ret;
> +
> +	/* Live Update is enabled, but there is no incoming FLB data. */
> +	if (ret == -ENODATA)
> +		return ret;
> +
> +	/*
> +	 * Live Update is enabled and there is incoming FLB data, but none of it
> +	 * matches pci_liveupdate_flb.compatible.
> +	 *
> +	 * This could mean that no PCI FLB data was passed by the previous
> +	 * kernel, but it could also mean the previous kernel used a different
> +	 * compatibility string (i.e.a different ABI). The latter deserves at
> +	 * least a WARN_ON_ONCE() but it cannot be distinguished from the
> +	 * former.

This says both "there is incoming FLB data" and "no PCI FLB data".  I
guess maybe it's possible to have FLB data but no *PCI* FLB data?

s/i.e.a/i.e., /

> +	 */
> +	if (ret == -ENOENT) {
> +		pr_info_once("PCI: No incoming FLB data detected during Live Update");

Not sure "FLB" will be meaningful to users here.  Maybe we could say
something like ("no FLB data compatible with %s\n", pci_liveupdate_flb.compatible)?

> +		return ret;
> +	}
> +
> +	/*
> +	 * There is incoming FLB data that matches pci_liveupdate_flb.compatible
> +	 * but it cannot be retrieved. Proceed with standard initialization as
> +	 * if there was not incoming PCI FLB data.

s/if there was not/if there was no/

> +	 */
> +	WARN_ONCE(ret, "PCI: Failed to retrieve incoming FLB data during Live Update");
> +	return ret;
> +}
> +
> +u32 pci_liveupdate_incoming_nr_devices(void)
> +{
> +	struct pci_ser *ser;
> +
> +	if (pci_liveupdate_flb_get_incoming(&ser))
> +		return 0;

Seems slightly overcomplicated to return various error codes from
pci_liveupdate_flb_get_incoming(), only to throw them away here and
special-case the "return 0".  I think you *could* set
"ser->nr_devices" to zero at entry to
pci_liveupdate_flb_get_incoming() and make this just:

  pci_liveupdate_flb_get_incoming(&ser);
  return ser->nr_devices;

> +	return ser->nr_devices;
> +}
> +
> +void pci_liveupdate_setup_device(struct pci_dev *dev)
> +{
> +	struct pci_ser *ser;
> +
> +	if (pci_liveupdate_flb_get_incoming(&ser))
> +		return;
> +
> +	if (!pci_ser_find(ser, dev))
> +		return;

If pci_liveupdate_flb_get_incoming() set ser->nr_devices to zero at
entry, the bsearch() in pci_ser_find() would return NULL if there were
no devices to search:

  pci_liveupdate_flb_get_incoming(&ser);
  if (!pci_ser_find(ser, dev))
    return;

> +	dev->liveupdate_incoming = true;
> +}
> +
> +int pci_liveupdate_retrieve(struct pci_dev *dev)
> +{
> +	if (!dev->liveupdate_incoming)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(pci_liveupdate_retrieve);
> +
> +void pci_liveupdate_finish(struct pci_dev *dev)
> +{
> +	dev->liveupdate_incoming = false;
> +}
> +EXPORT_SYMBOL_GPL(pci_liveupdate_finish);
> +
> +int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh)
> +{
> +	return liveupdate_register_flb(fh, &pci_liveupdate_flb);
> +}
> +EXPORT_SYMBOL_GPL(pci_liveupdate_register_flb);
> +
> +void pci_liveupdate_unregister_flb(struct liveupdate_file_handler *fh)
> +{
> +	liveupdate_unregister_flb(fh, &pci_liveupdate_flb);
> +}
> +EXPORT_SYMBOL_GPL(pci_liveupdate_unregister_flb);
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 13d998fbacce..979cb9921340 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -1434,4 +1434,18 @@ static inline int pci_msix_write_tph_tag(struct pci_dev *pdev, unsigned int inde
>  	(PCI_CONF1_ADDRESS(bus, dev, func, reg) | \
>  	 PCI_CONF1_EXT_REG(reg))
>  
> +#ifdef CONFIG_PCI_LIVEUPDATE
> +void pci_liveupdate_setup_device(struct pci_dev *dev);
> +u32 pci_liveupdate_incoming_nr_devices(void);
> +#else
> +static inline void pci_liveupdate_setup_device(struct pci_dev *dev)
> +{
> +}
> +
> +static inline u32 pci_liveupdate_incoming_nr_devices(void)
> +{
> +	return 0;
> +}
> +#endif
> +
>  #endif /* DRIVERS_PCI_H */
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index bccc7a4bdd79..c60222d45659 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -2064,6 +2064,8 @@ int pci_setup_device(struct pci_dev *dev)
>  	if (pci_early_dump)
>  		early_dump_pci_device(dev);
>  
> +	pci_liveupdate_setup_device(dev);
> +
>  	/* Need to have dev->class ready */
>  	dev->cfg_size = pci_cfg_space_size(dev);
>  
> diff --git a/include/linux/kho/abi/pci.h b/include/linux/kho/abi/pci.h
> new file mode 100644
> index 000000000000..7764795f6818
> --- /dev/null
> +++ b/include/linux/kho/abi/pci.h

It seems like most of include/linux/ is ABI, so does kho/abi/ need to
be separated out in its own directory?

It's kind of unusual for the hierarchy to be this deep, especially
since abi/ is the only thing in include/linux/kho/.

^ permalink raw reply

* Re: [PATCH v3 03/24] PCI: Require Live Update preserved devices are in singleton iommu_groups
From: Bjorn Helgaas @ 2026-03-25 23:13 UTC (permalink / raw)
  To: David Matlack
  Cc: Alex Williamson, Bjorn Helgaas, Adithya Jayachandran,
	Alexander Graf, Alex Mastro, Andrew Morton, Ankit Agrawal,
	Arnd Bergmann, Askar Safin, Borislav Petkov (AMD), Chris Li,
	Dapeng Mi, David Rientjes, Feng Tang, Jacob Pan, Jason Gunthorpe,
	Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Kees Cook,
	Kevin Tian, kexec, kvm, Leon Romanovsky, Leon Romanovsky,
	linux-doc, linux-kernel, linux-kselftest, linux-mm, linux-pci,
	Li RongQing, Lukas Wunner, Marco Elver, Michał Winiarski,
	Mike Rapoport, Parav Pandit, Pasha Tatashin, Paul E. McKenney,
	Pawan Gupta, Peter Zijlstra (Intel), Pranjal Shrivastava,
	Pratyush Yadav, Raghavendra Rao Ananta, Randy Dunlap,
	Rodrigo Vivi, Saeed Mahameed, Samiullah Khawaja, Shuah Khan,
	Vipin Sharma, Vivek Kasireddy, William Tu, Yi Liu, Zhu Yanjun
In-Reply-To: <20260323235817.1960573-4-dmatlack@google.com>

On Mon, Mar 23, 2026 at 11:57:55PM +0000, David Matlack wrote:
> Require that Live Update preserved devices are in singleton iommu_groups
> during preservation (outgoing kernel) and retrieval (incoming kernel).
> 
> PCI devices preserved across Live Update will be allowed to perform
> memory transactions throughout the Live Update. Thus IOMMU groups for
> preserved devices must remain fixed. Since all current use cases for
> Live Update are for PCI devices in singleton iommu_groups, require that
> as a starting point. This avoids the complexity of needing to enforce
> arbitrary iommu_group topologies while still allowing all current use
> cases.
> 
> Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: David Matlack <dmatlack@google.com>
> ---
>  drivers/pci/liveupdate.c | 34 +++++++++++++++++++++++++++++++++-
>  1 file changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
> index bec7b3500057..a3dbe06650ff 100644
> --- a/drivers/pci/liveupdate.c
> +++ b/drivers/pci/liveupdate.c
> @@ -75,6 +75,8 @@
>   *
>   *  * The device must not be a Physical Function (PF).
>   *
> + *  * The device must be the only device in its IOMMU group.
> + *
>   * Preservation Behavior
>   * =====================
>   *
> @@ -105,6 +107,7 @@
>  
>  #include <linux/bsearch.h>
>  #include <linux/io.h>
> +#include <linux/iommu.h>
>  #include <linux/kexec_handover.h>
>  #include <linux/kho/abi/pci.h>
>  #include <linux/liveupdate.h>
> @@ -222,6 +225,31 @@ static void pci_ser_delete(struct pci_ser *ser, struct pci_dev *dev)
>  	ser->nr_devices--;
>  }
>  
> +static int count_devices(struct device *dev, void *__nr_devices)
> +{
> +	(*(int *)__nr_devices)++;
> +	return 0;
> +}
> +
> +static int pci_liveupdate_validate_iommu_group(struct pci_dev *dev)
> +{
> +	struct iommu_group *group;
> +	int nr_devices = 0;
> +
> +	group = iommu_group_get(&dev->dev);
> +	if (group) {
> +		iommu_group_for_each_dev(group, &nr_devices, count_devices);
> +		iommu_group_put(group);
> +	}
> +
> +	if (nr_devices != 1) {
> +		pci_warn(dev, "Live Update preserved devices must be in singleton iommu groups!");
> +		return -EINVAL;
> +	}
> +
> +	return 0;

I assume the requirement is that there *is* an iommu_group and also
that dev is the only member.  If so, I think the intent would be a
little clearer as:

    group = iommu_group_get(&dev->dev);
    if (!group)
      goto no_group;

    iommu_group_for_each_dev(group, &nr_devices, count_devices);
    iommu_group_put(group);

    if (nr_devices == 1) {
      return 0;

  no_group:
    pci_warn(...);
    return -EINVAL;

> +}
> +
>  int pci_liveupdate_preserve(struct pci_dev *dev)
>  {
>  	struct pci_dev_ser new = INIT_PCI_DEV_SER(dev);
> @@ -232,6 +260,10 @@ int pci_liveupdate_preserve(struct pci_dev *dev)
>  	if (dev->is_virtfn || dev->is_physfn)
>  		return -EINVAL;
>  
> +	ret = pci_liveupdate_validate_iommu_group(dev);
> +	if (ret)
> +		return ret;
> +
>  	guard(mutex)(&pci_flb_outgoing_lock);
>  
>  	if (dev->liveupdate_outgoing)
> @@ -357,7 +389,7 @@ int pci_liveupdate_retrieve(struct pci_dev *dev)
>  	if (!dev->liveupdate_incoming)
>  		return -EINVAL;
>  
> -	return 0;
> +	return pci_liveupdate_validate_iommu_group(dev);
>  }
>  EXPORT_SYMBOL_GPL(pci_liveupdate_retrieve);
>  
> -- 
> 2.53.0.983.g0bb29b3bc5-goog
> 

^ permalink raw reply

* Re: [PATCH v9 net-next 00/11] nbl driver for Nebulamatrix NICs
From: Jakub Kicinski @ 2026-03-25 23:29 UTC (permalink / raw)
  To: illusion.wang
  Cc: dimon.zhao, alvin.wang, sam.chen, netdev, andrew+netdev, corbet,
	linux-doc, lorenzo, pabeni, horms, vadim.fedorenko, lukas.bulwahn,
	edumazet, open list
In-Reply-To: <20260325040048.2313-1-illusion.wang@nebula-matrix.com>

On Wed, 25 Mar 2026 12:00:32 +0800 illusion.wang wrote:
> This patch series represents the first phase. We plan to integrate it in
> two phases: the first phase covers mailbox and chip configuration,
> while the second phase involves net dev configuration.
> Together, they will provide basic PF-based Ethernet port transmission and
> reception capabilities.
> 
> After that, we will consider other features, such as ethtool support,
> flow management, adminq messaging, VF support, debugfs support, etc.

Documentation/networking/device_drivers/ethernet/nebula-matrix/nbl.rst:3: (SEVERE/4) Title overline & underline mismatch.
    
    =====================================================
    Linux Base Driver for Nebula-matrix M18000-NIC family
    ======================================================
-- 
pw-bot: cr

^ permalink raw reply

* [PATCH v2 0/4] clk: update kernel docs
From: Brian Masney @ 2026-03-25 23:52 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Maxime Ripard, Jonathan Corbet,
	Shuah Khan
  Cc: linux-clk, linux-kernel, linux-doc, Brian Masney

Here's a small series that updates the kernel documentation for struct
clk_core, moves the clk flags into a new enum so that they can be shown
in the documentation, and updates the clk kunit test to use HZ_PER_MHZ.

Since I've been doing a lot of work in the clk subsystem lately, I would
like to add some more documentation about this subsystem in the future
as I have time. There's a lot of other things that I know can be done
now, and I'd like to just start with these small changes merged.

Changes in v2:
- Add clk_core_flags enum, and kernel doc for this.
- Update descriptions in clk_core based on feedback from Stephen.
- Update clk kernel docs to show some of the new API documentation.
- Link to v1: https://lore.kernel.org/r/20260304-clk-docs-v1-0-fee468db99f1@redhat.com

Merge Strategy
--------------
Since there is a new enum that's added, and it's referenced in the
docoumentation, all of these patches will need to go through Stephen's
tree.

Signed-off-by: Brian Masney <bmasney@redhat.com>
---
Brian Masney (4):
      clk: move core flags into a new enum for kernel docs
      clk: add kernel docs for struct clk_core
      docs: clk: include some identifiers to keep documentation up to date
      clk: test: convert constants to use HZ_PER_MHZ

 Documentation/driver-api/clk.rst | 58 +++++++---------------------------------
 drivers/clk/clk.c                | 51 +++++++++++++++++++++++++++++++++++
 drivers/clk/clk_test.c           |  7 ++---
 include/linux/clk-provider.h     | 55 ++++++++++++++++++++++---------------
 4 files changed, 98 insertions(+), 73 deletions(-)
---
base-commit: 85964cdcad0fac9a0eb7b87a0f9d88cc074b854c
change-id: 20260304-clk-docs-0b578f421600

Best regards,
-- 
Brian Masney <bmasney@redhat.com>


^ permalink raw reply

* [PATCH v2 2/4] clk: add kernel docs for struct clk_core
From: Brian Masney @ 2026-03-25 23:52 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Maxime Ripard, Jonathan Corbet,
	Shuah Khan
  Cc: linux-clk, linux-kernel, linux-doc, Brian Masney
In-Reply-To: <20260325-clk-docs-v2-0-bcf660e1ceb5@redhat.com>

Document all of the members of struct clk_core.

Signed-off-by: Brian Masney <bmasney@redhat.com>
---
 drivers/clk/clk.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 47093cda9df32223c1120c3710261296027c4cd3..08b38ec044db7e50c7313b8f44cc0f6fa2cd4755 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -63,6 +63,57 @@ struct clk_parent_map {
 	int			index;
 };
 
+/**
+ * struct clk_core - The internal state of a clk in the clk tree.
+ * @name:              Unique name of the clk for identification.
+ * @ops:               Pointer to hardware-specific operations for this clk.
+ * @hw:                Pointer for traversing from a struct clk to its
+ *                     corresponding hardware-specific structure.
+ * @owner:             Kernel module owning this clk (for reference counting).
+ * @dev:               Device associated with this clk (optional)
+ * @rpm_node:          Node for runtime power management list management.
+ * @of_node:           Device tree node associated with this clk (if applicable)
+ * @parent:            Pointer to the current parent in the clock tree.
+ * @parents:           Array of possible parents (for muxes/selectable parents).
+ * @num_parents:       Number of possible parents.
+ * @new_parent_index:  Index of the new parent during parent change operations.
+ * @rate:              Current cached clock rate (Hz).
+ * @req_rate:          The last rate requested by a call to clk_set_rate(). It's
+ *                     initialized to clk_core->rate. It's also updated to
+ *                     clk_core->rate every time the clock is reparented, and
+ *                     when we're doing the orphan -> !orphan transition.
+ * @new_rate:          New rate to be set during a rate change operation.
+ * @new_parent:        Pointer to new parent during parent change. This is also
+ *                     used when a clk's rate is changed.
+ * @new_child:         Pointer to new child during reparenting. This is also
+ *                     used when a clk's rate is changed.
+ * @flags:             Clock property and capability flags in the
+ *                     enum clk_core_flags.
+ * @orphan:            True if this clk is currently orphaned.
+ * @rpm_enabled:       True if runtime power management is enabled for this clk.
+ * @enable_count:      Reference count of enables.
+ * @prepare_count:     Reference count of prepares.
+ * @protect_count:     Protection reference count against disable.
+ * @min_rate:          Minimum supported clock rate (Hz).
+ * @max_rate:          Maximum supported clock rate (Hz).
+ * @accuracy:          Accuracy of the clock rate (parts per billion).
+ * @phase:             Current phase (degrees).
+ * @duty:              Current duty cycle configuration (as ratio: num/den).
+ * @children:          All of the children of this clk.
+ * @child_node:        Node for linking as a child in the parent's list.
+ * @hashtable_node:    Node for hash table that allows fast clk lookup by name.
+ * @clks:              All of the clk consumers registered.
+ * @notifier_count:    Number of notifiers registered for this clk.
+ * @dentry:            DebugFS entry for this clk.
+ * @debug_node:        DebugFS node for this clk.
+ * @ref:               Reference count for structure lifetime management.
+ *
+ * Managed by the clk framework. Clk providers and consumers do not interact
+ * with this structure directly. Instead, clk operations flow through the
+ * framework and the framework manipulates this structure to keep track of
+ * parent/child relationships, rate, enable state, etc.
+ *
+ */
 struct clk_core {
 	const char		*name;
 	const struct clk_ops	*ops;

-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 1/4] clk: move core flags into a new enum for kernel docs
From: Brian Masney @ 2026-03-25 23:52 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Maxime Ripard, Jonathan Corbet,
	Shuah Khan
  Cc: linux-clk, linux-kernel, linux-doc, Brian Masney
In-Reply-To: <20260325-clk-docs-v2-0-bcf660e1ceb5@redhat.com>

Let's move all of the existing clk flags into a new enum so that all of
the flags can be easily referenced in the kernel documentation. Note
that I went with name clk_core_flags for the enum since the name
clk_flags is already in use in clk.c for the debugfs interface.

Note: The comment about "Please update clk_flags..." is included as a
separate comment so it doesn't show up in the generated documents.

Signed-off-by: Brian Masney <bmasney@redhat.com>
---
 include/linux/clk-provider.h | 55 +++++++++++++++++++++++++++-----------------
 1 file changed, 34 insertions(+), 21 deletions(-)

diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 630705a47129453c241f1b1755f2c2f2a7ed8f77..cb167c17c4f79cf438a26bb113b4968d0f223468 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -9,29 +9,42 @@
 #include <linux/of.h>
 #include <linux/of_clk.h>
 
-/*
- * flags used across common struct clk.  these flags should only affect the
- * top-level framework.  custom flags for dealing with hardware specifics
- * belong in struct clk_foo
+/* Please update clk_flags[] in drivers/clk/clk.c when making changes here! */
+/**
+ * enum clk_core_flags - framework-level clock flags
  *
- * Please update clk_flags[] in drivers/clk/clk.c when making changes here!
+ * These flags should only affect the top-level framework. Custom flags for
+ * dealing with hardware specifics belong in struct clk_foo.
+ *
+ * @CLK_SET_RATE_GATE: must be gated across rate change
+ * @CLK_SET_PARENT_GATE: must be gated across re-parent
+ * @CLK_SET_RATE_PARENT: propagate rate change up one level
+ * @CLK_IGNORE_UNUSED: do not gate even if unused
+ * @CLK_GET_RATE_NOCACHE: do not use the cached clk rate
+ * @CLK_SET_RATE_NO_REPARENT: don't re-parent on rate change
+ * @CLK_GET_ACCURACY_NOCACHE: do not use the cached clk accuracy
+ * @CLK_RECALC_NEW_RATES: recalc rates after notifications
+ * @CLK_SET_RATE_UNGATE: clock needs to run to set rate
+ * @CLK_IS_CRITICAL: do not gate, ever
+ * @CLK_OPS_PARENT_ENABLE: parents need enable during gate/ungate, set rate and re-parent
+ * @CLK_DUTY_CYCLE_PARENT: duty cycle call may be forwarded to the parent clock
  */
-#define CLK_SET_RATE_GATE	BIT(0) /* must be gated across rate change */
-#define CLK_SET_PARENT_GATE	BIT(1) /* must be gated across re-parent */
-#define CLK_SET_RATE_PARENT	BIT(2) /* propagate rate change up one level */
-#define CLK_IGNORE_UNUSED	BIT(3) /* do not gate even if unused */
-				/* unused */
-				/* unused */
-#define CLK_GET_RATE_NOCACHE	BIT(6) /* do not use the cached clk rate */
-#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
-#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
-#define CLK_RECALC_NEW_RATES	BIT(9) /* recalc rates after notifications */
-#define CLK_SET_RATE_UNGATE	BIT(10) /* clock needs to run to set rate */
-#define CLK_IS_CRITICAL		BIT(11) /* do not gate, ever */
-/* parents need enable during gate/ungate, set rate and re-parent */
-#define CLK_OPS_PARENT_ENABLE	BIT(12)
-/* duty cycle call may be forwarded to the parent clock */
-#define CLK_DUTY_CYCLE_PARENT	BIT(13)
+enum clk_core_flags {
+	CLK_SET_RATE_GATE		= BIT(0),
+	CLK_SET_PARENT_GATE		= BIT(1),
+	CLK_SET_RATE_PARENT		= BIT(2),
+	CLK_IGNORE_UNUSED		= BIT(3),
+	/* unused */
+	/* unused */
+	CLK_GET_RATE_NOCACHE		= BIT(6),
+	CLK_SET_RATE_NO_REPARENT	= BIT(7),
+	CLK_GET_ACCURACY_NOCACHE	= BIT(8),
+	CLK_RECALC_NEW_RATES		= BIT(9),
+	CLK_SET_RATE_UNGATE		= BIT(10),
+	CLK_IS_CRITICAL			= BIT(11),
+	CLK_OPS_PARENT_ENABLE		= BIT(12),
+	CLK_DUTY_CYCLE_PARENT		= BIT(13),
+};
 
 struct clk;
 struct clk_hw;

-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 3/4] docs: clk: include some identifiers to keep documentation up to date
From: Brian Masney @ 2026-03-25 23:52 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Maxime Ripard, Jonathan Corbet,
	Shuah Khan
  Cc: linux-clk, linux-kernel, linux-doc, Brian Masney
In-Reply-To: <20260325-clk-docs-v2-0-bcf660e1ceb5@redhat.com>

The clk documentation currently has a separate list of some members of
struct clk_core and struct clk_ops. Now that all of these structures
have proper kernel docs, let's go ahead and just include them here via
the identifiers statement in kerneldoc.

While changes are being made here, let's also include the newly-added
enum clk_core_flags.

Signed-off-by: Brian Masney <bmasney@redhat.com>
---
 Documentation/driver-api/clk.rst | 58 +++++++---------------------------------
 1 file changed, 9 insertions(+), 49 deletions(-)

diff --git a/Documentation/driver-api/clk.rst b/Documentation/driver-api/clk.rst
index 93bab5336dfda06069eea700d2830089bf3bce03..d3e93519114637b3a70067128192dd302bedad4b 100644
--- a/Documentation/driver-api/clk.rst
+++ b/Documentation/driver-api/clk.rst
@@ -42,21 +42,8 @@ clock interface.
 Common data structures and api
 ==============================
 
-Below is the common struct clk_core definition from
-drivers/clk/clk.c, modified for brevity::
-
-	struct clk_core {
-		const char		*name;
-		const struct clk_ops	*ops;
-		struct clk_hw		*hw;
-		struct module		*owner;
-		struct clk_core		*parent;
-		const char		**parent_names;
-		struct clk_core		**parents;
-		u8			num_parents;
-		u8			new_parent_index;
-		...
-	};
+.. kernel-doc:: drivers/clk/clk.c
+   :identifiers: struct clk_core
 
 The members above make up the core of the clk tree topology.  The clk
 api itself defines several driver-facing functions which operate on
@@ -64,41 +51,14 @@ struct clk.  That api is documented in include/linux/clk.h.
 
 Platforms and devices utilizing the common struct clk_core use the struct
 clk_ops pointer in struct clk_core to perform the hardware-specific parts of
-the operations defined in clk-provider.h::
+the operations defined in clk-provider.h, and can set one or more
+framework-level flags in the enum clk_core_flags.
 
-	struct clk_ops {
-		int		(*prepare)(struct clk_hw *hw);
-		void		(*unprepare)(struct clk_hw *hw);
-		int		(*is_prepared)(struct clk_hw *hw);
-		void		(*unprepare_unused)(struct clk_hw *hw);
-		int		(*enable)(struct clk_hw *hw);
-		void		(*disable)(struct clk_hw *hw);
-		int		(*is_enabled)(struct clk_hw *hw);
-		void		(*disable_unused)(struct clk_hw *hw);
-		unsigned long	(*recalc_rate)(struct clk_hw *hw,
-						unsigned long parent_rate);
-		long		(*round_rate)(struct clk_hw *hw,
-						unsigned long rate,
-						unsigned long *parent_rate);
-		int		(*determine_rate)(struct clk_hw *hw,
-						  struct clk_rate_request *req);
-		int		(*set_parent)(struct clk_hw *hw, u8 index);
-		u8		(*get_parent)(struct clk_hw *hw);
-		int		(*set_rate)(struct clk_hw *hw,
-					    unsigned long rate,
-					    unsigned long parent_rate);
-		int		(*set_rate_and_parent)(struct clk_hw *hw,
-					    unsigned long rate,
-					    unsigned long parent_rate,
-					    u8 index);
-		unsigned long	(*recalc_accuracy)(struct clk_hw *hw,
-						unsigned long parent_accuracy);
-		int		(*get_phase)(struct clk_hw *hw);
-		int		(*set_phase)(struct clk_hw *hw, int degrees);
-		void		(*init)(struct clk_hw *hw);
-		void		(*debug_init)(struct clk_hw *hw,
-					      struct dentry *dentry);
-	};
+.. kernel-doc:: include/linux/clk-provider.h
+   :identifiers: struct clk_ops
+
+.. kernel-doc:: include/linux/clk-provider.h
+   :identifiers: enum clk_core_flags
 
 Hardware clk implementations
 ============================

-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 4/4] clk: test: convert constants to use HZ_PER_MHZ
From: Brian Masney @ 2026-03-25 23:52 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Maxime Ripard, Jonathan Corbet,
	Shuah Khan
  Cc: linux-clk, linux-kernel, linux-doc, Brian Masney
In-Reply-To: <20260325-clk-docs-v2-0-bcf660e1ceb5@redhat.com>

Convert the DUMMY_CLOCK_* constants over to use HZ_PER_MHZ.

Signed-off-by: Brian Masney <bmasney@redhat.com>
---
 drivers/clk/clk_test.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
index a268d7b5d4cb28ec1f029f828c31107f8e130556..372dd289a7ba148a0725ea0643342ccda7196216 100644
--- a/drivers/clk/clk_test.c
+++ b/drivers/clk/clk_test.c
@@ -7,6 +7,7 @@
 #include <linux/clk/clk-conf.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/units.h>
 
 /* Needed for clk_hw_get_clk() */
 #include "clk.h"
@@ -21,9 +22,9 @@
 
 static const struct clk_ops empty_clk_ops = { };
 
-#define DUMMY_CLOCK_INIT_RATE	(42 * 1000 * 1000)
-#define DUMMY_CLOCK_RATE_1	(142 * 1000 * 1000)
-#define DUMMY_CLOCK_RATE_2	(242 * 1000 * 1000)
+#define DUMMY_CLOCK_INIT_RATE		(42 * HZ_PER_MHZ)
+#define DUMMY_CLOCK_RATE_1		(142 * HZ_PER_MHZ)
+#define DUMMY_CLOCK_RATE_2		(242 * HZ_PER_MHZ)
 
 struct clk_dummy_context {
 	struct clk_hw hw;

-- 
2.53.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox