Linux Documentation
 help / color / mirror / Atom feed
* Re: [PATCH 1/4] block: add a macro to initialize the status table
From: Christoph Hellwig @ 2026-06-08  5:09 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Christoph Hellwig, Jens Axboe, Jonathan Corbet, linux-block,
	linux-doc, Keith Busch
In-Reply-To: <aiMZ-PXXQ-NxOHT4@casper.infradead.org>

On Fri, Jun 05, 2026 at 07:48:24PM +0100, Matthew Wilcox wrote:
> On Fri, Jun 05, 2026 at 08:44:27PM +0200, Christoph Hellwig wrote:
> > Prepare for adding a new value to the error table by adding a macro
> > to fill it.
> 
> > +#define ENT(_tag, _errno, _desc)	\
> > +[BLK_STS_##_tag] = {				\
> > +	.errno		= _errno,		\
> > +	.name		= _desc,		\
> 
> Bleh.  I hate this.  Before, I can grep for BLK_STS_NOSPC and find it.

You will still find BLK_STS_NOSPC itself in include/linux/blk_types.h

> After, I can't.  Yes, I know we have a lot of such things already, but
> I don't like adding more.

I'm not a huge fan off CPP pasting, and especially thing we should never
use it to define global symbols (hi page/folio flag helpers!), and in
general try to avoid using them as much as possible.  But I think here
the need to keep the names in sync with the tags exposed in debugfs is
more important than the grepability.  Especially as this sits in _the_
core block file, so it can't be easily missed.

^ permalink raw reply

* Re: [PATCH mm-unstable v19 06/14] mm/khugepaged: generalize collapse_huge_page for mTHP collapse
From: Lance Yang @ 2026-06-08  4:54 UTC (permalink / raw)
  To: npache
  Cc: linux-doc, linux-kernel, linux-mm, linux-trace-kernel, aarcange,
	akpm, anshuman.khandual, apopple, baohua, baolin.wang, byungchul,
	catalin.marinas, cl, corbet, dave.hansen, david, dev.jain, gourry,
	hannes, hughd, jack, jackmanb, jannh, jglisse, joshua.hahnjy, kas,
	lance.yang, liam, ljs, mathieu.desnoyers, matthew.brost, mhiramat,
	mhocko, peterx, pfalcato, rakie.kim, raquini, rdunlap,
	richard.weiyang, rientjes, rostedt, rppt, ryan.roberts, shivankg,
	sunnanyong, surenb, thomas.hellstrom, tiwai, usamaarif642, vbabka,
	vishal.moola, wangkefeng.wang, will, willy, yang, ying.huang, ziy,
	zokeefe
In-Reply-To: <20260605161422.213817-7-npache@redhat.com>


On Fri, Jun 05, 2026 at 10:14:13AM -0600, Nico Pache wrote:
>Pass an order to collapse_huge_page to support collapsing anon memory to
>arbitrary orders within a PMD. order indicates what mTHP size we are
>attempting to collapse to.
>
>For non-PMD collapse we must leave the anon VMA write locked until after
>we collapse the mTHP-- in the PMD case all the pages are isolated, but in
>the mTHP case this is not true, and we must keep the lock to prevent
>access/changes to the page tables. This can happen if the rmap walkers hit
>a pmd_none while the PMD entry is currently unavailable due to being
>temporarily removed during the collapse phase.
>
>To properly establish the page table hierarchy without violating any
>expectations from certain architectures (e.g. MIPS), we must make sure to
>have the PMD reinstalled before the PTEs, and hold both PTE/PMD locks
>before calling update_mmu_cache_range() (if they are distinct locks).
>
>Signed-off-by: Nico Pache <npache@redhat.com>
>---

Nothing else jumped out at me. Anything left can be sorted out later, as
David and Lorenzo said :)

Reviewed-by: Lance Yang <lance.yang@linux.dev>

^ permalink raw reply

* Re: [PATCH mm-unstable v19 05/14] mm/khugepaged: require collapse_huge_page to enter/exit with the lock dropped
From: Lance Yang @ 2026-06-08  4:34 UTC (permalink / raw)
  To: npache
  Cc: linux-doc, linux-kernel, linux-mm, linux-trace-kernel, aarcange,
	akpm, anshuman.khandual, apopple, baohua, baolin.wang, byungchul,
	catalin.marinas, cl, corbet, dave.hansen, david, dev.jain, gourry,
	hannes, hughd, jack, jackmanb, jannh, jglisse, joshua.hahnjy, kas,
	lance.yang, liam, ljs, mathieu.desnoyers, matthew.brost, mhiramat,
	mhocko, peterx, pfalcato, rakie.kim, raquini, rdunlap,
	richard.weiyang, rientjes, rostedt, rppt, ryan.roberts, shivankg,
	sunnanyong, surenb, thomas.hellstrom, tiwai, usamaarif642, vbabka,
	vishal.moola, wangkefeng.wang, will, willy, yang, ying.huang, ziy,
	zokeefe
In-Reply-To: <20260605161422.213817-6-npache@redhat.com>


On Fri, Jun 05, 2026 at 10:14:12AM -0600, Nico Pache wrote:
>Currently the collapse_huge_page function requires the mmap_read_lock to
>enter with it held, and exit with it dropped. This function moves the
>unlock into its parent caller, and changes this semantic to requiring it
>to enter/exit with it always unlocked.
>
>In future patches, we need this expectation, as for in mTHP collapse, we
>may have already dropped the lock, and do not want to conditionally
>check for this by passing through the lock_dropped variable.
>
>No functional change is expected as one of the first things the
>collapse_huge_page function does is drop this lock before allocating the
>hugepage.
>
>Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
>Acked-by: David Hildenbrand (Arm) <david@kernel.org>
>Signed-off-by: Nico Pache <npache@redhat.com>
>---

Reviewed-by: Lance Yang <lance.yang@linux.dev>

^ permalink raw reply

* Re: [PATCH v3 3/6] alloc_tag: add size-based filtering to ioctl
From: Hao Ge @ 2026-06-08  4:09 UTC (permalink / raw)
  To: Abhishek Bapat, Suren Baghdasaryan, Andrew Morton,
	Kent Overstreet
  Cc: Shuah Khan, Jonathan Corbet, linux-doc, linux-kernel, linux-mm,
	Sourav Panda
In-Reply-To: <ef88e52368463e312086a966f10287a29d0edeca.1780701922.git.abhishekbapat@google.com>

Hi Abhishek


Thanks for the new version.


On 2026/6/6 07:36, Abhishek Bapat wrote:
> Extend the allocinfo filtering mechanism to allow users to filter tags
> based on the total number of bytes allocated [min_size, max_size]. The
> size range is inclusive.
>
> Filtering by size involves retrieving allocinfo per-CPU counters, which
> is an expensive operation. Hence, the performance of size-based
> filtering will be worse than other filters.
>
> Signed-off-by: Abhishek Bapat <abhishekbapat@google.com>
> ---
>   include/uapi/linux/alloc_tag.h |  8 +++-
>   lib/alloc_tag.c                | 68 +++++++++++++++++++++++++++-------
>   2 files changed, 62 insertions(+), 14 deletions(-)
>
> diff --git a/include/uapi/linux/alloc_tag.h b/include/uapi/linux/alloc_tag.h
> index cffb0c46e0b1..0e648192df4d 100644
> --- a/include/uapi/linux/alloc_tag.h
> +++ b/include/uapi/linux/alloc_tag.h
> @@ -39,13 +39,17 @@ enum {
>   	ALLOCINFO_FILTER_FUNCTION,
>   	ALLOCINFO_FILTER_FILENAME,
>   	ALLOCINFO_FILTER_LINENO,
> -	__ALLOCINFO_FILTER_LAST = ALLOCINFO_FILTER_LINENO
> +	ALLOCINFO_FILTER_MIN_SIZE,
> +	ALLOCINFO_FILTER_MAX_SIZE,
> +	__ALLOCINFO_FILTER_LAST = ALLOCINFO_FILTER_MAX_SIZE
>   };
>   
>   #define ALLOCINFO_FILTER_MASK_MODNAME		(1 << ALLOCINFO_FILTER_MODNAME)
>   #define ALLOCINFO_FILTER_MASK_FUNCTION		(1 << ALLOCINFO_FILTER_FUNCTION)
>   #define ALLOCINFO_FILTER_MASK_FILENAME		(1 << ALLOCINFO_FILTER_FILENAME)
>   #define ALLOCINFO_FILTER_MASK_LINENO		(1 << ALLOCINFO_FILTER_LINENO)
> +#define ALLOCINFO_FILTER_MASK_MIN_SIZE		(1 << ALLOCINFO_FILTER_MIN_SIZE)
> +#define ALLOCINFO_FILTER_MASK_MAX_SIZE		(1 << ALLOCINFO_FILTER_MAX_SIZE)
>   
>   #define ALLOCINFO_FILTER_MASKS \
>   	((1 << (__ALLOCINFO_FILTER_LAST + 1)) - 1)
> @@ -53,6 +57,8 @@ enum {
>   struct allocinfo_filter {
>   	__u64 mask; /* bitmask of the filter fields used */
>   	struct allocinfo_tag fields;
> +	__u64 min_size;
> +	__u64 max_size;
>   };
>   
>   struct allocinfo_get_at {
> diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c
> index 93bc976ac505..ddc6946f56ab 100644
> --- a/lib/alloc_tag.c
> +++ b/lib/alloc_tag.c
> @@ -191,15 +191,26 @@ static int allocinfo_cmp_str(const char *str, const char *template)
>   	return strncmp(allocinfo_str(str), template, ALLOCINFO_STR_SIZE);
>   }
>   
> +/* Fetch the per-CPU counters */
> +static inline struct alloc_tag_counters allocinfo_prefetch_counters(struct codetag *ct)
> +{
> +	return alloc_tag_read(ct_to_alloc_tag(ct));
> +}
> +
>   /*
>    * Populates the UAPI allocinfo_tag_data structure with active runtime
>    * profiling counters extracted from the given kernel codetag.
>    */
>   static void allocinfo_to_params(struct codetag *ct,
> -				struct allocinfo_tag_data *data)
> +				struct allocinfo_tag_data *data,
> +				struct alloc_tag_counters *counters)
>   {
> -	struct alloc_tag *tag = ct_to_alloc_tag(ct);
> -	struct alloc_tag_counters counter = alloc_tag_read(tag);
> +	struct alloc_tag_counters local_counters;
> +
> +	if (!counters) {
> +		local_counters = allocinfo_prefetch_counters(ct);
> +		counters = &local_counters;
> +	}
>   
>   	if (ct->modname)
>   		allocinfo_copy_str(data->tag.modname, ct->modname);
> @@ -208,9 +219,9 @@ static void allocinfo_to_params(struct codetag *ct,
>   	allocinfo_copy_str(data->tag.function, ct->function);
>   	allocinfo_copy_str(data->tag.filename, ct->filename);
>   	data->tag.lineno = ct->lineno;
> -	data->counter.bytes = counter.bytes;
> -	data->counter.calls = counter.calls;
> -	data->counter.accurate = !alloc_tag_is_inaccurate(tag);
> +	data->counter.bytes = counters->bytes;
> +	data->counter.calls = counters->calls;
> +	data->counter.accurate = !alloc_tag_is_inaccurate(ct_to_alloc_tag(ct));
>   }
>   
>   /*
> @@ -234,7 +245,9 @@ static int allocinfo_ioctl_get_content_id(struct seq_file *m, void __user *arg)
>    * Verifies whether a given codetag satisfies the active filtering criteria by
>    * matching it's characteristics against the specified filter.
>    */
> -static bool matches_filter(struct codetag *ct, struct allocinfo_filter *filter)
> +static bool matches_filter(struct codetag *ct, struct allocinfo_filter *filter,
> +			   struct alloc_tag_counters *counters,
> +			   bool *fetched_counters)
>   {
>   	if (!filter || !filter->mask)
>   		return true;
> @@ -247,20 +260,34 @@ static bool matches_filter(struct codetag *ct, struct allocinfo_filter *filter)
>   				return false;
>   		} else if (allocinfo_cmp_str(ct->modname, filter->fields.modname))
>   			return false;
> +		}
It seems an extra } was accidentally added here
>   	}
>   
>   	if ((filter->mask & ALLOCINFO_FILTER_MASK_FUNCTION) &&
> -	    ct->function && (allocinfo_cmp_str(ct->function, filter->fields.function)))
> +	    ct->function && allocinfo_cmp_str(ct->function, filter->fields.function))
>   		return false;
>   
This should be fixed in the second patch; it's unrelated to current 
functionality.
>   	if ((filter->mask & ALLOCINFO_FILTER_MASK_FILENAME) &&
> -	    ct->filename && (allocinfo_cmp_str(ct->filename, filter->fields.filename)))
> +	    ct->filename && allocinfo_cmp_str(ct->filename, filter->fields.filename))
>   		return false;

Ditto


Thanks

Best Regards

Hao

>   	if ((filter->mask & ALLOCINFO_FILTER_MASK_LINENO) &&
>   	    ct->lineno != filter->fields.lineno)
>   		return false;
>   
> +	if (filter->mask & (ALLOCINFO_FILTER_MASK_MIN_SIZE | ALLOCINFO_FILTER_MASK_MAX_SIZE)) {
> +		if (!*fetched_counters) {
> +			*counters = allocinfo_prefetch_counters(ct);
> +			*fetched_counters = true;
> +		}
> +		if ((filter->mask & ALLOCINFO_FILTER_MASK_MIN_SIZE) &&
> +		    counters->bytes < filter->min_size)
> +			return false;
> +		if ((filter->mask & ALLOCINFO_FILTER_MASK_MAX_SIZE) &&
> +		    counters->bytes > filter->max_size)
> +			return false;
> +	}
> +
>   	return true;
>   }
>   
> @@ -274,6 +301,8 @@ static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg)
>   	struct codetag *ct;
>   	struct allocinfo_get_at params = {0};
>   	__u64 skip_count;
> +	struct alloc_tag_counters counters;
> +	bool fetched_counters;
>   
>   	if (copy_from_user(&params, arg, sizeof(params)))
>   		return -EFAULT;
> @@ -281,6 +310,11 @@ static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg)
>   	if (params.filter.mask & ~ALLOCINFO_FILTER_MASKS)
>   		return -EINVAL;
>   
> +	if ((params.filter.mask & ALLOCINFO_FILTER_MASK_MIN_SIZE) &&
> +	    (params.filter.mask & ALLOCINFO_FILTER_MASK_MAX_SIZE) &&
> +	    params.filter.min_size > params.filter.max_size)
> +		return -EINVAL;
> +
>   	priv = m->private;
>   
>   	mutex_lock(&priv->ioctl_lock);
> @@ -304,7 +338,8 @@ static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg)
>   	ct = codetag_next_ct(&priv->ioctl_iter);
>   
>   	while (ct) {
> -		if (matches_filter(ct, &priv->filter)) {
> +		fetched_counters = false;
> +		if (matches_filter(ct, &priv->filter, &counters, &fetched_counters)) {
>   			if (skip_count == 0)
>   				break;
>   			skip_count--;
> @@ -313,7 +348,7 @@ static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg)
>   	}
>   
>   	if (ct) {
> -		allocinfo_to_params(ct, &params.data);
> +		allocinfo_to_params(ct, &params.data, fetched_counters ? &counters : NULL);
>   		priv->positioned = true;
>   	}
>   
> @@ -339,6 +374,8 @@ static int allocinfo_ioctl_get_next(struct seq_file *m, void __user *arg)
>   	struct codetag *ct;
>   	struct allocinfo_tag_data params;
>   	int ret = 0;
> +	struct alloc_tag_counters counters;
> +	bool fetched_counters;
>   
>   	memset(&params, 0, sizeof(params));
>   	priv = m->private;
> @@ -352,10 +389,15 @@ static int allocinfo_ioctl_get_next(struct seq_file *m, void __user *arg)
>   	}
>   
>   	ct = codetag_next_ct(&priv->ioctl_iter);
> -	while (ct && !matches_filter(ct, &priv->filter))
> +	while (ct) {
> +		fetched_counters = false;
> +		if (matches_filter(ct, &priv->filter, &counters, &fetched_counters))
> +			break;
>   		ct = codetag_next_ct(&priv->ioctl_iter);
> +	}
> +
>   	if (ct)
> -		allocinfo_to_params(ct, &params);
> +		allocinfo_to_params(ct, &params, fetched_counters ? &counters : NULL);
>   
>   	if (!ct) {
>   		priv->positioned = false;

^ permalink raw reply

* Re: [PATCH v2 2/3] hwmon: pmbus: Add support for Silergy SQ24860
From: Guenter Roeck @ 2026-06-08  3:34 UTC (permalink / raw)
  To: Ziming Zhu
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jonathan Corbet,
	Shuah Khan, linux-hwmon, devicetree, linux-kernel, linux-doc,
	Ziming Zhu
In-Reply-To: <20260605063042.91776-3-zmzhu0630@163.com>

On Fri, Jun 05, 2026 at 02:30:41PM +0800, Ziming Zhu wrote:
> From: Ziming Zhu <ziming.zhu@silergycorp.com>
> 
> Add PMBus hwmon support for the Silergy SQ24860 eFuse.
> 
> The driver reports input voltage, output voltage, auxiliary voltage,
> input current, input power, and temperature. It also exposes peak,
> average, and minimum history attributes, sample count configuration,
> and maps the manufacturer-specific VIREF register to the generic input
> over-current fault limit attribute.
> 
> The IMON resistor value is read from the silergy,rimon-micro-ohms device
> property and used to configure the input current calibration gain.
> 
> Signed-off-by: Ziming Zhu <ziming.zhu@silergycorp.com>

checkpatch --strict says:

total: 0 errors, 3 warnings, 6 checks, 464 lines checked

The MAINTAINERS and the DT warning can be ignored, but I expect the rest
to be fixed.

> ---
>  drivers/hwmon/pmbus/Kconfig   |  19 ++
>  drivers/hwmon/pmbus/Makefile  |   1 +
>  drivers/hwmon/pmbus/sq24860.c | 432 ++++++++++++++++++++++++++++++++++
>  3 files changed, 452 insertions(+)
>  create mode 100644 drivers/hwmon/pmbus/sq24860.c
> 
> diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
> index 8f4bff375ecb..a905b5af137c 100644
> --- a/drivers/hwmon/pmbus/Kconfig
> +++ b/drivers/hwmon/pmbus/Kconfig
> @@ -612,6 +612,25 @@ config SENSORS_STEF48H28
>  	  This driver can also be built as a module. If so, the module will
>  	  be called stef48h28.
>  
> +config SENSORS_SQ24860
> +	tristate "Silergy SQ24860"
> +	help
> +	  If you say yes here you get hardware monitoring support for Silergy
> +	  SQ24860 eFuse.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called sq24860.
> +
> +config SENSORS_SQ24860_REGULATOR
> +	bool "Regulator support for SQ24860"
> +	depends on SENSORS_SQ24860 && REGULATOR
> +	default SENSORS_SQ24860
> +	help
> +	  If you say yes here you get regulator support for Silergy SQ24860.
> +	  The regulator is registered through the PMBus regulator framework and
> +	  can be used to control the output exposed by the device.
> +	  This option is only useful if regulator framework support is needed.
> +
>  config SENSORS_STPDDC60
>  	tristate "ST STPDDC60"
>  	help
> diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
> index 7129b62bc00f..86bc93c6c091 100644
> --- a/drivers/hwmon/pmbus/Makefile
> +++ b/drivers/hwmon/pmbus/Makefile
> @@ -60,6 +60,7 @@ obj-$(CONFIG_SENSORS_PM6764TR)	+= pm6764tr.o
>  obj-$(CONFIG_SENSORS_PXE1610)	+= pxe1610.o
>  obj-$(CONFIG_SENSORS_Q54SJ108A2)	+= q54sj108a2.o
>  obj-$(CONFIG_SENSORS_STEF48H28)	+= stef48h28.o
> +obj-$(CONFIG_SENSORS_SQ24860)	+= sq24860.o
>  obj-$(CONFIG_SENSORS_STPDDC60)	+= stpddc60.o
>  obj-$(CONFIG_SENSORS_TDA38640)	+= tda38640.o
>  obj-$(CONFIG_SENSORS_TPS25990)	+= tps25990.o
> diff --git a/drivers/hwmon/pmbus/sq24860.c b/drivers/hwmon/pmbus/sq24860.c
> new file mode 100644
> index 000000000000..43a2cb542169
> --- /dev/null
> +++ b/drivers/hwmon/pmbus/sq24860.c
> @@ -0,0 +1,432 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Copyright (c) 2024.
> +// Author: Ziming Zhu <ziming.zhu@silergycorp.com>

Please do not mix C++ and C comments. Yes, I understand that the first
line must be a C++ comment. The rest of the driver must use a consistent
comment style.

> +#include <linux/bitfield.h>
> +#include <linux/debugfs.h>

I do not see where this include file is used.

> +#include <linux/err.h>
> +#include <linux/hwmon-sysfs.h>

I do not see where this include file is used.

> +#include <linux/i2c.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +
> +#include "pmbus.h"
> +
> +#define SQ24860_IIN_CAL_GAIN		0x38
> +#define SQ24860_READ_VAUX		0xd0
> +#define SQ24860_READ_VIN_MIN		0xd1
> +#define SQ24860_READ_VIN_PEAK		0xd2
> +#define SQ24860_READ_IIN_PEAK		0xd4
> +#define SQ24860_READ_PIN_PEAK		0xd5
> +#define SQ24860_READ_TEMP_AVG		0xd6
> +#define SQ24860_READ_TEMP_PEAK		0xd7
> +#define SQ24860_READ_VOUT_MIN		0xda
> +#define SQ24860_READ_VIN_AVG		0xdc
> +#define SQ24860_READ_VOUT_AVG		0xdd
> +#define SQ24860_READ_IIN_AVG		0xde
> +#define SQ24860_READ_PIN_AVG		0xdf
> +#define SQ24860_VIREF			0xe0
> +#define SQ24860_PK_MIN_AVG		0xea
> +#define PK_MIN_AVG_RST_PEAK		BIT(7)
> +#define PK_MIN_AVG_RST_AVG		BIT(6)
> +#define PK_MIN_AVG_RST_MIN		BIT(5)
> +#define PK_MIN_AVG_AVG_CNT		GENMASK(2, 0)
> +#define SQ24860_MFR_WRITE_PROTECT	0xf8
> +#define SQ24860_UNLOCKED		BIT(7)
> +
> +#define SQ24860_8B_SHIFT		2
> +#define SQ24860_IIN_OCF_NUM		1000000
> +#define SQ24860_IIN_OCF_DIV		129278
> +#define SQ24860_IIN_OCF_OFF		165
> +
> +#define PK_MIN_AVG_RST_MASK		(PK_MIN_AVG_RST_PEAK | \
> +					 PK_MIN_AVG_RST_AVG  | \
> +					 PK_MIN_AVG_RST_MIN)
> +#define SQ24860_MAX_SAMPLES		BIT(FIELD_MAX(PK_MIN_AVG_AVG_CNT))
> +/*
> + * Arbitrary default Rimon value: 1.6kOhm
> + */
> +#define SQ24860_DEFAULT_RIMON		1600000000
> +#define SQ24860_DEFAULT_GIMON		18180
> +
> +#define SQ24860_VAUX_DIV		20
> +
> +static int sq24860_write_iin_cal_gain(struct i2c_client *client, u32 rimon,
> +					u32 gimon)
> +{
> +	u64 temp = (u64)6400 * 1000000000 * 1000;
> +	u64 denom;
> +	u64 word;
> +
> +	if (!rimon || !gimon)
> +		return -EINVAL;
> +
> +	denom = (u64)rimon * gimon;
> +	word = div_u64(temp, denom);
> +	if (word > U16_MAX)
> +		return -ERANGE;

This is not "Math result not representable". Return -EINVAL.

Also, please make sure to fix the problem reported by Sashiko, or explain
why it does not apply.

> +
> +	return i2c_smbus_write_word_data(client, SQ24860_IIN_CAL_GAIN,
> +						(u16)word);
> +}
> +
> +static int sq24860_mfr_write_protect_set(struct i2c_client *client,
> +					  u8 protect)
> +{
> +	u8 val;
> +
> +	switch (protect) {
> +	case 0:
> +		val = 0xa2;
> +		break;
> +	case PB_WP_ALL:
> +		val = 0x0;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return pmbus_write_byte_data(client, -1, SQ24860_MFR_WRITE_PROTECT,
> +				     val);
> +}
> +
> +static int sq24860_mfr_write_protect_get(struct i2c_client *client)
> +{
> +	int ret = pmbus_read_byte_data(client, -1, SQ24860_MFR_WRITE_PROTECT);
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	return (ret & SQ24860_UNLOCKED) ? 0 : PB_WP_ALL;
> +}
> +
> +static int sq24860_read_word_data(struct i2c_client *client,
> +				   int page, int phase, int reg)
> +{
> +	int ret;
> +
> +	switch (reg) {
> +	case PMBUS_VIRT_READ_VIN_MAX:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_VIN_PEAK);
> +		break;
> +
> +	case PMBUS_VIRT_READ_VIN_MIN:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_VIN_MIN);
> +		break;
> +
> +	case PMBUS_VIRT_READ_VIN_AVG:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_VIN_AVG);
> +		break;
> +
> +	case PMBUS_VIRT_READ_VOUT_MIN:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_VOUT_MIN);
> +		break;
> +
> +	case PMBUS_VIRT_READ_VOUT_AVG:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_VOUT_AVG);
> +		break;
> +
> +	case PMBUS_VIRT_READ_IIN_AVG:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_IIN_AVG);
> +		break;
> +
> +	case PMBUS_VIRT_READ_IIN_MAX:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_IIN_PEAK);
> +		break;
> +
> +	case PMBUS_VIRT_READ_TEMP_AVG:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_TEMP_AVG);
> +		break;
> +
> +	case PMBUS_VIRT_READ_TEMP_MAX:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_TEMP_PEAK);
> +		break;
> +
> +	case PMBUS_VIRT_READ_PIN_AVG:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_PIN_AVG);
> +		break;
> +
> +	case PMBUS_VIRT_READ_PIN_MAX:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_PIN_PEAK);
> +		break;
> +
> +	case PMBUS_VIRT_READ_VMON:
> +		ret = pmbus_read_word_data(client, page, phase,
> +					   SQ24860_READ_VAUX);
> +		if (ret < 0)
> +			break;
> +		ret = DIV_ROUND_CLOSEST(ret, SQ24860_VAUX_DIV);
> +		break;
> +
> +	case PMBUS_VIN_UV_WARN_LIMIT:
> +	case PMBUS_VIN_UV_FAULT_LIMIT:
> +	case PMBUS_VIN_OV_WARN_LIMIT:
> +	case PMBUS_VIN_OV_FAULT_LIMIT:
> +	case PMBUS_VOUT_UV_WARN_LIMIT:
> +	case PMBUS_IIN_OC_WARN_LIMIT:
> +	case PMBUS_OT_WARN_LIMIT:
> +	case PMBUS_OT_FAULT_LIMIT:
> +	case PMBUS_PIN_OP_WARN_LIMIT:
> +		/*
> +		 * These registers provide an 8 bits value instead of a
> +		 * 10bits one. Just shifting twice the register value is
> +		 * enough to make the sensor type conversion work, even
> +		 * if the datasheet provides different m, b and R for
> +		 * those.
> +		 */
> +		ret = pmbus_read_word_data(client, page, phase, reg);
> +		if (ret < 0)
> +			break;
> +		ret <<= SQ24860_8B_SHIFT;
> +		break;
> +
> +	case PMBUS_IIN_OC_FAULT_LIMIT:
> +		/*
> +		 * VIREF directly sets the over-current limit at which the eFuse
> +		 * will turn the FET off and trigger a fault. Expose it through
> +		 * this generic property instead of a manufacturer specific one.
> +		 */
> +		ret = pmbus_read_byte_data(client, page, SQ24860_VIREF);
> +		if (ret < 0)
> +			break;
> +		ret = DIV_ROUND_CLOSEST(ret * SQ24860_IIN_OCF_NUM,
> +					SQ24860_IIN_OCF_DIV);
> +		ret += SQ24860_IIN_OCF_OFF;
> +		break;
> +
> +	case PMBUS_VIRT_SAMPLES:
> +		ret = pmbus_read_byte_data(client, page, SQ24860_PK_MIN_AVG);
> +		if (ret < 0)
> +			break;
> +		ret = BIT(FIELD_GET(PK_MIN_AVG_AVG_CNT, ret));
> +		break;
> +
> +	case PMBUS_VIRT_RESET_TEMP_HISTORY:
> +	case PMBUS_VIRT_RESET_VIN_HISTORY:
> +	case PMBUS_VIRT_RESET_IIN_HISTORY:
> +	case PMBUS_VIRT_RESET_PIN_HISTORY:
> +	case PMBUS_VIRT_RESET_VOUT_HISTORY:
> +		ret = 0;
> +		break;
> +
> +	default:
> +		ret = -ENODATA;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static int sq24860_write_word_data(struct i2c_client *client,
> +				    int page, int reg, u16 value)
> +{
> +	int ret;
> +
> +	switch (reg) {
> +	case PMBUS_VIN_UV_WARN_LIMIT:
> +	case PMBUS_VIN_UV_FAULT_LIMIT:
> +	case PMBUS_VIN_OV_WARN_LIMIT:
> +	case PMBUS_VIN_OV_FAULT_LIMIT:
> +	case PMBUS_VOUT_UV_WARN_LIMIT:
> +	case PMBUS_IIN_OC_WARN_LIMIT:
> +	case PMBUS_OT_WARN_LIMIT:
> +	case PMBUS_OT_FAULT_LIMIT:
> +	case PMBUS_PIN_OP_WARN_LIMIT:
> +		value >>= SQ24860_8B_SHIFT;
> +		value = clamp_val(value, 0, 0xff);
> +		ret = pmbus_write_word_data(client, page, reg, value);
> +		break;
> +
> +	case PMBUS_IIN_OC_FAULT_LIMIT:
> +		value -= SQ24860_IIN_OCF_OFF;

What if value is < SQ24860_IIN_OCF_OFF ?

(also reported by Sashiko)

> +		value = DIV_ROUND_CLOSEST(((unsigned int)value) * SQ24860_IIN_OCF_DIV,
> +					  SQ24860_IIN_OCF_NUM);
> +		value = clamp_val(value, 0, 0x3f);
> +		ret = pmbus_write_byte_data(client, page, SQ24860_VIREF, value);
> +		break;
> +
> +	case PMBUS_VIRT_SAMPLES:
> +		value = clamp_val(value, 1, SQ24860_MAX_SAMPLES);
> +		value = ilog2(value);
> +		ret = pmbus_update_byte_data(client, page, SQ24860_PK_MIN_AVG,
> +					     PK_MIN_AVG_AVG_CNT,
> +					     FIELD_PREP(PK_MIN_AVG_AVG_CNT, value));
> +		break;
> +
> +	case PMBUS_VIRT_RESET_TEMP_HISTORY:
> +	case PMBUS_VIRT_RESET_VIN_HISTORY:
> +	case PMBUS_VIRT_RESET_IIN_HISTORY:
> +	case PMBUS_VIRT_RESET_PIN_HISTORY:
> +	case PMBUS_VIRT_RESET_VOUT_HISTORY:
> +		/*
> +		 * SQ24860 has history resets based on MIN/AVG/PEAK instead of per
> +		 * sensor type. Exposing this quirk in hwmon is not desirable so
> +		 * reset MIN, AVG and PEAK together. Even is there effectively only
> +		 * one reset, which resets everything, expose the 5 entries so
> +		 * userspace is not required map a sensor type to another to trigger
> +		 * a reset
> +		 */
> +		ret = pmbus_update_byte_data(client, 0, SQ24860_PK_MIN_AVG,
> +					     PK_MIN_AVG_RST_MASK,
> +					     PK_MIN_AVG_RST_MASK);
> +		break;
> +
> +	default:
> +		ret = -ENODATA;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static int sq24860_read_byte_data(struct i2c_client *client,
> +				   int page, int reg)
> +{
> +	int ret;
> +
> +	switch (reg) {
> +	case PMBUS_WRITE_PROTECT:
> +		ret = sq24860_mfr_write_protect_get(client);
> +		break;
> +
> +	default:
> +		ret = -ENODATA;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static int sq24860_write_byte_data(struct i2c_client *client,
> +				    int page, int reg, u8 byte)
> +{
> +	int ret;
> +
> +	switch (reg) {
> +	case PMBUS_WRITE_PROTECT:
> +		ret = sq24860_mfr_write_protect_set(client, byte);
> +		break;
> +
> +	default:
> +		ret = -ENODATA;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +#if IS_ENABLED(CONFIG_SENSORS_SQ24860_REGULATOR)
> +static const struct regulator_desc sq24860_reg_desc[] = {
> +	PMBUS_REGULATOR_ONE_NODE("vout"),
> +};
> +#endif
> +
> +static const struct pmbus_driver_info sq24860_base_info = {
> +	.pages = 1,
> +	.format[PSC_VOLTAGE_IN] = direct,
> +	.m[PSC_VOLTAGE_IN] = 64,
> +	.b[PSC_VOLTAGE_IN] = 0,
> +	.R[PSC_VOLTAGE_IN] = 0,
> +	.format[PSC_VOLTAGE_OUT] = direct,
> +	.m[PSC_VOLTAGE_OUT] = 64,
> +	.b[PSC_VOLTAGE_OUT] = 0,
> +	.R[PSC_VOLTAGE_OUT] = 0,
> +	.format[PSC_TEMPERATURE] = direct,
> +	.m[PSC_TEMPERATURE] = 1,
> +	.b[PSC_TEMPERATURE] = 0,
> +	.R[PSC_TEMPERATURE] = 0,
> +	/*
> +	* Current and power measurements depend on the calibration gain
> +	* programmed from the board-specific IMON resistor value.
> +	*/

Comment alignment is off (see checkpatch results).

> +	.format[PSC_CURRENT_IN] = direct,
> +	.m[PSC_CURRENT_IN] = 16,
> +	.b[PSC_CURRENT_IN] = 0,
> +	.R[PSC_CURRENT_IN] = 0,
> +	.format[PSC_POWER] = direct,
> +	.m[PSC_POWER] = 2,
> +	.b[PSC_POWER] = 0,
> +	.R[PSC_POWER] = 0,
> +	.func[0] = (PMBUS_HAVE_VIN |
> +		    PMBUS_HAVE_VOUT |
> +		    PMBUS_HAVE_VMON |
> +		    PMBUS_HAVE_IIN |
> +		    PMBUS_HAVE_PIN |
> +		    PMBUS_HAVE_TEMP |
> +		    PMBUS_HAVE_STATUS_VOUT |
> +		    PMBUS_HAVE_STATUS_IOUT |
> +		    PMBUS_HAVE_STATUS_INPUT |
> +		    PMBUS_HAVE_STATUS_TEMP |
> +		    PMBUS_HAVE_SAMPLES),

Unnecessary ( ).

> +	.read_word_data = sq24860_read_word_data,
> +	.write_word_data = sq24860_write_word_data,
> +	.read_byte_data = sq24860_read_byte_data,
> +	.write_byte_data = sq24860_write_byte_data,
> +
> +#if IS_ENABLED(CONFIG_SENSORS_SQ24860_REGULATOR)
> +	.reg_desc = sq24860_reg_desc,
> +	.num_regulators = ARRAY_SIZE(sq24860_reg_desc),
> +#endif
> +};
> +
> +static const struct i2c_device_id sq24860_i2c_id[] = {
> +	{ "sq24860" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(i2c, sq24860_i2c_id);
> +
> +static const struct of_device_id sq24860_of_match[] = {
> +	{ .compatible = "silergy,sq24860" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, sq24860_of_match);
> +
> +static int sq24860_probe(struct i2c_client *client)
> +{
> +	struct device *dev = &client->dev;
> +	struct pmbus_driver_info *info;
> +	u32 rimon = SQ24860_DEFAULT_RIMON;
> +	u32 gimon = SQ24860_DEFAULT_GIMON;

gimon is a constant. Why pass it as parameter to sq24860_write_iin_cal_gain(),
and why validate it there instead of just using a constant ?

> +	int ret;
> +
> +	ret = device_property_read_u32(dev, "silergy,rimon-micro-ohms", &rimon);
> +	if (ret < 0 && ret != -EINVAL)
> +		return dev_err_probe(dev, ret, "failed to get rimon\n");

I am a bit lost here. Why accept -EINVAL (invalid arguments) ?

> +
> +	ret = sq24860_write_iin_cal_gain(client, rimon, gimon);
> +	if (ret < 0)
> +		return dev_err_probe(&client->dev, ret,
> +					     "Failed to set gain\n");
> +	info = devm_kmemdup(dev, &sq24860_base_info, sizeof(*info), GFP_KERNEL);
> +	if (!info)
> +		return -ENOMEM;
> +
> +	return pmbus_do_probe(client, info);
> +}
> +
> +static struct i2c_driver sq24860_driver = {
> +	.driver = {
> +		.name = "sq24860",
> +		.of_match_table = sq24860_of_match,
> +	},
> +	.probe = sq24860_probe,
> +	.id_table = sq24860_i2c_id,
> +};
> +module_i2c_driver(sq24860_driver);
> +
> +MODULE_AUTHOR("Ziming Zhu <ziming.zhu@silergycorp.com>");
> +MODULE_DESCRIPTION("PMBUS driver for SQ24860 eFuse");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS("PMBUS");

^ permalink raw reply

* Re: [PATCH v4 2/2] hwmon: (pmbus/max20860a) Add driver for Analog Devices MAX20860A
From: Guenter Roeck @ 2026-06-08  3:09 UTC (permalink / raw)
  To: Pradhan, Sanman
  Cc: linux-hwmon@vger.kernel.org, robh@kernel.org, krzk+dt@kernel.org,
	conor+dt@kernel.org, corbet@lwn.net, skhan@linuxfoundation.org,
	devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, noname.nuno@gmail.com, Syed, Arif,
	Sanman Pradhan
In-Reply-To: <20260601184516.919488-3-sanman.pradhan@hpe.com>

On Mon, Jun 01, 2026 at 06:45:36PM +0000, Pradhan, Sanman wrote:
> From: Syed Arif <arif.syed@hpe.com>
> 
> Add a PMBus driver for the Analog Devices MAX20860A step-down DC-DC
> switching regulator. The MAX20860A provides monitoring of input/output
> voltage, output current, and temperature via the PMBus interface using
> linear data format. Optional regulator support is available via
> CONFIG_SENSORS_MAX20860A_REGULATOR.
> 
> Signed-off-by: Syed Arif <arif.syed@hpe.com>
> Signed-off-by: Sanman Pradhan <psanman@juniper.net>

Applied.

Thanks,
Guenter

^ permalink raw reply

* Re: [PATCH v4 1/2] dt-bindings: hwmon: pmbus: Add Analog Devices MAX20860A
From: Guenter Roeck @ 2026-06-08  3:08 UTC (permalink / raw)
  To: Pradhan, Sanman
  Cc: linux-hwmon@vger.kernel.org, robh@kernel.org, krzk+dt@kernel.org,
	conor+dt@kernel.org, corbet@lwn.net, skhan@linuxfoundation.org,
	devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, noname.nuno@gmail.com, Syed, Arif,
	Sanman Pradhan, Conor Dooley
In-Reply-To: <20260601184516.919488-2-sanman.pradhan@hpe.com>

On Mon, Jun 01, 2026 at 06:45:30PM +0000, Pradhan, Sanman wrote:
> From: Sanman Pradhan <psanman@juniper.net>
> 
> Add devicetree binding documentation for the Analog Devices MAX20860A
> step-down DC-DC switching regulator with PMBus interface.
> 
> Signed-off-by: Sanman Pradhan <psanman@juniper.net>
> Acked-by: Conor Dooley <conor.dooley@microchip.com>

Applied.

Thanks,
Guenter

^ permalink raw reply

* Re: [PATCH v6 03/11] x86/virt/tdx: Add tdx_alloc/free_control_page() helpers
From: Yan Zhao @ 2026-06-08  2:18 UTC (permalink / raw)
  To: Binbin Wu
  Cc: Rick Edgecombe, bp, dave.hansen, hpa, kas, kvm, linux-coco,
	linux-doc, linux-kernel, mingo, nik.borisov, pbonzini, seanjc,
	tglx, vannapurve, x86, chao.gao, kai.huang, Kirill A. Shutemov
In-Reply-To: <50566572-6379-4100-8845-404f695e59cd@linux.intel.com>

On Mon, Jun 08, 2026 at 10:11:58AM +0800, Binbin Wu wrote:
> > diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
> > index 82dc27aecf297..74e75db5728c7 100644
> > --- a/arch/x86/include/asm/tdx.h
> > +++ b/arch/x86/include/asm/tdx.h
> > @@ -37,6 +37,7 @@
> >  
> >  #include <uapi/asm/mce.h>
> >  #include <asm/tdx_global_metadata.h>
> > +#include <linux/mm.h>
> 
> I think the header is not needed here.
Right. This version does not invoke page_address() in tdx.h for
tdx_alloc_control_page() any more.

Also no need to include mm.h for tdx.c (which has invoked page_address() before
this patch), since tdx.c includes memblock.h which further includes mm.h.

^ permalink raw reply

* Re: [PATCH v3 2/6] alloc_tag: add ioctl filters to /proc/allocinfo
From: Hao Ge @ 2026-06-08  2:39 UTC (permalink / raw)
  To: Abhishek Bapat, Suren Baghdasaryan, Andrew Morton,
	Kent Overstreet
  Cc: Shuah Khan, Jonathan Corbet, linux-doc, linux-kernel, linux-mm,
	Sourav Panda
In-Reply-To: <6f3b4aa0aa294cd56a73854c631de3ab7c0c5e01.1780701922.git.abhishekbapat@google.com>

Hi Abhishek


Thanks for the new version.


On 2026/6/6 07:36, Abhishek Bapat wrote:
> Extend the capability of the IOCTL mechanism to filter allocations based
> on tag's module name, function name, file name and line number.
>
> Signed-off-by: Abhishek Bapat <abhishekbapat@google.com>


Acked-by: Hao Ge <hao.ge@linux.dev>


> ---
>   include/uapi/linux/alloc_tag.h | 26 ++++++++++++-
>   lib/alloc_tag.c                | 68 ++++++++++++++++++++++++++++++++--
>   2 files changed, 89 insertions(+), 5 deletions(-)
>
> diff --git a/include/uapi/linux/alloc_tag.h b/include/uapi/linux/alloc_tag.h
> index 901199bad514..cffb0c46e0b1 100644
> --- a/include/uapi/linux/alloc_tag.h
> +++ b/include/uapi/linux/alloc_tag.h
> @@ -34,8 +34,32 @@ struct allocinfo_tag_data {
>   	struct allocinfo_counter counter;
>   };
>   
> +enum {
> +	ALLOCINFO_FILTER_MODNAME,
> +	ALLOCINFO_FILTER_FUNCTION,
> +	ALLOCINFO_FILTER_FILENAME,
> +	ALLOCINFO_FILTER_LINENO,
> +	__ALLOCINFO_FILTER_LAST = ALLOCINFO_FILTER_LINENO
> +};
> +
> +#define ALLOCINFO_FILTER_MASK_MODNAME		(1 << ALLOCINFO_FILTER_MODNAME)
> +#define ALLOCINFO_FILTER_MASK_FUNCTION		(1 << ALLOCINFO_FILTER_FUNCTION)
> +#define ALLOCINFO_FILTER_MASK_FILENAME		(1 << ALLOCINFO_FILTER_FILENAME)
> +#define ALLOCINFO_FILTER_MASK_LINENO		(1 << ALLOCINFO_FILTER_LINENO)
> +
> +#define ALLOCINFO_FILTER_MASKS \
> +	((1 << (__ALLOCINFO_FILTER_LAST + 1)) - 1)
> +
> +struct allocinfo_filter {
> +	__u64 mask; /* bitmask of the filter fields used */
> +	struct allocinfo_tag fields;
> +};
> +
>   struct allocinfo_get_at {
> -	__u64 pos;	/* input */
> +	/* inputs */
> +	__u64 pos;
> +	struct allocinfo_filter filter;
> +	/* output */
>   	struct allocinfo_tag_data data;
>   };
>   
> diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c
> index a0577215eb3d..93bc976ac505 100644
> --- a/lib/alloc_tag.c
> +++ b/lib/alloc_tag.c
> @@ -49,6 +49,7 @@ struct allocinfo_private {
>   	struct codetag_iterator iter;
>   	struct codetag_iterator reported_iter;
>   	bool print_header;
> +	struct allocinfo_filter filter;
>   	/* ioctl uses a separate iterator not to interfere with reads */
>   	struct codetag_iterator ioctl_iter;
>   	bool positioned; /* seq_open_private() sets to 0 */
> @@ -184,6 +185,12 @@ static void allocinfo_copy_str(char *dest, const char *src)
>   	strscpy_pad(dest, allocinfo_str(src), ALLOCINFO_STR_SIZE);
>   }
>   
> +/* Compare two strings and only consider the trimmed suffix if s1 is too long */
> +static int allocinfo_cmp_str(const char *str, const char *template)
> +{
> +	return strncmp(allocinfo_str(str), template, ALLOCINFO_STR_SIZE);
> +}
> +
>   /*
>    * Populates the UAPI allocinfo_tag_data structure with active runtime
>    * profiling counters extracted from the given kernel codetag.
> @@ -223,6 +230,40 @@ static int allocinfo_ioctl_get_content_id(struct seq_file *m, void __user *arg)
>   	return 0;
>   }
>   
> +/*
> + * Verifies whether a given codetag satisfies the active filtering criteria by
> + * matching it's characteristics against the specified filter.


nit: s/it's/its/


> + */
> +static bool matches_filter(struct codetag *ct, struct allocinfo_filter *filter)
> +{
> +	if (!filter || !filter->mask)
> +		return true;
> +
> +	if (filter->mask & ALLOCINFO_FILTER_MASK_MODNAME) {
> +		/* user wants to filter by modname but ct->modname is NULL */
> +		if (!ct->modname) {
> +			/* validate if user was attempting to filter for built-in allocations */
> +			if (filter->fields.modname[0] != '\0')
> +				return false;
> +		} else if (allocinfo_cmp_str(ct->modname, filter->fields.modname))
> +			return false;
> +	}
> +
> +	if ((filter->mask & ALLOCINFO_FILTER_MASK_FUNCTION) &&
> +	    ct->function && (allocinfo_cmp_str(ct->function, filter->fields.function)))
> +		return false;
> +
> +	if ((filter->mask & ALLOCINFO_FILTER_MASK_FILENAME) &&
> +	    ct->filename && (allocinfo_cmp_str(ct->filename, filter->fields.filename)))
> +		return false;
> +
> +	if ((filter->mask & ALLOCINFO_FILTER_MASK_LINENO) &&
> +	    ct->lineno != filter->fields.lineno)
> +		return false;
> +
> +	return true;
> +}
> +
>   /*
>    * Seeks the ioctl iterator to the specified 0-indexed tag position, reads its
>    * profiling data and returns it to userspace.
> @@ -231,29 +272,46 @@ static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg)
>   {
>   	struct allocinfo_private *priv;
>   	struct codetag *ct;
> -	__u64 pos;
>   	struct allocinfo_get_at params = {0};
> +	__u64 skip_count;
>   
>   	if (copy_from_user(&params, arg, sizeof(params)))
>   		return -EFAULT;
>   
> +	if (params.filter.mask & ~ALLOCINFO_FILTER_MASKS)
> +		return -EINVAL;
> +
>   	priv = m->private;
> -	pos = params.pos;
>   
>   	mutex_lock(&priv->ioctl_lock);
>   	codetag_lock_module_list(alloc_tag_cttype);
>   
> -	if (pos >= codetag_get_count(alloc_tag_cttype)) {
> +	if (params.pos >= codetag_get_count(alloc_tag_cttype)) {
>   		codetag_unlock_module_list(alloc_tag_cttype);
>   		mutex_unlock(&priv->ioctl_lock);
>   		return -ENOENT;
>   	}
>   
> +	skip_count = params.pos;
> +
> +	if (params.filter.mask)
> +		priv->filter = params.filter;
> +	else
> +		priv->filter.mask = 0;
> +
>   	/* Find the codetag */
>   	priv->ioctl_iter = codetag_get_ct_iter(alloc_tag_cttype);
>   	ct = codetag_next_ct(&priv->ioctl_iter);
> -	while (ct && pos--)
> +
> +	while (ct) {
> +		if (matches_filter(ct, &priv->filter)) {
> +			if (skip_count == 0)
> +				break;
> +			skip_count--;
> +		}
>   		ct = codetag_next_ct(&priv->ioctl_iter);
> +	}
> +
>   	if (ct) {
>   		allocinfo_to_params(ct, &params.data);
>   		priv->positioned = true;
> @@ -294,6 +352,8 @@ static int allocinfo_ioctl_get_next(struct seq_file *m, void __user *arg)
>   	}
>   
>   	ct = codetag_next_ct(&priv->ioctl_iter);
> +	while (ct && !matches_filter(ct, &priv->filter))
> +		ct = codetag_next_ct(&priv->ioctl_iter);
>   	if (ct)
>   		allocinfo_to_params(ct, &params);
>   

^ permalink raw reply

* [PATCH v3 3/3] PM: dpm_watchdog: Add sysctl interface for DPM watchdog timeouts
From: Tzung-Bi Shih @ 2026-06-08  2:15 UTC (permalink / raw)
  To: Jonathan Corbet, Rafael J. Wysocki, Greg Kroah-Hartman,
	Danilo Krummrich
  Cc: Shuah Khan, Pavel Machek, Len Brown, tzungbi, linux-doc,
	linux-kernel, linux-pm, driver-core, tfiga, senozhatsky,
	Randy Dunlap
In-Reply-To: <20260608021526.1023248-1-tzungbi@kernel.org>

Introduce sysctl knobs to allow configuring DPM watchdog timeouts at
runtime.

Currently, these timeouts are fixed at compile time via
CONFIG_DPM_WATCHDOG_TIMEOUT and CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT.
This limits flexibility if the timeouts need to be adjusted for
different testing scenarios or hardware behaviors without rebuilding
the kernel.

Add the following sysctl files under /proc/sys/kernel/:
- dpm_watchdog_timeout_secs: The total timeout before panic. The
  maximum value is capped at CONFIG_DPM_WATCHDOG_TIMEOUT to prevent
  unreasonably large timeouts.
- dpm_watchdog_warning_timeout_secs: The warning timeout. The maximum
  value is capped at the current dpm_watchdog_timeout_secs.
Both sysctls have a minimum value of 1.

Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
---
v3:
- No changes.

v2: https://lore.kernel.org/all/20260604090756.2884671-4-tzungbi@kernel.org
- New to the series.

v1: Doesn't exist.

 drivers/base/power/main.c | 61 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 57 insertions(+), 4 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 7822c29b7c8d..c1a4b30fafb2 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -28,6 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
+#include <linux/sysctl.h>
 #include <linux/async.h>
 #include <linux/suspend.h>
 #include <trace/events/power.h>
@@ -539,6 +540,58 @@ static bool __read_mostly dpm_watchdog_enabled =
 module_param(dpm_watchdog_enabled, bool, 0644);
 MODULE_PARM_DESC(dpm_watchdog_enabled, "Enable DPM watchdog");
 
+static unsigned int __read_mostly dpm_watchdog_timeout = CONFIG_DPM_WATCHDOG_TIMEOUT;
+static unsigned int __read_mostly dpm_watchdog_warning_timeout =
+						CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT;
+static const unsigned int dpm_watchdog_timeout_max = CONFIG_DPM_WATCHDOG_TIMEOUT;
+
+static int proc_dodpm_watchdog_timeout_secs(const struct ctl_table *table,
+					    int write, void *buffer,
+					    size_t *lenp, loff_t *ppos)
+{
+	struct ctl_table ctl = *table;
+	unsigned int val = dpm_watchdog_timeout;
+	int ret;
+
+	ctl.data = &val;
+	ret = proc_douintvec_minmax(&ctl, write, buffer, lenp, ppos);
+	if (ret || !write)
+		return ret;
+
+	if (val < dpm_watchdog_warning_timeout)
+		dpm_watchdog_warning_timeout = val;
+	dpm_watchdog_timeout = val;
+
+	return 0;
+}
+
+static const struct ctl_table dpm_watchdog_sysctls[] = {
+	{
+		.procname	= "dpm_watchdog_timeout_secs",
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= proc_dodpm_watchdog_timeout_secs,
+		.extra1		= SYSCTL_ONE,
+		.extra2		= (void *)&dpm_watchdog_timeout_max,
+	},
+	{
+		.procname	= "dpm_watchdog_warning_timeout_secs",
+		.data		= &dpm_watchdog_warning_timeout,
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= proc_douintvec_minmax,
+		.extra1		= SYSCTL_ONE,
+		.extra2		= (void *)&dpm_watchdog_timeout,
+	},
+};
+
+static int __init dpm_watchdog_sysctl_init(void)
+{
+	register_sysctl_init("kernel", dpm_watchdog_sysctls);
+	return 0;
+}
+subsys_initcall(dpm_watchdog_sysctl_init);
+
 /**
  * dpm_watchdog_handler - Driver suspend / resume watchdog handler.
  * @t: The timer that PM watchdog depends on.
@@ -564,9 +617,9 @@ static void dpm_watchdog_handler(struct timer_list *t)
 			dev_driver_string(wd->dev), dev_name(wd->dev));
 	}
 
-	time_left = CONFIG_DPM_WATCHDOG_TIMEOUT - CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT;
+	time_left = dpm_watchdog_timeout - dpm_watchdog_warning_timeout;
 	dev_warn(wd->dev, "**** DPM device timeout after %u seconds; %u seconds until panic ****\n",
-		 CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT, time_left);
+		 dpm_watchdog_warning_timeout, time_left);
 	show_stack(wd->tsk, NULL, KERN_WARNING);
 
 	wd->fatal = true;
@@ -587,11 +640,11 @@ static void dpm_watchdog_set(struct dpm_watchdog *wd, struct device *dev)
 
 	wd->dev = dev;
 	wd->tsk = current;
-	wd->fatal = CONFIG_DPM_WATCHDOG_TIMEOUT == CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT;
+	wd->fatal = dpm_watchdog_timeout == dpm_watchdog_warning_timeout;
 
 	timer_setup_on_stack(timer, dpm_watchdog_handler, 0);
 	/* use same timeout value for both suspend and resume */
-	timer->expires = jiffies + HZ * CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT;
+	timer->expires = jiffies + HZ * dpm_watchdog_warning_timeout;
 	add_timer(timer);
 }
 
-- 
2.54.0.1099.g489fc7bff1-goog


^ permalink raw reply related

* [PATCH v3 2/3] PM: dpm_watchdog: Allow disabling DPM watchdog by default
From: Tzung-Bi Shih @ 2026-06-08  2:15 UTC (permalink / raw)
  To: Jonathan Corbet, Rafael J. Wysocki, Greg Kroah-Hartman,
	Danilo Krummrich
  Cc: Shuah Khan, Pavel Machek, Len Brown, tzungbi, linux-doc,
	linux-kernel, linux-pm, driver-core, tfiga, senozhatsky,
	Randy Dunlap
In-Reply-To: <20260608021526.1023248-1-tzungbi@kernel.org>

Introduce the CONFIG_DPM_WATCHDOG_DEFAULT_ENABLED Kconfig option to
allow the device suspend/resume watchdog (DPM watchdog) to be disabled
by default at compile time.

Additionally, introduce the "dpm_watchdog_enabled" module parameter to
allow the watchdog to be enabled or disabled at boot time (via
"power.dpm_watchdog_enabled") and at runtime (via sysfs).

This provides flexibility for systems that want the watchdog code
compiled in but inactive by default, allowing it to be enabled only when
needed.

Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
---
v3:
- Add "PM" tag (was missing).
- Update the format and specify dependencies in kernel-parameters.txt.
- Update the help message in Kconfig to reflect that dpm_watchdog_enabled
  can be set at runtime as well.

v2: https://lore.kernel.org/all/20260604090756.2884671-3-tzungbi@kernel.org
- Use module parameter and bool for dpm_watchdog_enabled.
- Use IS_ENABLED().

v1: https://lore.kernel.org/all/20260528103215.505795-1-tzungbi@kernel.org

 Documentation/admin-guide/kernel-parameters.txt |  8 ++++++++
 drivers/base/power/main.c                       | 11 +++++++++++
 kernel/power/Kconfig                            | 10 ++++++++++
 3 files changed, 29 insertions(+)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 00375193bd26..f2620764c28e 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -47,6 +47,7 @@
 	PCI	PCI bus support is enabled.
 	PCIE	PCI Express support is enabled.
 	PCMCIA	The PCMCIA subsystem is enabled.
+	PM	Power Management support is enabled.
 	PNP	Plug & Play support is enabled.
 	PPC	PowerPC architecture is enabled.
 	PPT	Parallel port support is enabled.
@@ -5399,6 +5400,13 @@ Kernel parameters
 			function to NULL. On Idle the CPU just reduces
 			execution priority.
 
+	power.dpm_watchdog_enabled=
+			[PM] Enable or disable the device suspend/resume
+			watchdog (DPM watchdog).  Requires CONFIG_PM_SLEEP and
+			CONFIG_DPM_WATCHDOG enabled.
+			Format: <bool>
+			Default value is set by CONFIG_DPM_WATCHDOG_DEFAULT_ENABLED.
+
 	ppc_strict_facility_enable
 			[PPC,ENABLE] This option catches any kernel floating point,
 			Altivec, VSX and SPE outside of regions specifically
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index cd864f3a2799..7822c29b7c8d 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -534,6 +534,11 @@ module_param(dpm_watchdog_all_cpu_backtrace, bool, 0644);
 MODULE_PARM_DESC(dpm_watchdog_all_cpu_backtrace,
 		 "Backtrace all CPUs on DPM watchdog timeout");
 
+static bool __read_mostly dpm_watchdog_enabled =
+				IS_ENABLED(CONFIG_DPM_WATCHDOG_DEFAULT_ENABLED);
+module_param(dpm_watchdog_enabled, bool, 0644);
+MODULE_PARM_DESC(dpm_watchdog_enabled, "Enable DPM watchdog");
+
 /**
  * dpm_watchdog_handler - Driver suspend / resume watchdog handler.
  * @t: The timer that PM watchdog depends on.
@@ -577,6 +582,9 @@ static void dpm_watchdog_set(struct dpm_watchdog *wd, struct device *dev)
 {
 	struct timer_list *timer = &wd->timer;
 
+	if (!dpm_watchdog_enabled)
+		return;
+
 	wd->dev = dev;
 	wd->tsk = current;
 	wd->fatal = CONFIG_DPM_WATCHDOG_TIMEOUT == CONFIG_DPM_WATCHDOG_WARNING_TIMEOUT;
@@ -595,6 +603,9 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd)
 {
 	struct timer_list *timer = &wd->timer;
 
+	if (!dpm_watchdog_enabled)
+		return;
+
 	timer_delete_sync(timer);
 	timer_destroy_on_stack(timer);
 }
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 530c897311d4..b16bd159074a 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -268,6 +268,16 @@ config DPM_WATCHDOG
 	  captured in pstore device for inspection in subsequent
 	  boot session.
 
+config DPM_WATCHDOG_DEFAULT_ENABLED
+	bool "Enable DPM watchdog by default"
+	depends on DPM_WATCHDOG
+	default y
+	help
+	  If you say Y here, the DPM watchdog will be enabled by default.
+	  If you say N, it will be compiled in but disabled.  It can be
+	  enabled at boot time via the "power.dpm_watchdog_enabled" kernel
+	  parameter or at runtime via sysfs.
+
 config DPM_WATCHDOG_TIMEOUT
 	int "Watchdog timeout to panic in seconds"
 	range 1 120
-- 
2.54.0.1099.g489fc7bff1-goog


^ permalink raw reply related

* [PATCH v3 1/3] PM: core: Rename module parameters prefix to "power"
From: Tzung-Bi Shih @ 2026-06-08  2:15 UTC (permalink / raw)
  To: Jonathan Corbet, Rafael J. Wysocki, Greg Kroah-Hartman,
	Danilo Krummrich
  Cc: Shuah Khan, Pavel Machek, Len Brown, tzungbi, linux-doc,
	linux-kernel, linux-pm, driver-core, tfiga, senozhatsky,
	Randy Dunlap
In-Reply-To: <20260608021526.1023248-1-tzungbi@kernel.org>

Currently, the module parameters defined in drivers/base/power/main.c
use the default prefix "main" (derived from the filename).  The prefix
"main" is too generic and non-descriptive for power management
parameters.

Redefine MODULE_PARAM_PREFIX to "power." at the beginning of the file
to group the module parameters under the "power" namespace instead.
This makes the parameters more descriptive.

Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
---
v3:
- No changes.

v2: https://lore.kernel.org/all/20260604090756.2884671-2-tzungbi@kernel.org
- New to the series.

v1: Doesn't exist.

 drivers/base/power/main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index ed48c292f575..cd864f3a2799 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -40,6 +40,9 @@
 #include "../base.h"
 #include "power.h"
 
+#undef MODULE_PARAM_PREFIX
+#define MODULE_PARAM_PREFIX "power."
+
 typedef int (*pm_callback_t)(struct device *);
 
 /*
-- 
2.54.0.1099.g489fc7bff1-goog


^ permalink raw reply related

* [PATCH v3 0/3] PM: dpm_watchdog: Improve DPM watchdog configurability
From: Tzung-Bi Shih @ 2026-06-08  2:15 UTC (permalink / raw)
  To: Jonathan Corbet, Rafael J. Wysocki, Greg Kroah-Hartman,
	Danilo Krummrich
  Cc: Shuah Khan, Pavel Machek, Len Brown, tzungbi, linux-doc,
	linux-kernel, linux-pm, driver-core, tfiga, senozhatsky,
	Randy Dunlap

This series improves the configurability of the DPM watchdog.

Currently, the DPM watchdog timeouts are fixed at compile time, and the
watchdog is always enabled if compiled in.  Also, the module parameters
defined in drivers/base/power/main.c use the generic and non-descriptive
"main" prefix.

This series addresses these limitations.

Patch 1 renames the module parameter prefix for drivers/base/power/main.c
from "main" to "power".

Patch 2 introduces the CONFIG_DPM_WATCHDOG_DEFAULT_ENABLED to allow the DPM
watchdog to be disabled by default at compile time.  It also exposes the
"power.dpm_watchdog_enabled" module parameter to allow enabling/disabling
the watchdog at boot time and runtime.

Patch 3 introduces sysctl knobs under /proc/sys/kernel/ to allow
configuring the DPM watchdog timeouts at runtime.

---
v3:
- Address review comments on patch 2.

v2: https://lore.kernel.org/all/20260604090756.2884671-1-tzungbi@kernel.org
- Form a new series.

v1: Doesn't exist.

Tzung-Bi Shih (3):
  PM: core: Rename module parameters prefix to "power"
  PM: dpm_watchdog: Allow disabling DPM watchdog by default
  PM: dpm_watchdog: Add sysctl interface for DPM watchdog timeouts

 .../admin-guide/kernel-parameters.txt         |  8 ++
 drivers/base/power/main.c                     | 75 ++++++++++++++++++-
 kernel/power/Kconfig                          | 10 +++
 3 files changed, 89 insertions(+), 4 deletions(-)

-- 
2.54.0.1099.g489fc7bff1-goog


^ permalink raw reply

* Re: [PATCH 0/2] docs/zh: update DAMON usage sysfs documentation
From: Dongliang Mu @ 2026-06-08  2:12 UTC (permalink / raw)
  To: Doehyun Baek, Alex Shi, Yanteng Si, Hu Haowen
  Cc: Jonathan Corbet, Shuah Khan, SeongJae Park, linux-doc,
	linux-kernel, damon
In-Reply-To: <20260523094420.741003-1-doehyunbaek@gmail.com>


On 5/23/26 5:44 PM, Doehyun Baek wrote:
> Hi,
>
> The Simplified and Traditional Chinese DAMON usage translations are
> missing selected updates that are already documented in the English file.
> As a result, parts of the translated sysfs hierarchy and descriptions are
> stale, and the translations also lack the newer introduction of DAMON's
> special-purpose modules.

Hi Doehyun,

Thanks for your patch. To track the translation status of the 
documentation in different locales, we define a uniform format in 
how-to.rst [1]. Please revise the commit message of two patches.

	docs/zh_CN: Add/Update self-protection index Chinese translation

	Translate .../security/self-protection.rst into Chinese.

	Update the translation through commit b080e52110ea
	("docs: update self-protection __ro_after_init status")
	# 请执行 git log --oneline <您翻译的英文文档路径>,并替换上述内容

	Signed-off-by: Yanteng Si <si.yanteng@linux.dev>
	# 如果您前面的步骤正确执行,该行会自动显示,否则请检查 gitconfig 文件

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/translations/zh_CN/how-to.rst#n252

>
> The gaps correspond to the following English documentation commits:
>
>    commit a7bb1e754559 ("Docs/admin-guide/mm/damon/usage: document 'nid' file")
>    commit e85e965bdbec ("Docs/admin-guide/mm/damon/usage: document refresh_ms file")
>    commit e0c725455fd5 ("Docs/admin-guide/mm/damon/usage: document addr_unit file")
>    commit e06469cdf1fd ("Docs/admin-guide/mm/damon/usage: document obsolete_target file")
>    commit 2584dd7496c5 ("Docs/admin-guide/mm/damon/usage: update for max_nr_snapshots")
>    commit 652fd06d20da ("Docs/admin-guide/mm/damon/usage: update stats update process for refresh_ms")
>    commit e7df7a0bfc90 ("Docs/admin-guide/mm/damon/usage: introduce DAMON modules at the beginning")
>    commit d9cfe515d36e ("Docs/admin-guide/mm/damon/usage: document goal_tuner sysfs file")
>

> Update both translations only for those stale DAMON usage entries,
> including refresh_ms, addr_unit, obsolete_target, goal_tuner, nid, and
> max_nr_snapshots.
>
> Doehyun Baek (2):
>    docs/zh_CN: update DAMON usage sysfs documentation
>    docs/zh_TW: update DAMON usage sysfs documentation
>
>   .../zh_CN/admin-guide/mm/damon/usage.rst      | 56 +++++++++++++------
>   .../zh_TW/admin-guide/mm/damon/usage.rst      | 56 +++++++++++++------
>   2 files changed, 80 insertions(+), 32 deletions(-)
>
>
> base-commit: 79bd2dded182b1d458b18e62684b7f82ffc682e5


^ permalink raw reply

* Re: [PATCH v6 03/11] x86/virt/tdx: Add tdx_alloc/free_control_page() helpers
From: Binbin Wu @ 2026-06-08  2:11 UTC (permalink / raw)
  To: Rick Edgecombe
  Cc: bp, dave.hansen, hpa, kas, kvm, linux-coco, linux-doc,
	linux-kernel, mingo, nik.borisov, pbonzini, seanjc, tglx,
	vannapurve, x86, chao.gao, yan.y.zhao, kai.huang,
	Kirill A. Shutemov
In-Reply-To: <20260526023515.288829-4-rick.p.edgecombe@intel.com>

On 5/26/2026 10:35 AM, Rick Edgecombe wrote:
> From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
> 
> Add helpers to use when allocating or preparing pages that are handed to
> the TDX-Module for use as control/S-EPT pages, and thus need Dynamic PAMT
> adjustments.
> 
> The TDX module tracks some state for each page of physical memory that it
> might use. It calls this state the PAMT. It includes separate state for
> each page size a physical page could be utilized at within the TDX module
> (1GB, 2MB, 4KB). In Dynamic PAMT, only the 4KB page size state is
> allocated dynamically. So for pages that TDX will use as 2MB physically
> contiguous pages, Dynamic PAMT backing is not needed.
> 
> KVM will need to hand pages to the TDX module that it will use at 4KB
> granularity. So these pages will need Dynamic PAMT backing added before
> they are used by the TDX module, and removed afterwards.
> 
> Add tdx_alloc_control_page() and tdx_free_control_page() to handle both
> page allocation and Dynamic PAMT installation. Make them behave like
> normal alloc/free functions where allocation can fail in the case of no
> memory, but free (with any necessary Dynamic PAMT release) always
> succeeds. Do this so they can support the existing TDX flows that require
> teardowns to succeed.
> 
> Also create tdx_pamt_get/put() to handle installing Dynamic PAMT 4KB
> backing for pages that are already allocated (such as KVM's use of S-EPT
> page tables or guest private memory). Have them take a pfn instead of a
> struct page, as future changes will want to use these helpers for guest
> pages which are tracked by PFN.
> 
> Don't CLFLUSH the Dynamic PAMT pages handed to the TDX module, as is done
> for some other SEAMCALLs, as the TDX docs specify that this is only
> needed on "TD private memory or TD control structure page".
> 
> Since these allocations will be easily user triggerable, account the
> memory.
> 
> Leave logic to handle concurrency issues for future changes.
> 
> Assisted-by: GitHub Copilot:claude-opus-4-6 Claude:claude-opus-4-7 Sashiko:claude-opus-4-6
> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Co-developed-by: Sean Christopherson <seanjc@google.com>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> Co-developed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
> Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>

Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>

One comment below.


> 
> diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h
> index 82dc27aecf297..74e75db5728c7 100644
> --- a/arch/x86/include/asm/tdx.h
> +++ b/arch/x86/include/asm/tdx.h
> @@ -37,6 +37,7 @@
>  
>  #include <uapi/asm/mce.h>
>  #include <asm/tdx_global_metadata.h>
> +#include <linux/mm.h>

I think the header is not needed here.

>  #include <linux/pgtable.h>
>  
>  /*
> @@ -160,6 +161,12 @@ void tdx_guest_keyid_free(unsigned int keyid);
>  
>  void tdx_quirk_reset_paddr(unsigned long base, unsigned long size);
>  
> +/* Number PAMT pages to be provided to TDX module per 2MB region of PA */
> +#define TDX_DPAMT_ENTRY_PAGE_CNT 2
> +
> +struct page *tdx_alloc_control_page(void);
> +void tdx_free_control_page(struct page *page);
> +
>  struct tdx_td {
>  	/* TD root structure: */
>  	struct page *tdr_page;
> diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
> index 9ebd192cb5c17..9e0812d87ab06 100644[...]

^ permalink raw reply

* Re: [PATCH v3 1/6] alloc_tag: add ioctl to /proc/allocinfo
From: Hao Ge @ 2026-06-08  1:52 UTC (permalink / raw)
  To: Abhishek Bapat, Suren Baghdasaryan, Andrew Morton,
	Kent Overstreet
  Cc: Shuah Khan, Jonathan Corbet, linux-doc, linux-kernel, linux-mm,
	Sourav Panda
In-Reply-To: <0e91fdd3a88dbe5220d15c4c8ff7b8f66e86af7c.1780701922.git.abhishekbapat@google.com>

Hi Suren and Abhishek


Thanks for the new version.


On 2026/6/6 07:36, Abhishek Bapat wrote:
> From: Suren Baghdasaryan <surenb@google.com>
>
> Add the following ioctl commands for /proc/allocinfo file:
>
> ALLOCINFO_IOC_CONTENT_ID - gets content identifier which can be used
> to check whether the file content has changed specifically due to module
> load/unload. Every time a module is loaded / unloaded, the returned
> value will be different. By comparing the identifier value at the
> beginning and at the end of the content retrieval operation, users can
> validate retrieved information for consistency.
>
> ALLOCINFO_IOC_GET_AT - gets the record at the specified position. This
> is the position of a record in /proc/allocinfo.
>
> ALLOCINFO_IOC_GET_NEXT - gets the record next to the last retrieved
> one. If no records were previously retrieved, returns the first
> record.
>
> Signed-off-by: Suren Baghdasaryan <surenb@google.com>
> Signed-off-by: Abhishek Bapat <abhishekbapat@google.com>
> ---
>   Documentation/mm/allocation-profiling.rst     |   5 +
>   .../userspace-api/ioctl/ioctl-number.rst      |   2 +
>   MAINTAINERS                                   |   1 +
>   include/linux/codetag.h                       |   2 +
>   include/uapi/linux/alloc_tag.h                |  54 ++++
>   lib/alloc_tag.c                               | 232 +++++++++++++++++-
>   lib/codetag.c                                 |  18 ++
>   7 files changed, 312 insertions(+), 2 deletions(-)
>   create mode 100644 include/uapi/linux/alloc_tag.h
>
> diff --git a/Documentation/mm/allocation-profiling.rst b/Documentation/mm/allocation-profiling.rst
> index 5389d241176a..c3a28467955f 100644
> --- a/Documentation/mm/allocation-profiling.rst
> +++ b/Documentation/mm/allocation-profiling.rst
> @@ -46,6 +46,11 @@ sysctl:
>   Runtime info:
>     /proc/allocinfo
>   
> +  Profiling data can be retrieved either by reading `/proc/allocinfo` directly as
> +  text or programmatically via `ioctl()` calls defined in `<uapi/linux/alloc_tag.h>`.
> +  The ioctl interface supports structured binary data extraction as well as filtering
> +  by module name, function, file, line number, accuracy, or allocation size limits.
> +
>   Example output::
>   
>     root@moria-kvm:~# sort -g /proc/allocinfo|tail|numfmt --to=iec
> diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
> index 331223761fff..84f6808a8578 100644
> --- a/Documentation/userspace-api/ioctl/ioctl-number.rst
> +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
> @@ -349,6 +349,8 @@ Code  Seq#    Include File                                             Comments
>                                                                          <mailto:luzmaximilian@gmail.com>
>   0xA5  20-2F  linux/surface_aggregator/dtx.h                            Microsoft Surface DTX driver
>                                                                          <mailto:luzmaximilian@gmail.com>
> +0xA6  00-0F  uapi/linux/alloc_tag.h                                    Memory allocation profiling
> +                                                                       <mailto:surenb@google.com>
>   0xAA  00-3F  linux/uapi/linux/userfaultfd.h
>   0xAB  00-1F  linux/nbd.h
>   0xAC  00-1F  linux/raw.h
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a31f6f207afd..77f3fc487691 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16711,6 +16711,7 @@ S:	Maintained
>   F:	Documentation/mm/allocation-profiling.rst
>   F:	include/linux/alloc_tag.h
>   F:	include/linux/pgalloc_tag.h
> +F:	include/uapi/linux/alloc_tag.h
>   F:	lib/alloc_tag.c
>   
>   MEMORY CONTROLLER DRIVERS
> diff --git a/include/linux/codetag.h b/include/linux/codetag.h
> index ddae7484ca45..a25a085c2df1 100644
> --- a/include/linux/codetag.h
> +++ b/include/linux/codetag.h
> @@ -77,6 +77,8 @@ struct codetag_iterator {
>   void codetag_lock_module_list(struct codetag_type *cttype);
>   bool codetag_trylock_module_list(struct codetag_type *cttype);
>   void codetag_unlock_module_list(struct codetag_type *cttype);
> +unsigned long codetag_get_content_id(struct codetag_type *cttype);
> +unsigned int codetag_get_count(struct codetag_type *cttype);
>   struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype);
>   struct codetag *codetag_next_ct(struct codetag_iterator *iter);
>   
> diff --git a/include/uapi/linux/alloc_tag.h b/include/uapi/linux/alloc_tag.h
> new file mode 100644
> index 000000000000..901199bad514
> --- /dev/null
> +++ b/include/uapi/linux/alloc_tag.h
> @@ -0,0 +1,54 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +/*
> + *  include/linux/alloc_tag.h

nit: it should be include/uapi/linux/alloc_tag.h

(I guess you may have missed the comment I brought up before. It is not 
a critical problem though.)

> + */
> +
> +#ifndef _UAPI_ALLOC_TAG_H
> +#define _UAPI_ALLOC_TAG_H
> +
> +#include <linux/types.h>
> +
> +#define ALLOCINFO_STR_SIZE	64
> +
> +struct allocinfo_content_id {
> +	__u64 id;
> +};
> +
> +struct allocinfo_tag {
> +	/* Longer names are trimmed */
> +	char modname[ALLOCINFO_STR_SIZE];
> +	char function[ALLOCINFO_STR_SIZE];
> +	char filename[ALLOCINFO_STR_SIZE];
> +	__u64 lineno;
> +};
> +
> +/* The alignment ensures 32-bit compatible interfaces are not broken */
> +struct allocinfo_counter {
> +	__u64 bytes;
> +	__u64 calls;
> +	__u8 accurate;
> +} __attribute__((aligned(8)));
> +
> +struct allocinfo_tag_data {
> +	struct allocinfo_tag tag;
> +	struct allocinfo_counter counter;
> +};
> +
> +struct allocinfo_get_at {
> +	__u64 pos;	/* input */
> +	struct allocinfo_tag_data data;
> +};
> +
> +#define _ALLOCINFO_IOC_CONTENT_ID	0
> +#define _ALLOCINFO_IOC_GET_AT		1
> +#define _ALLOCINFO_IOC_GET_NEXT		2
> +
> +#define ALLOCINFO_IOC_BASE		0xA6
> +#define ALLOCINFO_IOC_CONTENT_ID	_IOR(ALLOCINFO_IOC_BASE, _ALLOCINFO_IOC_CONTENT_ID,	\
> +					     struct allocinfo_content_id)
> +#define ALLOCINFO_IOC_GET_AT		_IOWR(ALLOCINFO_IOC_BASE, _ALLOCINFO_IOC_GET_AT,	\
> +					      struct allocinfo_get_at)
> +#define ALLOCINFO_IOC_GET_NEXT		_IOR(ALLOCINFO_IOC_BASE, _ALLOCINFO_IOC_GET_NEXT,	\
> +					     struct allocinfo_tag_data)
> +
> +#endif /* _UAPI_ALLOC_TAG_H */
> diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c
> index d9be1cf5187d..a0577215eb3d 100644
> --- a/lib/alloc_tag.c
> +++ b/lib/alloc_tag.c
> @@ -5,6 +5,7 @@
>   #include <linux/gfp.h>
>   #include <linux/kallsyms.h>
>   #include <linux/module.h>
> +#include <linux/mutex.h>
>   #include <linux/page_ext.h>
>   #include <linux/pgalloc_tag.h>
>   #include <linux/proc_fs.h>
> @@ -14,6 +15,7 @@
>   #include <linux/string_choices.h>
>   #include <linux/vmalloc.h>
>   #include <linux/kmemleak.h>
> +#include <uapi/linux/alloc_tag.h>
>   
>   #define ALLOCINFO_FILE_NAME		"allocinfo"
>   #define MODULE_ALLOC_TAG_VMAP_SIZE	(100000UL * sizeof(struct alloc_tag))
> @@ -47,6 +49,10 @@ struct allocinfo_private {
>   	struct codetag_iterator iter;
>   	struct codetag_iterator reported_iter;
>   	bool print_header;
> +	/* ioctl uses a separate iterator not to interfere with reads */
> +	struct codetag_iterator ioctl_iter;
> +	bool positioned; /* seq_open_private() sets to 0 */
> +	struct mutex ioctl_lock;
>   };
>   
>   static void *allocinfo_start(struct seq_file *m, loff_t *pos)
> @@ -130,6 +136,229 @@ static const struct seq_operations allocinfo_seq_op = {
>   	.show	= allocinfo_show,
>   };
>   
> +/*
> + * Initializes seq_file operations and allocates private state when opening
> + * the /proc/allocinfo procfs entry.
> + */
> +static int allocinfo_open(struct inode *inode, struct file *file)
> +{
> +	int ret;
> +
> +	ret = seq_open_private(file, &allocinfo_seq_op,
> +			       sizeof(struct allocinfo_private));
> +	if (!ret) {
> +		struct seq_file *m = file->private_data;
> +		struct allocinfo_private *priv = m->private;
> +
> +		mutex_init(&priv->ioctl_lock);
> +	}
> +	return ret;
> +}
> +
> +/*
> + * Cleans up the seq_file state and frees up the private state allocated in
> + * allocinfo_open() when closing the /proc/allocinfo file descriptor.
> + */
> +static int allocinfo_release(struct inode *inode, struct file *file)
> +{
> +	return seq_release_private(inode, file);
> +}
> +
> +/*
> + * Returns a pointer to the suffix of a string so that its length fits within
> + * ALLOCINFO_STR_SIZE, preserving the trailing characters.
> + */
> +static const char *allocinfo_str(const char *str)
> +{
> +	size_t len = strlen(str);
> +
> +	/* Keep an extra space for the trailing NULL. */
> +	if (len >= ALLOCINFO_STR_SIZE)
> +		str += (len - ALLOCINFO_STR_SIZE) + 1;
> +	return str;
> +}
> +
> +/* Copy a string and trim from the beginning if it's too long */
> +static void allocinfo_copy_str(char *dest, const char *src)
> +{
> +	strscpy_pad(dest, allocinfo_str(src), ALLOCINFO_STR_SIZE);
> +}
> +
> +/*
> + * Populates the UAPI allocinfo_tag_data structure with active runtime
> + * profiling counters extracted from the given kernel codetag.
> + */
> +static void allocinfo_to_params(struct codetag *ct,
> +				struct allocinfo_tag_data *data)
> +{
> +	struct alloc_tag *tag = ct_to_alloc_tag(ct);
> +	struct alloc_tag_counters counter = alloc_tag_read(tag);
> +
> +	if (ct->modname)
> +		allocinfo_copy_str(data->tag.modname, ct->modname);
> +	else
> +		data->tag.modname[0] = '\0';
> +	allocinfo_copy_str(data->tag.function, ct->function);
> +	allocinfo_copy_str(data->tag.filename, ct->filename);
> +	data->tag.lineno = ct->lineno;
> +	data->counter.bytes = counter.bytes;
> +	data->counter.calls = counter.calls;
> +	data->counter.accurate = !alloc_tag_is_inaccurate(tag);
> +}
> +
> +/*
> + * Retrieves the unique content ID representing the current allocation tag module
> + * layout, allowing userspace to detect if modules were loaded / unloaded.
> + */
> +static int allocinfo_ioctl_get_content_id(struct seq_file *m, void __user *arg)
> +{
> +	struct allocinfo_content_id params;
> +
> +	codetag_lock_module_list(alloc_tag_cttype);
> +	params.id = codetag_get_content_id(alloc_tag_cttype);
> +	codetag_unlock_module_list(alloc_tag_cttype);
> +	if (copy_to_user(arg, &params, sizeof(params)))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
> +/*
> + * Seeks the ioctl iterator to the specified 0-indexed tag position, reads its
> + * profiling data and returns it to userspace.
> + */
> +static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg)
> +{
> +	struct allocinfo_private *priv;
> +	struct codetag *ct;
> +	__u64 pos;
> +	struct allocinfo_get_at params = {0};
> +
> +	if (copy_from_user(&params, arg, sizeof(params)))
> +		return -EFAULT;
> +
> +	priv = m->private;
> +	pos = params.pos;
> +
> +	mutex_lock(&priv->ioctl_lock);
> +	codetag_lock_module_list(alloc_tag_cttype);
> +
> +	if (pos >= codetag_get_count(alloc_tag_cttype)) {
> +		codetag_unlock_module_list(alloc_tag_cttype);
> +		mutex_unlock(&priv->ioctl_lock);
> +		return -ENOENT;
> +	}
> +
> +	/* Find the codetag */
> +	priv->ioctl_iter = codetag_get_ct_iter(alloc_tag_cttype);
> +	ct = codetag_next_ct(&priv->ioctl_iter);
> +	while (ct && pos--)
> +		ct = codetag_next_ct(&priv->ioctl_iter);
> +	if (ct) {
> +		allocinfo_to_params(ct, &params.data);
> +		priv->positioned = true;
> +	}
> +
> +	codetag_unlock_module_list(alloc_tag_cttype);
> +	mutex_unlock(&priv->ioctl_lock);
> +
> +	if (!ct)
> +		return -ENOENT;
> +
> +	if (copy_to_user(arg, &params, sizeof(params)))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
> +/*
> + * Advances the ioctl iterator to the next allocation tag in the sequence and
> + * returns its profiling data to userspace.
> + */
> +static int allocinfo_ioctl_get_next(struct seq_file *m, void __user *arg)
> +{
> +	struct allocinfo_private *priv;
> +	struct codetag *ct;
> +	struct allocinfo_tag_data params;
> +	int ret = 0;
> +
> +	memset(&params, 0, sizeof(params));
> +	priv = m->private;
> +
> +	mutex_lock(&priv->ioctl_lock);
> +	codetag_lock_module_list(alloc_tag_cttype);
> +
> +	if (!priv->positioned) {
> +		priv->ioctl_iter = codetag_get_ct_iter(alloc_tag_cttype);
> +		priv->positioned = true;
> +	}
> +
> +	ct = codetag_next_ct(&priv->ioctl_iter);
> +	if (ct)
> +		allocinfo_to_params(ct, &params);
> +
> +	if (!ct) {
> +		priv->positioned = false;
> +		ret = -ENOENT;
> +	}
> +	codetag_unlock_module_list(alloc_tag_cttype);
> +	mutex_unlock(&priv->ioctl_lock);
> +
> +	if (ret == 0) {
> +		if (copy_to_user(arg, &params, sizeof(params)))
> +			return -EFAULT;
> +	}
> +	return ret;
> +}
> +
> +/*
> + * Entry point ioctl function for /proc/allocinfo routing requests to fetch the
> + * layout content ID, seek to a specific tag, or read sequential tags.
> + */
> +static long allocinfo_ioctl(struct file *file, unsigned int cmd,
> +			    unsigned long __arg)
> +{
> +	void __user *arg = (void __user *)__arg;
> +	int ret;
> +
> +	switch (cmd) {
> +	case ALLOCINFO_IOC_CONTENT_ID:
> +		ret = allocinfo_ioctl_get_content_id(file->private_data, arg);
> +		break;
> +	case ALLOCINFO_IOC_GET_AT:
> +		ret = allocinfo_ioctl_get_at(file->private_data, arg);
> +		break;
> +	case ALLOCINFO_IOC_GET_NEXT:
> +		ret = allocinfo_ioctl_get_next(file->private_data, arg);
> +		break;
> +	default:
> +		ret = -ENOIOCTLCMD;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +#ifdef CONFIG_COMPAT
> +static long allocinfo_compat_ioctl(struct file *file, unsigned int cmd,
> +				   unsigned long arg)
> +{
> +	return allocinfo_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
> +}
> +#endif
> +
> +static const struct proc_ops allocinfo_proc_ops = {
> +	.proc_open		= allocinfo_open,
> +	.proc_read_iter		= seq_read_iter,
> +	.proc_lseek		= seq_lseek,
> +	.proc_release		= allocinfo_release,
> +	.proc_ioctl		= allocinfo_ioctl,
> +#ifdef CONFIG_COMPAT
> +	.proc_compat_ioctl	= allocinfo_compat_ioctl,
> +#endif
> +
> +};
> +
>   size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep)
>   {
>   	struct codetag_iterator iter;
> @@ -993,8 +1222,7 @@ static int __init alloc_tag_init(void)
>   		return 0;
>   	}
>   
> -	if (!proc_create_seq_private(ALLOCINFO_FILE_NAME, 0400, NULL, &allocinfo_seq_op,
> -				     sizeof(struct allocinfo_private), NULL)) {
> +	if (!proc_create(ALLOCINFO_FILE_NAME, 0400, NULL, &allocinfo_proc_ops)) {
>   		pr_err("Failed to create %s file\n", ALLOCINFO_FILE_NAME);
>   		shutdown_mem_profiling(false);
>   		return -ENOMEM;
> diff --git a/lib/codetag.c b/lib/codetag.c
> index 4001a7ea6675..a9cda4c962a3 100644
> --- a/lib/codetag.c
> +++ b/lib/codetag.c
> @@ -19,6 +19,8 @@ struct codetag_type {
>   	struct codetag_type_desc desc;
>   	/* generates unique sequence number for module load */
>   	unsigned long next_mod_seq;
> +	/* bumped on every module load and unload */
> +	unsigned long content_id;
>   };
>   
>   struct codetag_range {
> @@ -50,6 +52,20 @@ void codetag_unlock_module_list(struct codetag_type *cttype)
>   	up_read(&cttype->mod_lock);
>   }
>   
> +unsigned long codetag_get_content_id(struct codetag_type *cttype)
> +{
> +	lockdep_assert_held(&cttype->mod_lock);
> +
> +	return cttype->content_id;
> +}
> +
> +unsigned int codetag_get_count(struct codetag_type *cttype)
> +{
> +	lockdep_assert_held(&cttype->mod_lock);
> +
> +	return cttype->count;
> +}
> +
>   struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype)
>   {
>   	struct codetag_iterator iter = {
> @@ -204,6 +220,7 @@ static int codetag_module_init(struct codetag_type *cttype, struct module *mod)
>   
>   	down_write(&cttype->mod_lock);
>   	cmod->mod_seq = ++cttype->next_mod_seq;
> +	++cttype->content_id;

I have a comment on the content_id bump placement.

++cttype->content_id is placed before idr_alloc and the module_load

callback. If idr_alloc fails or module_load returns an error

(While the chance of this occurring is very low.), the idr entry gets

rolled back but content_id has already been bumped. The actual

content didn't change in this case, so userspace would see a

different content_id and assume the data is inconsistent when it

isn't.


Thanks

Best Regards

Hao

>   	mod_id = idr_alloc(&cttype->mod_idr, cmod, 0, 0, GFP_KERNEL);
>   	if (mod_id >= 0) {
>   		if (cttype->desc.module_load) {
> @@ -368,6 +385,7 @@ void codetag_unload_module(struct module *mod)
>   			cttype->count -= range_size(cttype, &cmod->range);
>   			idr_remove(&cttype->mod_idr, mod_id);
>   			kfree(cmod);
> +			++cttype->content_id;
>   		}
>   		up_write(&cttype->mod_lock);
>   		if (found && cttype->desc.free_section_mem)

^ permalink raw reply

* Re: [PATCH v2] docs/zh_CN: update admin-guide/index.rst translation
From: Alex Shi @ 2026-06-08  1:40 UTC (permalink / raw)
  To: dzm91
  Cc: alexs, corbet, frederic, gpiccoli, jani.nikula, kees, linux-doc,
	linux-kernel, longman, mchehab+huawei, si.yanteng, skhan,
	tony.luck, zhuyan2015
In-Reply-To: <4534170c-700d-43b5-ad32-6b91455b3f14@hust.edu.cn>

Applied, Thanks!

^ permalink raw reply

* Re: [PATCH v2 1/6] alloc_tag: add ioctl to /proc/allocinfo
From: Hao Ge @ 2026-06-08  1:34 UTC (permalink / raw)
  To: Suren Baghdasaryan
  Cc: Abhishek Bapat, Andrew Morton, Kent Overstreet, Shuah Khan,
	Jonathan Corbet, linux-doc, linux-kernel, linux-mm, Sourav Panda
In-Reply-To: <CAJuCfpGUEUVprws-VQ0xWWeFSSMTeRv5MKtQ5BVH3HN9=mOcjg@mail.gmail.com>


On 2026/6/4 03:59, Suren Baghdasaryan wrote:
> On Sun, May 24, 2026 at 7:21 PM Hao Ge <hao.ge@linux.dev> wrote:
>> Hi Abhishek
>>
>>
>> Thanks for this patch. I had a few questions/comments after going
>>
>> through it.
>>
>>
>> On 2026/5/23 01:45, Abhishek Bapat wrote:
>>> From: Suren Baghdasaryan <surenb@google.com>
>>>
>>> Add the following ioctl commands for /proc/allocinfo file:
>>>
>>> ALLOCINFO_IOC_CONTENT_ID - gets content identifier which can be used
>>> to check whether the file content has changed specifically due to module
>>> load/unload. Every time a module is loaded / unloaded, the returned
>>> value will be different. By comparing the identifier value at the
>>> beginning and at the end of the content retrieval operation, users can
>>> validate retrieved information for consistency.
>> codetag_get_content_id() does not reflect module unload
>>
>> codetag_get_content_id() returns cttype->next_mod_seq:
>>
>> unsigned long codetag_get_content_id(struct codetag_type *cttype)
>>
>> {
>>
>>       return cttype->next_mod_seq;
>>
>> }
>>
>> However, next_mod_seq is only bumped in codetag_module_init(),
>>
>> i.e.the module load path:
>>
>> https://elixir.bootlin.com/linux/v7.1-rc4/source/lib/codetag.c#L204
>>
>> codetag_unload_module() does not increment next_mod_seq. This means
>>
>> that if only a module unload happens (without a subsequent load),
>>
>> content_id stays the same, so users comparing the id before and after
>>
>> won't detect that the content has changed. The commit message says
>>
>> "Every time a module is loaded / unloaded" -- I was wondering if this
>>
>> is intentional? If not, would it make sense to also bump next_mod_seq
>>
>> in the unload path?
> Good point. I overlooked that when I wrote the prototype for this patch.
> We should not bump next_mod_seq in the unload path but instead use a
> separate seq_count that gets bumped every time
> codetag_load_module/codetag_unload_module is called.

Make sense. I looked through the code with the question of why we should 
not bump next_mod_seq in the unload path.

I've now found the answer.

next_mod_seq is used as a sequence number allocator.

Every newly loaded module gets assigned ++cttype->next_mod_seq as its 
mod_seq.

The iterator then uses this mod_seq to detect module replacement at a 
given idr slot:

https://elixir.bootlin.com/linux/v7.1-rc6/source/lib/codetag.c#L102

Bumping it in the unload path would compromise the mod_seq uniqueness 
relied upon by the iterator.

Thanks for this.


Best Regards

Hao

>>
>>> ALLOCINFO_IOC_GET_AT - gets the record at the specified position. This
>>> is the position of a record in /proc/allocinfo.
>>>
>>> ALLOCINFO_IOC_GET_NEXT - gets the record next to the last retrieved
>>> one. If no records were previously retrieved, returns the first
>>> record.
>>>
>>> Signed-off-by: Suren Baghdasaryan <surenb@google.com>
>>> Signed-off-by: Abhishek Bapat <abhishekbapat@google.com>
>>> ---
>>>    .../userspace-api/ioctl/ioctl-number.rst      |   2 +
>>>    MAINTAINERS                                   |   1 +
>>>    include/linux/codetag.h                       |   1 +
>>>    include/uapi/linux/alloc_tag.h                |  54 +++++
>>>    lib/alloc_tag.c                               | 193 +++++++++++++++++-
>>>    lib/codetag.c                                 |  11 +
>>>    6 files changed, 260 insertions(+), 2 deletions(-)
>>>    create mode 100644 include/uapi/linux/alloc_tag.h
>>>
>>> diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
>>> index 331223761fff..84f6808a8578 100644
>>> --- a/Documentation/userspace-api/ioctl/ioctl-number.rst
>>> +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
>>> @@ -349,6 +349,8 @@ Code  Seq#    Include File                                             Comments
>>>                                                                           <mailto:luzmaximilian@gmail.com>
>>>    0xA5  20-2F  linux/surface_aggregator/dtx.h                            Microsoft Surface DTX driver
>>>                                                                           <mailto:luzmaximilian@gmail.com>
>>> +0xA6  00-0F  uapi/linux/alloc_tag.h                                    Memory allocation profiling
>>> +                                                                       <mailto:surenb@google.com>
>>>    0xAA  00-3F  linux/uapi/linux/userfaultfd.h
>>>    0xAB  00-1F  linux/nbd.h
>>>    0xAC  00-1F  linux/raw.h
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 46ed0f0e76d8..d176bde8fbfc 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -16709,6 +16709,7 @@ S:    Maintained
>>>    F:  Documentation/mm/allocation-profiling.rst
>>>    F:  include/linux/alloc_tag.h
>>>    F:  include/linux/pgalloc_tag.h
>>> +F:   include/uapi/linux/alloc_tag.h
>>>    F:  lib/alloc_tag.c
>>>
>>>    MEMORY CONTROLLER DRIVERS
>>> diff --git a/include/linux/codetag.h b/include/linux/codetag.h
>>> index 8ea2a5f7c98a..2bcd4e7c809e 100644
>>> --- a/include/linux/codetag.h
>>> +++ b/include/linux/codetag.h
>>> @@ -76,6 +76,7 @@ struct codetag_iterator {
>>>
>>>    void codetag_lock_module_list(struct codetag_type *cttype, bool lock);
>>>    bool codetag_trylock_module_list(struct codetag_type *cttype);
>>> +unsigned long codetag_get_content_id(struct codetag_type *cttype);
>>>    struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype);
>>>    struct codetag *codetag_next_ct(struct codetag_iterator *iter);
>>>
>>> diff --git a/include/uapi/linux/alloc_tag.h b/include/uapi/linux/alloc_tag.h
>>> new file mode 100644
>>> index 000000000000..e9a5b55fcc7a
>>> --- /dev/null
>>> +++ b/include/uapi/linux/alloc_tag.h
>>> @@ -0,0 +1,54 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
>>> +/*
>>> + *  include/linux/alloc_tag.h
>> nit: it should be include/uapi/linux/alloc_tag.h
>>> + */
>>> +
>>> +#ifndef _UAPI_ALLOC_TAG_H
>>> +#define _UAPI_ALLOC_TAG_H
>>> +
>>> +#include <linux/types.h>
>>> +
>>> +#define ALLOCINFO_STR_SIZE   64
>>> +
>>> +struct allocinfo_content_id {
>>> +     __u64 id;
>>> +};
>>> +
>>> +struct allocinfo_tag {
>>> +     /* Longer names are trimmed */
>>> +     char modname[ALLOCINFO_STR_SIZE];
>>> +     char function[ALLOCINFO_STR_SIZE];
>>> +     char filename[ALLOCINFO_STR_SIZE];
>>> +     __u64 lineno;
>>> +};
>>> +
>>> +struct allocinfo_counter {
>>> +     __u64 bytes;
>>> +     __u64 calls;
>>> +     __u8 accurate;
>>> +     __u8 pad[7]; /* Add alignment to not break the 32-bit compatible interface */
>>> +};
>>> +
>>> +struct allocinfo_tag_data {
>>> +     struct allocinfo_tag tag;
>>> +     struct allocinfo_counter counter;
>>> +};
>>> +
>>> +struct allocinfo_get_at {
>>> +     __u64 pos;      /* input */
>>> +     struct allocinfo_tag_data data;
>>> +};
>>> +
>>> +#define _ALLOCINFO_IOC_CONTENT_ID    0
>>> +#define _ALLOCINFO_IOC_GET_AT                1
>>> +#define _ALLOCINFO_IOC_GET_NEXT              2
>>> +
>>> +#define ALLOCINFO_IOC_BASE           0xA6
>>> +#define ALLOCINFO_IOC_CONTENT_ID     _IOR(ALLOCINFO_IOC_BASE, _ALLOCINFO_IOC_CONTENT_ID,     \
>>> +                                          struct allocinfo_content_id)
>>> +#define ALLOCINFO_IOC_GET_AT         _IOWR(ALLOCINFO_IOC_BASE, _ALLOCINFO_IOC_GET_AT,        \
>>> +                                           struct allocinfo_get_at)
>>> +#define ALLOCINFO_IOC_GET_NEXT               _IOR(ALLOCINFO_IOC_BASE, _ALLOCINFO_IOC_GET_NEXT,       \
>>> +                                          struct allocinfo_tag_data)
>>> +
>>> +#endif /* _UAPI_ALLOC_TAG_H */
>>> diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c
>>> index b9ca95d1f506..3598735b6c93 100644
>>> --- a/lib/alloc_tag.c
>>> +++ b/lib/alloc_tag.c
>>> @@ -5,6 +5,7 @@
>>>    #include <linux/gfp.h>
>>>    #include <linux/kallsyms.h>
>>>    #include <linux/module.h>
>>> +#include <linux/mutex.h>
>>>    #include <linux/page_ext.h>
>>>    #include <linux/pgalloc_tag.h>
>>>    #include <linux/proc_fs.h>
>>> @@ -14,6 +15,7 @@
>>>    #include <linux/string_choices.h>
>>>    #include <linux/vmalloc.h>
>>>    #include <linux/kmemleak.h>
>>> +#include <uapi/linux/alloc_tag.h>
>>>
>>>    #define ALLOCINFO_FILE_NAME         "allocinfo"
>>>    #define MODULE_ALLOC_TAG_VMAP_SIZE  (100000UL * sizeof(struct alloc_tag))
>>> @@ -46,6 +48,10 @@ int alloc_tag_ref_offs;
>>>    struct allocinfo_private {
>>>        struct codetag_iterator iter;
>>>        bool print_header;
>>> +     /* ioctl uses a separate iterator not to interfere with reads */
>>> +     struct codetag_iterator ioctl_iter;
>>> +     bool positioned; /* seq_open_private() sets to 0 */
>>> +     struct mutex ioctl_lock;
>>>    };
>>>
>>>    static void *allocinfo_start(struct seq_file *m, loff_t *pos)
>>> @@ -125,6 +131,190 @@ static const struct seq_operations allocinfo_seq_op = {
>>>        .show   = allocinfo_show,
>>>    };
>>>
>>> +static int allocinfo_open(struct inode *inode, struct file *file)
>>> +{
>>> +     int ret;
>>> +
>>> +     ret = seq_open_private(file, &allocinfo_seq_op,
>>> +                            sizeof(struct allocinfo_private));
>>> +     if (!ret) {
>>> +             struct seq_file *m = file->private_data;
>>> +             struct allocinfo_private *priv = m->private;
>>> +
>>> +             mutex_init(&priv->ioctl_lock);
>>> +     }
>>> +     return ret;
>>> +}
>>> +
>>> +static int allocinfo_release(struct inode *inode, struct file *file)
>>> +{
>>> +     return seq_release_private(inode, file);
>>> +}
>>> +
>>> +static const char *allocinfo_str(const char *str)
>>> +{
>>> +     size_t len = strlen(str);
>>> +
>>> +     /* Keep an extra space for the trailing NULL. */
>>> +     if (len >= ALLOCINFO_STR_SIZE)
>>> +             str += (len - ALLOCINFO_STR_SIZE) + 1;
>>> +     return str;
>>> +}
>>> +
>>> +/* Copy a string and trim from the beginning if it's too long */
>>> +static void allocinfo_copy_str(char *dest, const char *src)
>>> +{
>>> +     strscpy(dest, allocinfo_str(src), ALLOCINFO_STR_SIZE);
>>> +}
>>> +
>>> +static void allocinfo_to_params(struct codetag *ct,
>>> +                             struct allocinfo_tag_data *data)
>>> +{
>>> +     struct alloc_tag *tag = ct_to_alloc_tag(ct);
>>> +     struct alloc_tag_counters counter = alloc_tag_read(tag);
>>> +
>>> +     if (ct->modname)
>>> +             allocinfo_copy_str(data->tag.modname, ct->modname);
>>> +     else
>>> +             data->tag.modname[0] = '\0';
>>> +     allocinfo_copy_str(data->tag.function, ct->function);
>>> +     allocinfo_copy_str(data->tag.filename, ct->filename);
>>> +     data->tag.lineno = ct->lineno;
>>> +     data->counter.bytes = counter.bytes;
>>> +     data->counter.calls = counter.calls;
>>> +     data->counter.accurate = !alloc_tag_is_inaccurate(tag);
>>> +}
>>> +
>>> +static int allocinfo_ioctl_get_content_id(struct seq_file *m, void __user *arg)
>>> +{
>>> +     struct allocinfo_content_id params;
>>> +
>>> +     codetag_lock_module_list(alloc_tag_cttype, true);
>>> +     params.id = codetag_get_content_id(alloc_tag_cttype);
>>> +     codetag_lock_module_list(alloc_tag_cttype, false);
>>> +     if (copy_to_user(arg, &params, sizeof(params)))
>>> +             return -EFAULT;
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg)
>>> +{
>>> +     struct allocinfo_private *priv;
>>> +     struct codetag *ct;
>>> +     __u64 pos;
>>> +     struct allocinfo_get_at params = {0};
>>> +
>>> +     if (copy_from_user(&params, arg, sizeof(params)))
>>> +             return -EFAULT;
>>> +
>>> +     priv = (struct allocinfo_private *)m->private;
>>> +     pos = params.pos;
>>> +
>>> +     mutex_lock(&priv->ioctl_lock);
>>> +     codetag_lock_module_list(alloc_tag_cttype, true);
>>> +
>>> +     /* Find the codetag */
>>> +     priv->ioctl_iter = codetag_get_ct_iter(alloc_tag_cttype);
>>> +     ct = codetag_next_ct(&priv->ioctl_iter);
>>> +     while (ct && pos--)
>>> +             ct = codetag_next_ct(&priv->ioctl_iter);
>> No upper bound check on pos in ALLOCINFO_IOC_GET_AT:
>>
>> pos comes straight from userspace (__u64) with no validation.
>>
>> If the system has 10000 tags and someone passes pos=10001,
>>
>> the loop will still walk all 10000 tags just to return ENOENT
>>
>> -- all while holding ioctl_lock and mod_lock. It might be worth
>>
>> checking pos against the total tag count early. struct codetag_type
>>
>> is not exposed outside codetag.c though, so this would need a small helper.
> Ack.
>
>>
>> Thanks
>>
>> Best Regards
>>
>> Hao
>>
>>> +     if (ct) {
>>> +             allocinfo_to_params(ct, &params.data);
>>> +             priv->positioned = true;
>>> +     }
>>> +
>>> +     codetag_lock_module_list(alloc_tag_cttype, false);
>>> +     mutex_unlock(&priv->ioctl_lock);
>>> +
>>> +     if (!ct)
>>> +             return -ENOENT;
>>> +
>>> +     if (copy_to_user(arg, &params, sizeof(params)))
>>> +             return -EFAULT;
>>> +
>>> +     return 0;
>>> +}
>>> +
>>> +static int allocinfo_ioctl_get_next(struct seq_file *m, void __user *arg)
>>> +{
>>> +     struct allocinfo_private *priv;
>>> +     struct codetag *ct;
>>> +     struct allocinfo_tag_data params = {0};
>>> +     int ret = 0;
>>> +
>>> +     priv = (struct allocinfo_private *)m->private;
>>> +
>>> +     mutex_lock(&priv->ioctl_lock);
>>> +     codetag_lock_module_list(alloc_tag_cttype, true);
>>> +
>>> +     if (!priv->positioned) {
>>> +             priv->ioctl_iter = codetag_get_ct_iter(alloc_tag_cttype);
>>> +             priv->positioned = true;
>>> +     }
>>> +
>>> +     ct = codetag_next_ct(&priv->ioctl_iter);
>>> +     if (ct)
>>> +             allocinfo_to_params(ct, &params);
>>> +
>>> +     if (!ct) {
>>> +             priv->positioned = false;
>>> +             ret = -ENOENT;
>>> +     }
>>> +     codetag_lock_module_list(alloc_tag_cttype, false);
>>> +     mutex_unlock(&priv->ioctl_lock);
>>> +
>>> +     if (ret == 0) {
>>> +             if (copy_to_user(arg, &params, sizeof(params)))
>>> +                     return -EFAULT;
>>> +     }
>>> +     return ret;
>>> +}
>>> +
>>> +static long allocinfo_ioctl(struct file *file, unsigned int cmd,
>>> +                         unsigned long __arg)
>>> +{
>>> +     void __user *arg = (void __user *)__arg;
>>> +     int ret;
>>> +
>>> +     switch (cmd) {
>>> +     case ALLOCINFO_IOC_CONTENT_ID:
>>> +             ret = allocinfo_ioctl_get_content_id(file->private_data, arg);
>>> +             break;
>>> +     case ALLOCINFO_IOC_GET_AT:
>>> +             ret = allocinfo_ioctl_get_at(file->private_data, arg);
>>> +             break;
>>> +     case ALLOCINFO_IOC_GET_NEXT:
>>> +             ret = allocinfo_ioctl_get_next(file->private_data, arg);
>>> +             break;
>>> +     default:
>>> +             ret = -ENOIOCTLCMD;
>>> +             break;
>>> +     }
>>> +
>>> +     return ret;
>>> +}
>>> +
>>> +#ifdef CONFIG_COMPAT
>>> +static long allocinfo_compat_ioctl(struct file *file, unsigned int cmd,
>>> +                                unsigned long arg)
>>> +{
>>> +     return allocinfo_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
>>> +}
>>> +#endif
>>> +
>>> +static const struct proc_ops allocinfo_proc_ops = {
>>> +     .proc_open              = allocinfo_open,
>>> +     .proc_read_iter         = seq_read_iter,
>>> +     .proc_lseek             = seq_lseek,
>>> +     .proc_release           = allocinfo_release,
>>> +     .proc_ioctl             = allocinfo_ioctl,
>>> +#ifdef CONFIG_COMPAT
>>> +     .proc_compat_ioctl      = allocinfo_compat_ioctl,
>>> +#endif
>>> +
>>> +};
>>> +
>>>    size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep)
>>>    {
>>>        struct codetag_iterator iter;
>>> @@ -989,8 +1179,7 @@ static int __init alloc_tag_init(void)
>>>                return 0;
>>>        }
>>>
>>> -     if (!proc_create_seq_private(ALLOCINFO_FILE_NAME, 0400, NULL, &allocinfo_seq_op,
>>> -                                  sizeof(struct allocinfo_private), NULL)) {
>>> +     if (!proc_create(ALLOCINFO_FILE_NAME, 0400, NULL, &allocinfo_proc_ops)) {
>>>                pr_err("Failed to create %s file\n", ALLOCINFO_FILE_NAME);
>>>                shutdown_mem_profiling(false);
>>>                return -ENOMEM;
>>> diff --git a/lib/codetag.c b/lib/codetag.c
>>> index 304667897ad4..93aa30991563 100644
>>> --- a/lib/codetag.c
>>> +++ b/lib/codetag.c
>>> @@ -48,6 +48,17 @@ bool codetag_trylock_module_list(struct codetag_type *cttype)
>>>        return down_read_trylock(&cttype->mod_lock) != 0;
>>>    }
>>>
>>> +unsigned long codetag_get_content_id(struct codetag_type *cttype)
>>> +{
>>> +     lockdep_assert_held(&cttype->mod_lock);
>>> +
>>> +     /*
>>> +      * next_mod_seq is updated on every load, so can be used to identify
>>> +      * content changes.
>>> +      */
>>> +     return cttype->next_mod_seq;
>>> +}
>>> +
>>>    struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype)
>>>    {
>>>        struct codetag_iterator iter = {

^ permalink raw reply

* Re: [PATCH] docs/zh_TW: replace 接口 with 介面 in stable-api-nonsense.rst
From: Alex Shi @ 2026-06-08  1:34 UTC (permalink / raw)
  To: Dongliang Mu, panzhipop, Hu Haowen
  Cc: Jonathan Corbet, Shuah Khan, linux-doc, linux-kernel, Alex Shi,
	Yanteng Si
In-Reply-To: <7b6913d0-921f-4f46-8d97-adf18eddb5d1@hust.edu.cn>



On 2026/6/5 21:02, Dongliang Mu wrote:
> 
> On 6/4/26 3:34 AM, panzhipop wrote:
>> In Taiwan's standard terminology, as defined by the National Academy
>> for Educational Research (NAER) term bank (https://terms.naer.edu.tw/),
>> the correct Traditional Chinese translation for "interface" is "介面",
>> not "接口" (which is used in Simplified Chinese/Mainland China).
>>
>> Update the zh_TW translation of stable-api-nonsense.rst to use
>> the proper Taiwanese terminology.
> Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
>>
>> Signed-off-by: panzhipop <kipp455187@gmail.com>
>> --- 

Applied to git remote set-url linuxdoc 
git@gitolite.kernel.org:pub/scm/linux/kernel/git/alexs/linux.git.

Thanks!

^ permalink raw reply

* Re: [PATCH] Documentation: ABI: sysfs-class-reboot-mode-reboot_modes: fix doc warnings
From: Randy Dunlap @ 2026-06-08  1:04 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: linux-pm, linux-arm-kernel, Sebastian Reichel, Shivendra Pratap,
	linux-doc, linux-kernel
In-Reply-To: <d7cd7bb3-520f-4e80-8242-583f689f60db@infradead.org>



On 5/24/26 3:48 PM, Randy Dunlap wrote:
> Sebastian,
> 
> On 4/27/26 2:11 AM, Bartosz Golaszewski wrote:
>> On Mon, 27 Apr 2026 01:27:05 +0200, Randy Dunlap <rdunlap@infradead.org> said:
>>> Repair the docs build warnings in this file by unindenting the description,
>>> adding blank lines, and using `` to quote *arg.
>>>
>>> WARNING: Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes:36: abi_sys_class_reboot_mode_driver_reboot_modes doesn't have a description
>>> Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes:1: ERROR: Unexpected indentation. [docutils]
>>> Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes:1: ERROR: Unexpected indentation. [docutils]
>>> Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes:1: WARNING: Inline emphasis start-string without end-string. [docutils]
>>> Documentation/ABI/testing/sysfs-class-reboot-mode-reboot_modes:1: ERROR: Unexpected indentation. [docutils]
>>>
>>> Fixes: d3da03025e6d ("Documentation: ABI: Add sysfs-class-reboot-mode-reboot_modes")
>>> Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
>>> ---
>>
>> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> 
> This build warning is now in mainline.
> Will you be merging this patch soon?

ping.

> thanks.

-- 
~Randy


^ permalink raw reply

* Re: [PATCH 3/3] Documentation/arch/x86: remove obsolete vdso32=2 compatibility note
From: Randy Dunlap @ 2026-06-08  0:54 UTC (permalink / raw)
  To: Thorsten Blum, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, H. Peter Anvin, Andrew Morton,
	Jonathan Corbet, Shuah Khan
  Cc: x86, linux-doc, linux-kernel
In-Reply-To: <20260607151614.79567-8-thorsten.blum@linux.dev>



On 6/7/26 8:16 AM, Thorsten Blum wrote:
> Commit b0b49f2673f0 ("x86, vdso: Remove compat vdso support") removed
> compat vDSO support and documented vdso32=2 as an alias for vdso32=0.
> 
> However, since commit c06989da39cd ("x86/vdso: Ensure vdso32_enabled
> gets set to valid values only"), vdso32_setup() accepts only 0 and 1.
> 
> Remove the obsolete vdso32=2 compatibility note and document only the
> supported values.
> 
> Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>

Reviewed-by: Randy Dunlap <rdunlap@infradead.org>

Great to see that we are keeping the docs up-to-date.
Thanks.

> ---
>  Documentation/admin-guide/kernel-parameters.txt | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 97007f4f69d4..ce1c630d6859 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -8249,15 +8249,12 @@ Kernel parameters
>  
>  	vdso32=		[X86] Control the 32-bit vDSO
>  			vdso32=1: enable 32-bit VDSO
> -			vdso32=0 or vdso32=2: disable 32-bit VDSO
> +			vdso32=0: disable 32-bit VDSO
>  
>  			See the help text for CONFIG_COMPAT_VDSO for more
>  			details.  If CONFIG_COMPAT_VDSO is set, the default is
>  			vdso32=0; otherwise, the default is vdso32=1.
>  
> -			For compatibility with older kernels, vdso32=2 is an
> -			alias for vdso32=0.
> -
>  			Try vdso32=0 if you encounter an error that says:
>  			dl_main: Assertion `(void *) ph->p_vaddr == _rtld_local._dl_sysinfo_dso' failed!
>  
> 

-- 
~Randy

^ permalink raw reply

* Re: [PATCH v2 0/7] seg6: add SRv6 Mobile User Plane (RFC 9433) behaviors
From: Andrea Mayer @ 2026-06-08  0:39 UTC (permalink / raw)
  To: Yuya Kusakabe
  Cc: David S. Miller, Eric Dumazet, David Ahern, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Justin Iurman, Shuah Khan,
	Jonathan Corbet, Shuah Khan, linux-kernel, netdev,
	linux-kselftest, linux-doc, stefano.salsano, ahabdels,
	Andrea Mayer, andrea
In-Reply-To: <CAGCJULPdm8jbveZsUm467_LBHRf5g=Jqd=XvCVKdNE1F2U99jg@mail.gmail.com>

On Wed, 20 May 2026 12:12:08 +0900
Yuya Kusakabe <yuya.kusakabe@gmail.com> wrote:

Hi Yuya,

Thanks for the reply. Inline answers below.

> On Sun, May 17, 2026 at 1:26 AM Andrea Mayer <andrea.mayer@uniroma2.it>
> wrote:
>
> > RFC 9433 Section 6 is titled "SRv6 Segment Endpoint Mobility
> > Behaviors", but Section 6.7 defines H.M.GTP4.D as "SR Policy Headend
> > with tunnel decapsulation and map to an SRv6 policy". This behavior
> > receives IPv4 packets and is not bound to any SID, so it does not fit
> > the endpoint model that seg6_local implements. Placing it there
> > required relaxing the ETH_P_IPV6 guard to accept ETH_P_IP and adding
> > input_family to seg6_action_desc, for a single behavior that does not
> > share the endpoint model.
> >
> > seg6_local is not the natural place for this behavior. The UAPI cannot
> > be undone once merged, so where it should live needs discussion on the
> > list before we proceed.
> >
> > Given the volume, moving the MUP code into a separate seg6_mobile.c
> > (say CONFIG_IPV6_SEG6_MUP) would keep seg6_local focused on the RFC
> > 8986 endpoint framework.
>
> I will move the MUP code out of seg6_local into a new
> net/ipv6/seg6_mobile.c under a new Kconfig symbol, and register the
> behaviors under a new lwtunnel encap type rather than
> LWTUNNEL_ENCAP_SEG6_LOCAL.
>

On the placement, the new lwtunnel encap type you propose could be a way to
implement the seg6_mobile.c separation. Since this touches UAPI in
include/uapi/linux/lwtunnel.h beyond the SRv6 subsystem and cannot be
undone once merged, it needs careful design.

> For naming I was thinking CONFIG_IPV6_SEG6_MOBILE and
> LWTUNNEL_ENCAP_SEG6_MOBILE to match the file name, but I have no strong
> preference over CONFIG_IPV6_SEG6_MUP if the list prefers that.

On the Kconfig symbol I agree, CONFIG_IPV6_SEG6_MOBILE matches the RFC 9433
Section 6 terminology better than CONFIG_IPV6_SEG6_MUP. Section 6 is titled
"SRv6 Segment Endpoint Mobility Behaviors".

> Once LWTUNNEL_ENCAP_SEG6_MOBILE is its own encap type, it feels
> natural to me to put H.M.GTP4.D there too rather than adding a
> separate LWTUNNEL_ENCAP_SEG6_MOBILE_HEADEND. What do you think?

H.M.GTP4.D in v2 shares the SEG6_LOCAL_MOBILE_* attributes and processing
helpers with the End.M.* behaviors. A separate
LWTUNNEL_ENCAP_SEG6_MOBILE_HEADEND would require its own attribute set,
lwtunnel_encap_ops, and iproute2 parser, similar to the current
implementation of RFC 8986 in the kernel (seg6 and seg6local).

As far as I can see, RFC 9433 has only one Headend behavior, and no L2 or
reduced variants. So a single LWTUNNEL_ENCAP_SEG6_MOBILE handling both
End.M.* and H.M.GTP4.D could be viable if accepting both input families
(ETH_P_IPV6 for End.M.*, ETH_P_IP for H.M.GTP4.D) is treated as a design
choice of the new encap type, not a stretching of the seg6_local endpoint
processing model.

These trade-offs are worth weighing in the final design. The patchset
rework (shared helper functions, the layout of the new UAPI attributes,
etc.) feeds into this decision. Like the encap type above, this is a UAPI
choice and cannot be undone once merged. I think the lwtunnel direction
will need feedback and comments from its community and maintainers.

> Will do, following the End.DT4/End.DT6/End.DT46 model: one patchset
> per behavior, with the behavior, helpers, and selftest as separate
> patches. The new code will be aligned with seg6_local.c style as
> part of this rework.

Sounds good.

> The mobile behaviors will define their own SEG6_MOBILE_* attribute
> namespace under LWTUNNEL_ENCAP_SEG6_MOBILE, with no reuse of any
> SEG6_LOCAL_* attribute. That keeps the established SEG6_LOCAL_*
> semantics untouched.

If LWTUNNEL_ENCAP_SEG6_MOBILE is added, using SEG6_MOBILE_* attributes
instead of SEG6_LOCAL_* removes the NH6/SRH/OIF overload raised in v2.
After solving the above, additional issues remain in the patchset,
for example src is overloaded across MUP behaviors, and v4_mask_len
needs revision. These are independent of the lwtunnel decision.

> I will drop VRF support from the initial behaviors and revisit it
> later as a separate optional attribute.

OK.

> Good idea. The prep patchset would introduce the SRv6-level reasons
> (SEG6_INVALID_SRH, SEG6_HMAC, ...) and convert the existing
> seg6_local and seg6_iptunnel call sites to use them. The
> mobile-specific reasons (BAD_SID, BAD_GTPU) would then be added
> together with the first behavior that uses them and reused by
> subsequent behaviors. NOMEM and MTU_EXCEEDED would be dropped in
> favor of the existing generic reasons, and the current
> INVALID_SRH_SL / BAD_INNER misuses would be replaced by the new
> SRv6-level reasons from the prep patchset.
>
> Would you prefer to lead on the prep patchset yourself, or would you
> like me to prepare it?

I can lead it. I have been evaluating the SRv6 drop reasons with my
research group, alongside other pending SRv6 patches.

We can sync offline on which SRv6 reasons fit your MUP behaviors, which
v2 MUP-specific reasons would fit better as SRv6 or generic, and what
stays MUP-specific.

> I will replace the python3/scapy heredocs with a statically compiled
> C helper for packet construction and validation, and extend the
> selftests to cover the cases you mention (SRH / no-SRH input paths,
> missing SRH where required, malformed SRH, and invalid attribute
> values).

Thanks. Maybe also worth covering bad packets, like fragmented input or
malformed GTP-U extensions.

> Thanks for taking that on. Given the cb/dst issues you described, I
> am inclined to drop NF_HOOK support from the initial mobile
> behaviors and add it in a follow-up patchset once your fix lands.
> The initial behaviors would then do a direct input -> output flow
> without the cb-context/finish-callback pattern, which avoids the
> issues entirely on day one and decouples this series from the
> pre-existing fix. Does that work for you, or would you prefer
> NF_HOOK to be present from the start and rebased on top of your fix?

Works for me. What matters is that the upcoming patches are well structured
so NF_HOOK can be wired in cleanly in the follow-up.

I am already working on the fix.

Thanks,
Andrea

P.S. I am temporarily writing from another address due to a mail
delivery issue at my @uniroma2.it address. Please always Cc my default
andrea.mayer@uniroma2.it address on replies.

^ permalink raw reply

* Re: [PATCH] hwmon: (asus-ec-sensors) add ROG STRIX B850-E GAMING WIFI
From: Guenter Roeck @ 2026-06-08  0:22 UTC (permalink / raw)
  To: Eugene Shalygin
  Cc: Jonathan Corbet, Shuah Khan, open list:HARDWARE MONITORING,
	open list:DOCUMENTATION, open list
In-Reply-To: <20260607123626.100630-1-eugene.shalygin@gmail.com>

On Sun, Jun 07, 2026 at 02:36:16PM +0200, Eugene Shalygin wrote:
> The board has a similar sensor configuration to the
> ROG STRIX B850-I GAMING WIFI, but includes an additional
> T-Sensor header. The patch was provided via GitHub [1].
> 
> Signed-off-by: Eugene Shalygin <eugene.shalygin@gmail.com>

Applied.

Thanks,
Guenter

> 
> [1] https://github.com/zeule/asus-ec-sensors/pull/105
> ---
>  Documentation/hwmon/asus_ec_sensors.rst |  1 +
>  drivers/hwmon/asus-ec-sensors.c         | 10 ++++++++++
>  2 files changed, 11 insertions(+)
> 
> diff --git a/Documentation/hwmon/asus_ec_sensors.rst b/Documentation/hwmon/asus_ec_sensors.rst
> index 9ad3f0a57f55..9669e729bb8b 100644
> --- a/Documentation/hwmon/asus_ec_sensors.rst
> +++ b/Documentation/hwmon/asus_ec_sensors.rst
> @@ -32,6 +32,7 @@ Supported boards:
>   * ROG STRIX B550-E GAMING
>   * ROG STRIX B550-I GAMING
>   * ROG STRIX B650E-I GAMING WIFI
> + * ROG STRIX B850-E GAMING WIFI
>   * ROG STRIX B850-I GAMING WIFI
>   * ROG STRIX X470-F GAMING
>   * ROG STRIX X470-I GAMING
> diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c
> index b5d97a27f80d..27e39138011e 100644
> --- a/drivers/hwmon/asus-ec-sensors.c
> +++ b/drivers/hwmon/asus-ec-sensors.c
> @@ -628,6 +628,14 @@ static const struct ec_board_info board_info_strix_b650e_i_gaming = {
>  	.family = family_amd_600_series,
>  };
>  
> +static const struct ec_board_info board_info_strix_b850_e_gaming_wifi = {
> +	.sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE |
> +		SENSOR_TEMP_MB | SENSOR_TEMP_VRM |
> +		SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT,
> +	.mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0,
> +	.family = family_amd_800_series,
> +};
> +
>  static const struct ec_board_info board_info_strix_b850_i_gaming_wifi = {
>  	.sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE |
>  		SENSOR_TEMP_MB | SENSOR_TEMP_VRM,
> @@ -868,6 +876,8 @@ static const struct dmi_system_id dmi_table[] = {
>  					&board_info_strix_b550_i_gaming),
>  	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B650E-I GAMING WIFI",
>  					&board_info_strix_b650e_i_gaming),
> +	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B850-E GAMING WIFI",
> +					&board_info_strix_b850_e_gaming_wifi),
>  	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B850-I GAMING WIFI",
>  					&board_info_strix_b850_i_gaming_wifi),
>  	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X470-F GAMING",

^ permalink raw reply

* Re: [PATCH v2 1/1] hwmon: (asus-ec-sensors) add ROG STRIX B650E-E GAMING WIFI
From: Guenter Roeck @ 2026-06-08  0:21 UTC (permalink / raw)
  To: Eugene Shalygin
  Cc: Veronika Kossmann, Oleg Tsvetkov, Jonathan Corbet, Shuah Khan,
	open list:HARDWARE MONITORING, open list:DOCUMENTATION, open list
In-Reply-To: <20260607110702.84599-2-eugene.shalygin@gmail.com>

On Sun, Jun 07, 2026 at 01:06:10PM +0200, Eugene Shalygin wrote:
> From: Veronika Kossmann <nanodesuu@gmail.com>
> 
> Add support for ROG STRIX B650E-E GAMING WIFI
> 
> Signed-off-by: Veronika Kossmann <nanodesuu@gmail.com>
> Co-developed-by: Oleg Tsvetkov <oleg-tsv@yandex.ru>
> Signed-off-by: Oleg Tsvetkov <oleg-tsv@yandex.ru>
> Signed-off-by: Eugene Shalygin <eugene.shalygin@gmail.com>

Applied.

Thanks,
Guenter

> ---
>  Documentation/hwmon/asus_ec_sensors.rst |  1 +
>  drivers/hwmon/asus-ec-sensors.c         | 12 +++++++++++-
>  2 files changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/hwmon/asus_ec_sensors.rst b/Documentation/hwmon/asus_ec_sensors.rst
> index 9ad3f0a57f55..e14419811aac 100644
> --- a/Documentation/hwmon/asus_ec_sensors.rst
> +++ b/Documentation/hwmon/asus_ec_sensors.rst
> @@ -31,6 +31,7 @@ Supported boards:
>   * ROG MAXIMUS Z690 FORMULA
>   * ROG STRIX B550-E GAMING
>   * ROG STRIX B550-I GAMING
> + * ROG STRIX B650E-E GAMING WIFI
>   * ROG STRIX B650E-I GAMING WIFI
>   * ROG STRIX B850-I GAMING WIFI
>   * ROG STRIX X470-F GAMING
> diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c
> index 070bb368f2b7..f351bcfc5679 100644
> --- a/drivers/hwmon/asus-ec-sensors.c
> +++ b/drivers/hwmon/asus-ec-sensors.c
> @@ -274,7 +274,7 @@ static const struct ec_sensor_info sensors_family_amd_600[] = {
>  	[ec_sensor_temp_cpu_package] =
>  		EC_SENSOR("CPU Package", hwmon_temp, 1, 0x00, 0x31),
>  	[ec_sensor_temp_mb] =
> -	EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x32),
> +		EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x32),
>  	[ec_sensor_temp_vrm] =
>  		EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x33),
>  	[ec_sensor_temp_t_sensor] =
> @@ -616,6 +616,14 @@ static const struct ec_board_info board_info_strix_b550_i_gaming = {
>  	.family = family_amd_500_series,
>  };
>  
> +static const struct ec_board_info board_info_strix_b650e_e_gaming = {
> +	.sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE |
> +		SENSOR_TEMP_MB | SENSOR_TEMP_VRM |
> +		SENSOR_FAN_CPU_OPT,
> +	.mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0,
> +	.family = family_amd_600_series,
> +};
> +
>  static const struct ec_board_info board_info_strix_b650e_i_gaming = {
>  	.sensors = SENSOR_TEMP_VRM | SENSOR_TEMP_T_SENSOR |
>  		SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_IN_CPU_CORE,
> @@ -861,6 +869,8 @@ static const struct dmi_system_id dmi_table[] = {
>  					&board_info_strix_b550_e_gaming),
>  	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-I GAMING",
>  					&board_info_strix_b550_i_gaming),
> +	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B650E-E GAMING WIFI",
> +					&board_info_strix_b650e_e_gaming),
>  	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B650E-I GAMING WIFI",
>  					&board_info_strix_b650e_i_gaming),
>  	DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B850-I GAMING WIFI",

^ permalink raw reply

* Re: [RFC] hwmon: add a driver for the temp/voltage sensor on PolarFire SoC
From: Guenter Roeck @ 2026-06-07 23:56 UTC (permalink / raw)
  To: Conor Dooley
  Cc: linux-hwmon, Lars Randers, Conor Dooley, Jonathan Corbet,
	Shuah Khan, Daire McNamara, linux-doc, linux-kernel, linux-riscv,
	Valentina.FernandezAlanis
In-Reply-To: <20260528-defog-lasso-84891a72775a@spud>

On 5/28/26 15:34, Conor Dooley wrote:
> On Wed, May 27, 2026 at 09:07:20PM -0700, Guenter Roeck wrote:
>> On Wed, May 27, 2026 at 10:06:11AM +0100, Conor Dooley wrote:
>>> From: Lars Randers <lranders@mail.dk>
>>>
>>> Add a driver for the temperature and voltage sensors on PolarFire SoC.
>>> The temperature reports how hot the die is, and the voltages are the
>>> SoC's 1.05, 1.8 and 2.5 volt rails respectively.
>>>
>>> The hardware supports alarms in theory, but there is an unconfirmed
>>> erratum that prevents clearing them once triggered, so no support is
>>> added.
>>>
>>> The hardware measures voltage with 16 bits, of which 1 is a sign bit and
>>> the remainder holds the voltage as a fixed point integer value. It's
>>> improbable that the hardware will work if the voltages are negative, so
>>> the driver ignores the sign bits.
>>>
>>> There's no dt support etc here because this is the child of a simple-mfd
>>> syscon.
>>>
>>> Signed-off-by: Lars Randers <lranders@mail.dk>
>>> Co-developed-by: Conor Dooley <conor.dooley@microchip.com>
>>> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
>>> ---
>>> Guenter, there's one question here about the unit that update_interval
>>> is in, I didn't see anyone else using us, but I assume that's okay since
>>> the resolution that ms would give would be 8 steps only?
>>> RFC cos the question is also in the driver as a comment.
>>>
>>
>> That just came up in a different context. We'll add a new standard attribute
>> update_interval_us. The existing attribute MUST use ms. Everything else
>> would be an ABI violation.
> 
> Cool. Sounds like Ferdinand is working on that based on the other
> thread.
> 
> Do you think I should support both update_interval and update_interval_us in
> this driver?
> 

I have been thinking about only supporting one for a given driver, but that
doesn't work because there are existing drivers which would benefit from
supporting microsecond-based intervals, so both it is (unless you want to
wait for _us support to be available and then just support that).

> If yes, should I do the ms version now and add the us version later once
> Ferdinand's work is complete?
> 

Yes, that is what I would recommend.

Thanks,
Guenter


^ permalink raw reply


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