Linux Documentation
 help / color / mirror / Atom feed
* [PATCH v6 11/19] drm/atomic-state-helper: Rename __drm_atomic_helper_crtc_state_reset()
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart, Laurent Pinchart
In-Reply-To: <20260526-drm-mode-config-init-v6-0-852346394200@kernel.org>

__drm_atomic_helper_crtc_state_reset() is used to initialize a newly
allocated drm_crtc_state, and is being typically called by the
drm_crtc_funcs.reset implementation.

Since we want to consolidate DRM objects state allocation around the
atomic_create_state callback that will only allocate and initialize a
new drm_crtc_state instance, we will need to call
__drm_atomic_helper_crtc_state_reset() from both the reset and
atomic_create hooks.

To avoid any confusion, we can thus rename
__drm_atomic_helper_crtc_state_reset() to
__drm_atomic_helper_crtc_state_init().

Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c | 10 +++++-----
 drivers/gpu/drm/i915/display/intel_crtc.c |  2 +-
 include/drm/drm_atomic_state_helper.h     |  2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index ab171bfe6e86..b277f92f4532 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -61,25 +61,25 @@
  * For other drivers the building blocks are split out, see the documentation
  * for these functions.
  */
 
 /**
- * __drm_atomic_helper_crtc_state_reset - reset the CRTC state
+ * __drm_atomic_helper_crtc_state_init - Initialize the CRTC state
  * @crtc_state: atomic CRTC state, must not be NULL
  * @crtc: CRTC object, must not be NULL
  *
  * Initializes the newly allocated @crtc_state with default
  * values. This is useful for drivers that subclass the CRTC state.
  */
 void
-__drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state,
-				     struct drm_crtc *crtc)
+__drm_atomic_helper_crtc_state_init(struct drm_crtc_state *crtc_state,
+				    struct drm_crtc *crtc)
 {
 	crtc_state->crtc = crtc;
 	crtc_state->background_color = DRM_ARGB64_PREP(0xffff, 0, 0, 0);
 }
-EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset);
+EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_init);
 
 /**
  * __drm_atomic_helper_crtc_reset - reset state on CRTC
  * @crtc: drm CRTC
  * @crtc_state: CRTC state to assign
@@ -94,11 +94,11 @@ EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset);
 void
 __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
 			       struct drm_crtc_state *crtc_state)
 {
 	if (crtc_state)
-		__drm_atomic_helper_crtc_state_reset(crtc_state, crtc);
+		__drm_atomic_helper_crtc_state_init(crtc_state, crtc);
 
 	if (drm_dev_has_vblank(crtc->dev))
 		drm_crtc_vblank_reset(crtc);
 
 	crtc->state = crtc_state;
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index 03de219f7a64..7486f2dc60ef 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -179,11 +179,11 @@ struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc)
 void intel_crtc_state_reset(struct intel_crtc_state *crtc_state,
 			    struct intel_crtc *crtc)
 {
 	memset(crtc_state, 0, sizeof(*crtc_state));
 
-	__drm_atomic_helper_crtc_state_reset(&crtc_state->uapi, &crtc->base);
+	__drm_atomic_helper_crtc_state_init(&crtc_state->uapi, &crtc->base);
 
 	crtc_state->cpu_transcoder = INVALID_TRANSCODER;
 	crtc_state->master_transcoder = INVALID_TRANSCODER;
 	crtc_state->hsw_workaround_pipe = INVALID_PIPE;
 	crtc_state->scaler_state.scaler_id = -1;
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index 8d1ef268fdef..0bb72453464a 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -38,11 +38,11 @@ struct drm_connector_state;
 struct drm_private_obj;
 struct drm_private_state;
 struct drm_modeset_acquire_ctx;
 struct drm_device;
 
-void __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *state,
+void __drm_atomic_helper_crtc_state_init(struct drm_crtc_state *state,
 					  struct drm_crtc *crtc);
 void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
 				    struct drm_crtc_state *state);
 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc);
 void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,

-- 
2.54.0


^ permalink raw reply related

* [PATCH v6 10/19] drm/plane: Add new atomic_create_state callback
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart
In-Reply-To: <20260526-drm-mode-config-init-v6-0-852346394200@kernel.org>

Commit 47b5ac7daa46 ("drm/atomic: Add new atomic_create_state callback
to drm_private_obj") introduced a new pattern for allocating drm object
states.

Instead of relying on the reset() callback, it created a new
atomic_create_state hook. This is helpful because reset is a bit
overloaded: it's used to create the initial software state, reset it,
but also reset the hardware.

It can also be used either at probe time, to create the initial state
and possibly reset the hardware to an expected default, but also during
suspend/resume.

Both these cases come with different expectations too: during the
initialization, we want to initialize all states, but during
suspend/resume, drm_private_states for example are expected to be kept
around.

reset() also isn't fallible, which makes it harder to handle
initialization errors properly. This is only really relevant for some
drivers though, since all the helpers for reset only create a new
state, and don't touch the hardware at all.

It was thus decided to create a new hook that would allocate and
initialize a pristine state without any side effect:
atomic_create_state to untangle a bit some of it, and to separate the
initialization with the actual reset one might need during a
suspend/resume.

Continue the transition to the new pattern with planes.

Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c | 25 +++++++++++++++++++++++++
 drivers/gpu/drm/drm_mode_config.c         | 31 ++++++++++++++++++++++++++++++-
 include/drm/drm_atomic_state_helper.h     |  2 ++
 include/drm/drm_plane.h                   | 16 ++++++++++++++++
 4 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index ee01700d4ca7..ab171bfe6e86 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -338,10 +338,35 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane)
 	if (plane->state)
 		__drm_atomic_helper_plane_reset(plane, plane->state);
 }
 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
 
+/**
+ * drm_atomic_helper_plane_create_state - default &drm_plane_funcs.atomic_create_state hook for planes
+ * @plane: plane object
+ *
+ * Allocates and initializes pristine @drm_plane_state.
+ *
+ * This is useful for drivers that don't subclass @drm_plane_state.
+ *
+ * RETURNS:
+ * Pointer to new plane state, or ERR_PTR on failure.
+ */
+struct drm_plane_state *drm_atomic_helper_plane_create_state(struct drm_plane *plane)
+{
+	struct drm_plane_state *state;
+
+	state = kzalloc_obj(*state);
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	__drm_atomic_helper_plane_state_init(state, plane);
+
+	return state;
+}
+EXPORT_SYMBOL(drm_atomic_helper_plane_create_state);
+
 /**
  * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state
  * @plane: plane object
  * @state: atomic plane state
  *
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index c33382a38191..fa609357858f 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -180,10 +180,36 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
 	drm_connector_list_iter_end(&conn_iter);
 
 	return ret;
 }
 
+static int drm_mode_config_plane_create_state(struct drm_plane *plane)
+{
+	struct drm_plane_state *plane_state;
+
+	if (!plane->funcs->atomic_create_state)
+		return 0;
+
+	plane_state = plane->funcs->atomic_create_state(plane);
+	if (IS_ERR(plane_state))
+		return PTR_ERR(plane_state);
+
+	plane->state = plane_state;
+
+	return 0;
+}
+
+static int drm_mode_config_plane_reset_with_create_state(struct drm_plane *plane)
+{
+	if (plane->state) {
+		plane->funcs->atomic_destroy_state(plane, plane->state);
+		plane->state = NULL;
+	}
+
+	return drm_mode_config_plane_create_state(plane);
+}
+
 /**
  * drm_mode_config_reset - call ->reset callbacks
  * @dev: drm device
  *
  * This functions calls all the crtc's, encoder's and connector's ->reset
@@ -204,13 +230,16 @@ void drm_mode_config_reset(struct drm_device *dev)
 	struct drm_connector_list_iter conn_iter;
 
 	drm_for_each_colorop(colorop, dev)
 		drm_colorop_reset(colorop);
 
-	drm_for_each_plane(plane, dev)
+	drm_for_each_plane(plane, dev) {
 		if (plane->funcs->reset)
 			plane->funcs->reset(plane);
+		else if (plane->funcs->atomic_create_state)
+			drm_mode_config_plane_reset_with_create_state(plane);
+	}
 
 	drm_for_each_crtc(crtc, dev)
 		if (crtc->funcs->reset)
 			crtc->funcs->reset(crtc);
 
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index 691c1ccfa4e0..8d1ef268fdef 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -53,10 +53,12 @@ void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state);
 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
 					  struct drm_crtc_state *state);
 
 void __drm_atomic_helper_plane_state_init(struct drm_plane_state *state,
 					   struct drm_plane *plane);
+struct drm_plane_state *
+drm_atomic_helper_plane_create_state(struct drm_plane *plane);
 void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
 				     struct drm_plane_state *state);
 void drm_atomic_helper_plane_reset(struct drm_plane *plane);
 void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
 					       struct drm_plane_state *state);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 419c88c873a6..2c5a5a70a71b 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -386,10 +386,26 @@ struct drm_plane_funcs {
 	 * 0 on success or a negative error code on failure.
 	 */
 	int (*set_property)(struct drm_plane *plane,
 			    struct drm_property *property, uint64_t val);
 
+	/**
+	 * @atomic_create_state:
+	 *
+	 * Allocate a pristine, initialized, state for the plane object
+	 * and return it. This callback must have no side effects: in
+	 * particular, the returned state must not be assigned to the
+	 * object's state pointer and it must not affect the hardware
+	 * state.
+	 *
+	 * RETURNS:
+	 *
+	 * A new, pristine, plane state instance or an error pointer
+	 * on failure.
+	 */
+	struct drm_plane_state *(*atomic_create_state)(struct drm_plane *plane);
+
 	/**
 	 * @atomic_duplicate_state:
 	 *
 	 * Duplicate the current atomic state for this plane and return it.
 	 * The core and helpers guarantee that any atomic state duplicated with

-- 
2.54.0


^ permalink raw reply related

* [PATCH v6 09/19] drm/atomic-state-helper: Rename __drm_atomic_helper_plane_state_reset()
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart, Laurent Pinchart
In-Reply-To: <20260526-drm-mode-config-init-v6-0-852346394200@kernel.org>

__drm_atomic_helper_plane_state_reset() is used to initialize a newly
allocated drm_plane_state, and is being typically called by the
drm_plane_funcs.reset implementation.

Since we want to consolidate DRM objects state allocation around the
atomic_create_state callback that will only allocate and initialize a
new drm_plane_state instance, we will need to call
__drm_atomic_helper_plane_state_reset() from both the reset and
atomic_create hooks.

To avoid any confusion, we can thus rename
__drm_atomic_helper_plane_state_reset() to
__drm_atomic_helper_plane_state_init().

Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c  | 12 ++++++------
 drivers/gpu/drm/i915/display/intel_plane.c |  2 +-
 include/drm/drm_atomic_state_helper.h      |  2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index c8ccf8be5074..ee01700d4ca7 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -235,19 +235,19 @@ void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
 	kfree(state);
 }
 EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
 
 /**
- * __drm_atomic_helper_plane_state_reset - resets plane state to default values
+ * __drm_atomic_helper_plane_state_init - Initialize the plane state
  * @plane_state: atomic plane state, must not be NULL
  * @plane: plane object, must not be NULL
  *
  * Initializes the newly allocated @plane_state with default
- * values. This is useful for drivers that subclass the CRTC state.
+ * values. This is useful for drivers that subclass the plane state.
  */
-void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
-					   struct drm_plane *plane)
+void __drm_atomic_helper_plane_state_init(struct drm_plane_state *plane_state,
+					  struct drm_plane *plane)
 {
 	u64 val;
 
 	plane_state->plane = plane;
 	plane_state->rotation = DRM_MODE_ROTATE_0;
@@ -295,11 +295,11 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
 							   plane->hotspot_y_property,
 							   &val))
 			plane_state->hotspot_y = val;
 	}
 }
-EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
+EXPORT_SYMBOL(__drm_atomic_helper_plane_state_init);
 
 /**
  * __drm_atomic_helper_plane_reset - reset state on plane
  * @plane: drm plane
  * @plane_state: plane state to assign
@@ -313,11 +313,11 @@ EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
  */
 void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
 				     struct drm_plane_state *plane_state)
 {
 	if (plane_state)
-		__drm_atomic_helper_plane_state_reset(plane_state, plane);
+		__drm_atomic_helper_plane_state_init(plane_state, plane);
 
 	plane->state = plane_state;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
 
diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
index c181a7d063ec..11467d19399d 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -65,11 +65,11 @@
 static void intel_plane_state_reset(struct intel_plane_state *plane_state,
 				    struct intel_plane *plane)
 {
 	memset(plane_state, 0, sizeof(*plane_state));
 
-	__drm_atomic_helper_plane_state_reset(&plane_state->uapi, &plane->base);
+	__drm_atomic_helper_plane_state_init(&plane_state->uapi, &plane->base);
 
 	plane_state->scaler_id = -1;
 	plane_state->fence_id = -1;
 }
 
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index 61a3b38ad49f..691c1ccfa4e0 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -51,11 +51,11 @@ struct drm_crtc_state *
 drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc);
 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state);
 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
 					  struct drm_crtc_state *state);
 
-void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *state,
+void __drm_atomic_helper_plane_state_init(struct drm_plane_state *state,
 					   struct drm_plane *plane);
 void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
 				     struct drm_plane_state *state);
 void drm_atomic_helper_plane_reset(struct drm_plane *plane);
 void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,

-- 
2.54.0


^ permalink raw reply related

* [PATCH v6 08/19] drm/atomic-state-helper: Fix __drm_atomic_helper_plane_reset() doc typo
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart
In-Reply-To: <20260526-drm-mode-config-init-v6-0-852346394200@kernel.org>

A typo has slipped through in the __drm_atomic_helper_plane_reset()
documentation, probably due to copy and paste. It will not assign
drm_crtc state pointer, but rather the drm_plane's.

Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index a82568d87e4f..c8ccf8be5074 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -303,11 +303,11 @@ EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
  * __drm_atomic_helper_plane_reset - reset state on plane
  * @plane: drm plane
  * @plane_state: plane state to assign
  *
  * Initializes the newly allocated @plane_state and assigns it to
- * the &drm_crtc->state pointer of @plane, usually required when
+ * the &drm_plane->state pointer of @plane, usually required when
  * initializing the drivers or when called from the &drm_plane_funcs.reset
  * hook.
  *
  * This is useful for drivers that subclass the plane state.
  */

-- 
2.54.0


^ permalink raw reply related

* [PATCH v6 07/19] drm/colorop: Create drm_atomic_helper_colorop_create_state()
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart
In-Reply-To: <20260526-drm-mode-config-init-v6-0-852346394200@kernel.org>

Commit 47b5ac7daa46 ("drm/atomic: Add new atomic_create_state callback
to drm_private_obj") introduced a new pattern for allocating drm object
states.

Instead of relying on the reset() callback, it created a new
atomic_create_state hook. This is helpful because reset is a bit
overloaded: it's used to create the initial software state, reset it,
but also reset the hardware.

It can also be used either at probe time, to create the initial state
and possibly reset the hardware to an expected default, but also during
suspend/resume.

Both these cases come with different expectations too: during the
initialization, we want to initialize all states, but during
suspend/resume, drm_private_states for example are expected to be kept
around.

reset() also isn't fallible, which makes it harder to handle
initialization errors properly. This is only really relevant for some
drivers though, since all the helpers for reset only create a new
state, and don't touch the hardware at all.

It was thus decided to create a new hook that would allocate and
initialize a pristine state without any side effect:
atomic_create_state to untangle a bit some of it, and to separate the
initialization with the actual reset one might need during a
suspend/resume.

Continue the transition to the new pattern with drm_colorop.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/drm_colorop.c | 23 +++++++++++++++++++++++
 include/drm/drm_colorop.h     |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index 4c4d0a953e35..c0eecde8c176 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -521,10 +521,33 @@ static void __drm_colorop_state_init(struct drm_colorop_state *colorop_state,
 							   &val))
 			colorop_state->curve_1d_type = val;
 	}
 }
 
+/**
+ * drm_atomic_helper_colorop_create_state - Allocates and initializes colorop atomic state
+ * @colorop: drm colorop
+ *
+ * Initializes a pristine @drm_colorop_state.
+ *
+ * RETURNS:
+ * Pointer to new colorop state, or ERR_PTR on failure.
+ */
+struct drm_colorop_state *
+drm_atomic_helper_colorop_create_state(struct drm_colorop *colorop)
+{
+	struct drm_colorop_state *state;
+
+	state = kzalloc_obj(*state);
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	__drm_colorop_state_init(state, colorop);
+
+	return state;
+}
+
 /**
  * __drm_colorop_reset - reset state on colorop
  * @colorop: drm colorop
  * @colorop_state: colorop state to assign
  *
diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
index c873199c60da..b4b9e4f558ab 100644
--- a/include/drm/drm_colorop.h
+++ b/include/drm/drm_colorop.h
@@ -423,10 +423,12 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
 				 struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
 				 uint32_t lut_size,
 				 enum drm_colorop_lut3d_interpolation_type interpolation,
 				 uint32_t flags);
 
+struct drm_colorop_state *
+drm_atomic_helper_colorop_create_state(struct drm_colorop *colorop);
 struct drm_colorop_state *
 drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop);
 
 void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
 				      struct drm_colorop_state *state);

-- 
2.54.0


^ permalink raw reply related

* [PATCH v6 06/19] drm/colorop: Rename __drm_colorop_state_reset()
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart
In-Reply-To: <20260526-drm-mode-config-init-v6-0-852346394200@kernel.org>

__drm_colorop_state_reset() is used to initialize a newly allocated
drm_colorop_state, and is being typically called by drm_colorop_reset().

Since we want to consolidate DRM objects state allocation around the
atomic_create_state callback that will only allocate and initialize a
new drm_colorop_state instance, we will need to call
__drm_colorop_state_reset() from both the reset and atomic_create paths.

To avoid any confusion, we can thus rename __drm_colorop_state_reset()
to __drm_colorop_state_init().

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/drm_colorop.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index 48d0b7ae3fc9..4c4d0a953e35 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -498,19 +498,19 @@ void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
 	__drm_atomic_helper_colorop_destroy_state(state);
 	kfree(state);
 }
 
 /**
- * __drm_colorop_state_reset - resets colorop state to default values
+ * __drm_colorop_state_init - Initializes colorop state to default values
  * @colorop_state: atomic colorop state, must not be NULL
  * @colorop: colorop object, must not be NULL
  *
  * Initializes the newly allocated @colorop_state with default
  * values. This is useful for drivers that subclass the colorop state.
  */
-static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
-				      struct drm_colorop *colorop)
+static void __drm_colorop_state_init(struct drm_colorop_state *colorop_state,
+				     struct drm_colorop *colorop)
 {
 	u64 val;
 
 	colorop_state->colorop = colorop;
 	colorop_state->bypass = true;
@@ -537,11 +537,11 @@ static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
  */
 static void __drm_colorop_reset(struct drm_colorop *colorop,
 				struct drm_colorop_state *colorop_state)
 {
 	if (colorop_state)
-		__drm_colorop_state_reset(colorop_state, colorop);
+		__drm_colorop_state_init(colorop_state, colorop);
 
 	colorop->state = colorop_state;
 }
 
 void drm_colorop_reset(struct drm_colorop *colorop)

-- 
2.54.0


^ permalink raw reply related

* [PATCH v6 05/19] drm/mode-config: Document drm_private_obj exclusion from drm_mode_config_reset()
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart
In-Reply-To: <20260526-drm-mode-config-init-v6-0-852346394200@kernel.org>

drm_mode_config_reset() does not reset drm_private_states by design.

This is especially significant for the DP MST and tunneling code that
expect to be preserved across a suspend/resume cycle, where
drm_mode_config_reset() is also used.

Document this expectation.

Link: https://lore.kernel.org/dri-devel/aOaQLx-7EpsHRwkH@ideak-desk/
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/drm_mode_config.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 66f7dc37b597..c33382a38191 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -187,10 +187,14 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
  * @dev: drm device
  *
  * This functions calls all the crtc's, encoder's and connector's ->reset
  * callback. Drivers can use this in e.g. their driver load or resume code to
  * reset hardware and software state.
+ *
+ * Note that &drm_private_obj structures are expected to be stable across
+ * suspend/resume cycles, and drm_mode_config_reset() does not affect these
+ * structures.
  */
 void drm_mode_config_reset(struct drm_device *dev)
 {
 	struct drm_crtc *crtc;
 	struct drm_colorop *colorop;

-- 
2.54.0


^ permalink raw reply related

* [PATCH v6 04/19] drm/atomic: Expand atomic_create_state expectations for drm_private_obj
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart
In-Reply-To: <20260526-drm-mode-config-init-v6-0-852346394200@kernel.org>

The atomic_create_state callback documentation for planes, CRTCs, and
connectors explicitly states the expected behaviour: the returned
state must not be assigned to the object's state pointer, and hardware
must not be touched.

The drm_private_state_funcs.atomic_create_state documentation is
missing this clarification. Add it for consistency.

Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 include/drm/drm_atomic.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 1a80a8cdf269..88087910ab1a 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -263,11 +263,14 @@ struct drm_private_state;
 struct drm_private_state_funcs {
 	/**
 	 * @atomic_create_state:
 	 *
 	 * Allocates a pristine, initialized, state for the private
-	 * object and returns it.
+	 * object and returns it. This callback must have no side
+	 * effects: in particular, the returned state must not be
+	 * assigned to the object's state pointer and it must not affect
+	 * the hardware state.
 	 *
 	 * RETURNS:
 	 *
 	 * A new, pristine, private state instance or an error pointer
 	 * on failure.

-- 
2.54.0


^ permalink raw reply related

* [PATCH v6 03/19] drm/atomic: Drop drm_private_obj.state assignment from create_state
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart
In-Reply-To: <20260526-drm-mode-config-init-v6-0-852346394200@kernel.org>

The initial intent of the atomic_create_state hook was to simply
allocate a proper drm_private_state and return it, without any side
effect.

However, __drm_atomic_helper_private_obj_create_state(), which most
atomic_create_state implementations call, introduces a side effect by
setting drm_private_obj.state to the newly allocated state.

This assignment defeats the purpose, but is also redundant since
drm_atomic_private_obj_init(), the only call site for the
atomic_create_state hook, will also set this pointer to the newly
allocated state.

Drop the assignment in __drm_atomic_helper_private_obj_create_state().

Fixes: e7be39ed1716 ("drm/atomic-helper: Add private_obj atomic_create_state helper")
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/drm_atomic_state_helper.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index cc70508d4fdb..a82568d87e4f 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -729,12 +729,10 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
 void __drm_atomic_helper_private_obj_create_state(struct drm_private_obj *obj,
 						  struct drm_private_state *state)
 {
 	if (state)
 		state->obj = obj;
-
-	obj->state = state;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_private_obj_create_state);
 
 /**
  * __drm_atomic_helper_private_obj_duplicate_state - copy atomic private state

-- 
2.54.0


^ permalink raw reply related

* [PATCH v6 02/19] drm/colorop: Fix typos in the doc
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart
In-Reply-To: <20260526-drm-mode-config-init-v6-0-852346394200@kernel.org>

In the documentation of drm_colorop introduced by commit cfc27680ee20
("drm/colorop: Introduce new drm_colorop mode object"), the
documentation of __drm_colorop_state_reset() and __drm_colorop_reset()
were mentioning CRTC when they really meant colorop, probably due to
copy and paste.

Fixes: cfc27680ee20 ("drm/colorop: Introduce new drm_colorop mode object")
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 drivers/gpu/drm/drm_colorop.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index 764d12060666..48d0b7ae3fc9 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -503,11 +503,11 @@ void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
  * __drm_colorop_state_reset - resets colorop state to default values
  * @colorop_state: atomic colorop state, must not be NULL
  * @colorop: colorop object, must not be NULL
  *
  * Initializes the newly allocated @colorop_state with default
- * values. This is useful for drivers that subclass the CRTC state.
+ * values. This is useful for drivers that subclass the colorop state.
  */
 static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
 				      struct drm_colorop *colorop)
 {
 	u64 val;
@@ -526,14 +526,14 @@ static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
 /**
  * __drm_colorop_reset - reset state on colorop
  * @colorop: drm colorop
  * @colorop_state: colorop state to assign
  *
- * Initializes the newly allocated @colorop_state and assigns it to
- * the &drm_crtc->state pointer of @colorop, usually required when
- * initializing the drivers or when called from the &drm_colorop_funcs.reset
- * hook.
+ * Initializes the newly allocated @colorop_state and assigns it to the
+ * &drm_colorop->state pointer of @colorop, usually required when
+ * initializing the drivers or when called from the
+ * &drm_colorop_funcs.reset hook.
  *
  * This is useful for drivers that subclass the colorop state.
  */
 static void __drm_colorop_reset(struct drm_colorop *colorop,
 				struct drm_colorop_state *colorop_state)

-- 
2.54.0


^ permalink raw reply related

* [PATCH v6 01/19] drm/atomic: Document atomic commit lifetime
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart
In-Reply-To: <20260526-drm-mode-config-init-v6-0-852346394200@kernel.org>

How drm_atomic_commit and the various entity structures are allocated
and freed isn't really trivial. Document it.

Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
 Documentation/gpu/drm-kms.rst |  6 ++++
 drivers/gpu/drm/drm_atomic.c  | 72 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index d22817fdf9aa..36d76e391074 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -282,10 +282,16 @@ structure, ordering of committing state changes to hardware is sequenced using
 :c:type:`struct drm_crtc_commit <drm_crtc_commit>`.
 
 Read on in this chapter, and also in :ref:`drm_atomic_helper` for more detailed
 coverage of specific topics.
 
+Atomic State Lifetime
+---------------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_atomic.c
+   :doc: state lifetime
+
 Handling Driver Private State
 -----------------------------
 
 .. kernel-doc:: drivers/gpu/drm/drm_atomic.c
    :doc: handling driver private state
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 170de30c28ae..3c5714481ad2 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -45,10 +45,82 @@
 #include <drm/drm_colorop.h>
 
 #include "drm_crtc_internal.h"
 #include "drm_internal.h"
 
+/**
+ * DOC: state lifetime
+ *
+ * &drm_atomic_commit represents an update to modeset pipeline state.
+ * It's a transient object that holds a state update as a collection of
+ * pointers to individual objects' states. &struct drm_atomic_commit has
+ * a much shorter lifetime than the objects' states, since it's only
+ * allocated while preparing, checking or committing the update, while
+ * object states are allocated when preparing the update and kept alive
+ * as long as they are active in the device.
+ *
+ * Their respective lifetimes are:
+ *
+ * - at reset time, the object reset implementation allocates a new
+ *   default state and stores it in the object state pointer.
+ *
+ * - whenever a new update is needed:
+ *
+ *   + drm_atomic_commit_alloc() allocates a new &drm_atomic_commit
+ *     instance.
+ *
+ *   + The code triggering the commit (ioctl, client modeset,
+ *     drm_atomic_helper_reset_crtc(), etc.) copies the current active
+ *     state of all entities affected by the update into this new
+ *     &drm_atomic_commit using drm_atomic_get_plane_state(),
+ *     drm_atomic_get_crtc_state(), drm_atomic_get_connector_state(), or
+ *     drm_atomic_get_private_obj_state(). This new state can then be
+ *     modified.
+ *
+ *     At that point, &drm_atomic_commit stores three state pointers for
+ *     any affected entity: the "old" and "new" states, and
+ *     state_to_destroy. The old state is the state currently active in
+ *     the hardware, which is either the one initialized by reset() or a
+ *     newer one if a commit has been made. The new state is the state
+ *     we just allocated and we might eventually commit to the hardware.
+ *     The state_to_destroy points to the state we'll eventually have to
+ *     free when the drm_atomic_commit will be destroyed, and points to
+ *     the new state for now since the old state is still the active
+ *     state.
+ *
+ *   + After the calling code populated the commit with the entities
+ *     states, it updates the new states with the new values we need to
+ *     commit. The new commit instance is now ready.
+ *
+ *   + Then we have two branches depending on the calling code intent:
+ *
+ *     - If the calling code only wants to check that the commit would
+ *       work (for example because of the DRM_MODE_ATOMIC_TEST_ONLY
+ *       flag). It calls drm_atomic_check_only(), which in turn checks
+ *       all these states by invoking atomic_check on all affected
+ *       pipeline stages.
+ *
+ *     - If the calling code actually wants to trigger a commit, it
+ *       calls drm_atomic_commit(). The first stage is the check
+ *       mentioned above, and if the check is successful, it performs
+ *       the commit. Part of the commit is a call to
+ *       drm_atomic_helper_swap_state() which turns the new states into
+ *       the active states. After swapping states, each object's state
+ *       pointer now refers to the formerly new state. The
+ *       state_to_destroy now refers to the formerly old state.
+ *
+ *   + Once done, and when the last refererence to our &struct
+ *     drm_atomic_commit is given up through drm_atomic_commit_put(), it
+ *     calls __drm_atomic_commit_free(). In turn,
+ *     __drm_atomic_commit_free() calls drm_atomic_commit_clear() that
+ *     will free all state_to_destroy (ie. old states), and it finally
+ *     frees &drm_atomic_commit instance.
+ *
+ *   + Now, we don't have any active &drm_atomic_commit anymore, and
+ *     only the entity active states remain allocated.
+ */
+
 void __drm_crtc_commit_free(struct kref *kref)
 {
 	struct drm_crtc_commit *commit =
 		container_of(kref, struct drm_crtc_commit, ref);
 

-- 
2.54.0


^ permalink raw reply related

* [PATCH v6 00/19] drm/atomic: Rework initial state allocation
From: Maxime Ripard @ 2026-05-26 16:46 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Jonathan Corbet, Shuah Khan, Dmitry Baryshkov, Jyri Sarha,
	Tomi Valkeinen, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Simon Ser,
	Harry Wentland, Melissa Wen, Sebastian Wick, Alex Hung,
	Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	Chen-Yu Tsai, Samuel Holland, Dave Stevenson, Maíra Canal,
	Raspberry Pi Kernel Maintenance
  Cc: dri-devel, linux-doc, linux-kernel, Daniel Stone, intel-gfx,
	intel-xe, linux-arm-kernel, linux-sunxi, Maxime Ripard,
	Laurent Pinchart, Laurent Pinchart

Hi,

This series started from my work on the hardware state readout[1], and
more specifically a discussion with Thomas[2].

This series expands the work that has been merged recently to make
drm_private_obj and drm_private_state allocation a bit more consistent
and ended up creating a new atomic_create_state callback to allocate a
new state with no side effect.

The first patches document the existing behaviour and fix a few
cleanups and typos.

Then, __drm_*_state_reset() helpers are renamed to
__drm_*_state_init() to clarify that they initialize rather than
reset state, and we add the new atomic_create_state callback to
every other DRM object (planes, CRTCs, connectors, colorops).

Next, we leverage those new callbacks to create a new helper,
drm_mode_config_create_initial_state(), to create the initial state
for all the objects of a driver, and update the driver skeleton to
recommend it.

Finally, we convert the tidss driver and the bridge_connector to the
new pattern.

This was tested on a TI SK-AM62, with the tidss driver.

Let me know what you think,
Maxime

1: https://lore.kernel.org/dri-devel/20250902-drm-state-readout-v1-0-14ad5315da3f@kernel.org/
2: https://lore.kernel.org/dri-devel/5920ffe5-b6b1-484b-b320-332b9eb9db82@suse.de/

Signed-off-by: Maxime Ripard <mripard@kernel.org>
---
Changes in v6:
- Reword the docs according to Thomas review
- Link to v5: https://lore.kernel.org/r/20260519-drm-mode-config-init-v5-0-388b03321e38@kernel.org

Changes in v5:
- Address sashiko reviews
- Improve the docs
- Fix drmm_connector_hdmi_init
- Drop drm/tidss: Switch to drm_mode_config_create_initial_state since
  not all possible bridges would have been converted to create_state 
- Link to v4: https://lore.kernel.org/r/20260512-drm-mode-config-init-v4-0-591dfdcc1bf9@kernel.org

Changes in v4:
- Rebased on current drm-misc-next
- Update drm_atomic_state to drm_atomic_commit
- Various doc impromvements
- Don't call drm_crtc_vblank_reset in create_state
- Prevent mem leak if states already have a state when
  drm_mode_config_reset or _create_initial_state are called
- Link to v3: https://lore.kernel.org/r/20260424-drm-mode-config-init-v3-0-8b68d9db0d8b@kernel.org

Changes in v3:
- Reintroduce state documentation that was dropped by accident
- Change name to drm_mode_config_create_initial_state()
- Don't call drm_mode_config_create_initial_state() in drm_dev_register
  anymore
- Drop __drm_atomic_helper_*_create_state
- Improve documentation and commit messages where necessary
- Collected tags
- Link to v2: https://lore.kernel.org/r/20260320-drm-mode-config-init-v2-0-c63f1134e76c@kernel.org

Changes in v2:
- Change the _state_reset function names to _state_init
- Change the colorop too
- Various doc improvements
- Link to v1: https://lore.kernel.org/r/20260310-drm-mode-config-init-v1-0-de7397c8e1cf@kernel.org

---
Maxime Ripard (19):
      drm/atomic: Document atomic commit lifetime
      drm/colorop: Fix typos in the doc
      drm/atomic: Drop drm_private_obj.state assignment from create_state
      drm/atomic: Expand atomic_create_state expectations for drm_private_obj
      drm/mode-config: Document drm_private_obj exclusion from drm_mode_config_reset()
      drm/colorop: Rename __drm_colorop_state_reset()
      drm/colorop: Create drm_atomic_helper_colorop_create_state()
      drm/atomic-state-helper: Fix __drm_atomic_helper_plane_reset() doc typo
      drm/atomic-state-helper: Rename __drm_atomic_helper_plane_state_reset()
      drm/plane: Add new atomic_create_state callback
      drm/atomic-state-helper: Rename __drm_atomic_helper_crtc_state_reset()
      drm/crtc: Add new atomic_create_state callback
      drm/atomic-state-helper: Rename __drm_atomic_helper_connector_state_reset()
      drm/hdmi: Rename __drm_atomic_helper_connector_hdmi_reset()
      drm/connector: Add new atomic_create_state callback
      drm/mode-config: Create drm_mode_config_create_initial_state()
      drm/drv: Switch skeleton to drm_mode_config_create_initial_state()
      drm/tidss: Convert to atomic_create_state
      drm/bridge_connector: Convert to atomic_create_state

 Documentation/gpu/drm-kms.rst                      |   6 +
 drivers/gpu/drm/display/drm_bridge_connector.c     |  17 +-
 drivers/gpu/drm/display/drm_hdmi_state_helper.c    |  15 +-
 drivers/gpu/drm/drm_atomic.c                       |  80 +++++++++
 drivers/gpu/drm/drm_atomic_state_helper.c          | 114 ++++++++++---
 drivers/gpu/drm/drm_colorop.c                      |  41 ++++-
 drivers/gpu/drm/drm_connector.c                    |  10 +-
 drivers/gpu/drm/drm_drv.c                          |   4 +-
 drivers/gpu/drm/drm_mode_config.c                  | 189 ++++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_crtc.c          |   2 +-
 drivers/gpu/drm/i915/display/intel_plane.c         |   2 +-
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c             |   2 +-
 drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c |   2 +-
 drivers/gpu/drm/tidss/tidss_crtc.c                 |  17 +-
 drivers/gpu/drm/tidss/tidss_plane.c                |   2 +-
 drivers/gpu/drm/vc4/vc4_hdmi.c                     |   2 +-
 include/drm/display/drm_hdmi_state_helper.h        |   4 +-
 include/drm/drm_atomic.h                           |   5 +-
 include/drm/drm_atomic_state_helper.h              |  12 +-
 include/drm/drm_colorop.h                          |   2 +
 include/drm/drm_connector.h                        |  16 ++
 include/drm/drm_crtc.h                             |  16 ++
 include/drm/drm_mode_config.h                      |   1 +
 include/drm/drm_plane.h                            |  16 ++
 24 files changed, 509 insertions(+), 68 deletions(-)
---
base-commit: 69c95e4c529297c25503e60acba757fba24fdc95
change-id: 20260310-drm-mode-config-init-1e1f52b745d0

Best regards,
-- 
Maxime Ripard <mripard@kernel.org>


^ permalink raw reply

* Re: [PATCH v6 06/11] x86/virt/tdx: Optimize tdx_pamt_get/put()
From: Edgecombe, Rick P @ 2026-05-26 16:42 UTC (permalink / raw)
  To: Gao, Chao
  Cc: kvm@vger.kernel.org, linux-coco@lists.linux.dev, Huang, Kai,
	Hansen, Dave, Zhao, Yan Y, kas@kernel.org, seanjc@google.com,
	mingo@redhat.com, linux-kernel@vger.kernel.org,
	pbonzini@redhat.com, nik.borisov@suse.com,
	linux-doc@vger.kernel.org, hpa@zytor.com, tglx@kernel.org,
	Annapurve, Vishal, bp@alien8.de, kirill.shutemov@linux.intel.com,
	x86@kernel.org
In-Reply-To: <ahVghgNAe4JrmlQH@intel.com>

On Tue, 2026-05-26 at 16:57 +0800, Chao Gao wrote:
> > -	scoped_guard(spinlock, &pamt_lock) {
> 
> This converts the scoped_guard() added by the previous patch to
> explicit lock/unlock and goto. It would reduce code churn if the
> previous patch used that form directly.

Yea, it's a good point. I actually debated doing it, but decided not to because
the scoped version is cleaner for the non-optimized version. But for
reviewability, never doing the scoped version is probably better.

^ permalink raw reply

* Re: [PATCH v12 00/16] Direct Map Removal Support for guest_memfd
From: Lorenzo Stoakes @ 2026-05-26 16:27 UTC (permalink / raw)
  To: Takahiro Itazuri
  Cc: seanjc, Liam.Howlett, ackerleytng, agordeev, ajones, akpm, alex,
	andrii, aou, ast, baolu.lu, borntraeger, bp, bpf, catalin.marinas,
	chenhuacai, corbet, coxu, daniel, dave.hansen, david, derekmn,
	dev.jain, eddyz87, gerald.schaefer, gor, haoluo, hca, hpa, itazur,
	jackabt, jackmanb, jannh, jgg, jgross, jhubbard, jiayuan.chen,
	jmattson, joey.gouly, john.fastabend, jolsa, jthoughton, kalyazin,
	kas, kernel, kpsingh, kvm, kvmarm, lenb, linux-arm-kernel,
	linux-doc, linux-fsdevel, linux-kernel, linux-kselftest, linux-mm,
	linux-pm, linux-riscv, linux-s390, loongarch, lorenzo.stoakes,
	luto, maobibo, martin.lau, maz, mhocko, mingo, mlevitsk,
	nikita.kalyazin, oupton, palmer, patrick.roy, pavel, pbonzini,
	peterx, peterz, pfalcato, pjw, prsampat, rafael, riel, rppt,
	ryan.roberts, sdf, shijie, skhan, song, surenb, suzuki.poulose,
	svens, tabba, tglx, thuth, urezki, vannapurve, vbabka, will,
	willy, wu.fei9, x86, yang, yangyicong, yonghong.song, yosry,
	yu-cheng.yu, yuzenghui, zhengqi.arch
In-Reply-To: <20260506080753.14517-1-itazur@amazon.com>

On Wed, May 06, 2026 at 08:07:52AM +0000, Takahiro Itazuri wrote:
> Hi Lorenzo and Sean,
>
> Apologies for the delayed reply — Nikita is leaving Amazon, and I'm
> taking over this series going forward. Thanks for your patience.

Hey,

Thanks for letting us know! And thanks to Nikita for all his work, will
keep an eye out for the respin!

Cheers, Lorenzo

>
> On Tue, Apr 21, 2026 at 01:40:00PM +0000, Lorenzo Stoakes wrote:
> > Hm, given this touches a fair bit of mm, I wonder if we shouldn't try to do this
> > through the mm tree?
>
> On Tue, Apr 21, 2026 at 04:36:00PM +0000, Sean Christopherson wrote:
> > Yeah, when the time comes, the mm pieces definitely need to go through the mm
> > tree.  Ideally, I think this would be merged in two separate parts, with all mm
> > changes going through the mm tree, and then the KVM changes through the KVM tree
> > using a stable topic branch/tag from Andrew.
>
> Thanks for the guidance. The split makes sense to me; I'm planning to
> follow this approach with patches 1-6 (mm) going through the mm tree
> and patches 7-16 (KVM) through the KVM tree on top of a stable
> branch/tag from mm. I'll confirm the exact boundary and coordination
> details as I prepare the repost.
>
> On Tue, Apr 21, 2026 at 01:40:00PM +0000, Lorenzo Stoakes wrote:
> > In any case, we definitely need a rebase on something not-next :) if not mm then
> > Linus's tree at least maybe?
> >
> > I'm seeing a lot of conflicts against mm-unstable, it can't b4 shazam even patch
> > 1 and in Linus's tree it's failing at an mm patch (mm: introduce
> > AS_NO_DIRECT_MAP).
>
> I'll rebase onto v7.1-rc1 and resolve the conflicts as part of the split.
>
> Takahiro
>

^ permalink raw reply

* Re: [PATCH net-next 3/3] net/mlx5: Apply devlink default eswitch mode during init
From: Jiri Pirko @ 2026-05-26 16:23 UTC (permalink / raw)
  To: Mark Bloch
  Cc: Tariq Toukan, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Andrew Lunn, David S. Miller, Jonathan Corbet, Shuah Khan,
	Simon Horman, Saeed Mahameed, Leon Romanovsky,
	Borislav Petkov (AMD), Andrew Morton, Randy Dunlap,
	Thomas Gleixner, Petr Mladek, Peter Zijlstra (Intel), Tejun Heo,
	Vlastimil Babka, Feng Tang, Christian Brauner, Dave Hansen,
	Dapeng Mi, Kees Cook, Marco Elver, Li RongQing, Eric Biggers,
	Paul E. McKenney, linux-doc, linux-kernel, netdev, linux-rdma,
	Gal Pressman, Dragos Tatulea, Jiri Pirko, Shay Drori,
	Moshe Shemesh
In-Reply-To: <9aa7c295-35cb-428b-9031-13a2f507ae4b@nvidia.com>

Tue, May 26, 2026 at 05:03:57PM +0200, mbloch@nvidia.com wrote:
>
>
>On 26/05/2026 17:07, Jiri Pirko wrote:
>> Tue, May 26, 2026 at 11:44:46AM +0200, mbloch@nvidia.com wrote:
>>>
>>>
>>> On 26/05/2026 10:44, Jiri Pirko wrote:
>>>> Thu, May 21, 2026 at 09:24:34AM +0200, tariqt@nvidia.com wrote:
>>>>> From: Mark Bloch <mbloch@nvidia.com>
>>>>>
>>>>> Apply devlink default eswitch mode for mlx5 devices after successful
>>>>> device initialization while holding the devlink instance lock.
>>>>>
>>>>> At this point the devlink instance is registered and the mlx5 devlink
>>>>> operations are available, so the default eswitch mode can be applied to
>>>>> the matching PCI devlink handle.
>>>>>
>>>>> Signed-off-by: Mark Bloch <mbloch@nvidia.com>
>>>>> Reviewed-by: Shay Drori <shayd@nvidia.com>
>>>>> Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
>>>>> Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
>>>>> ---
>>>>> drivers/net/ethernet/mellanox/mlx5/core/main.c | 17 +++++++++++++++++
>>>>> 1 file changed, 17 insertions(+)
>>>>>
>>>>> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
>>>>> index 0c6e4efe38c8..4528097f3d84 100644
>>>>> --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
>>>>> +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
>>>>> @@ -1391,6 +1391,21 @@ static void mlx5_unload(struct mlx5_core_dev *dev)
>>>>> 	mlx5_free_bfreg(dev, &dev->priv.bfreg);
>>>>> }
>>>>>
>>>>> +static void mlx5_devl_apply_default_esw_mode(struct mlx5_core_dev *dev)
>>>>> +{
>>>>> +	struct devlink *devlink = priv_to_devlink(dev);
>>>>> +	int err;
>>>>> +
>>>>> +	if (!MLX5_ESWITCH_MANAGER(dev))
>>>>> +		return;
>>>>> +
>>>>> +	devl_assert_locked(devlink);
>>>>> +	err = devl_apply_default_esw_mode(devlink);
>>>>> +	if (err)
>>>>> +		mlx5_core_warn(dev, "Couldn't apply default eswitch mode, err %d\n",
>>>>> +			       err);
>>>>> +}
>>>>> +
>>>>> int mlx5_init_one_devl_locked(struct mlx5_core_dev *dev)
>>>>> {
>>>>> 	bool light_probe = mlx5_dev_is_lightweight(dev);
>>>>> @@ -1437,6 +1452,7 @@ int mlx5_init_one_devl_locked(struct mlx5_core_dev *dev)
>>>>> 		mlx5_core_err(dev, "mlx5_hwmon_dev_register failed with error code %d\n", err);
>>>>>
>>>>> 	mutex_unlock(&dev->intf_state_mutex);
>>>>> +	mlx5_devl_apply_default_esw_mode(dev);
>>>>
>>>> I wonder how we can make this work for all. I mean, other driver would
>>>> silently ignore this command like arg, right? Any idea how to make all
>>>> drivers follow the arg from very beginning?
>>>>
>>>
>>> I have a follow-up series that adds the call to all drivers which support
>>> setting eswitch mode. When going over the other drivers, what I found is
>>> that the right point to apply the default is driver specific, drivers
>>> I have patch for:
>>>
>>> 46e16c6d9836 net: Apply devlink esw mode defaults
>>> ab4f54102ba9 bnxt_en: Apply devlink default eswitch mode during init
>>> b48cce1607bb liquidio: Apply devlink default eswitch mode during init
>>> 4ea54b0fe04a ice: Apply devlink default eswitch mode during init
>>> b7faddaa1c90 octeontx2-af: Apply devlink default eswitch mode during init
>>> 74b0c22c47b9 octeontx2-pf: Apply devlink default eswitch mode during init
>>> 5000e4c3d768 nfp: Apply devlink default eswitch mode during init
>>> 97a218e95e41 netdevsim: Apply devlink default eswitch mode during init
>>>
>>> I don't think doing this generically from devlink is realistic. devlink
>>> doesn't really know when a given driver is ready to change eswitch mode.
>>> Some drivers need SR-IOV state, representor setup, or other init pieces to
>>> be ready first, and the locking is not identical across drivers either.
>> 
>> 
>> Low hanging fruit would be just to call ops->eswitch_mode_set at the end
>> of register. Multiple reasons:
>> 
>> 1) end of devl_register is exactly the point userspace is free to issue
>>    the eswitch mode set. Driver should be ready to handle it.
>> 2) all drivers would transparently get this functionality, without
>>    actually knowing this kernel command line arg ever existed, without
>>    odd wiring call of related exported function. I prefer that stongly.
>> 3) you should add a there warning for the case this arg is passed yet
>>    the driver does not implement eswitch_mode_set. User should
>>    get a feedback like this, not silent ignore.
>> 
>> The only loose end is see it the void return of devl_register().
>> Multiple ways to handle the possibly failed eswitch_mode_set(). I would
>> probably just go for pr_warn, seems to be the most correct.
>> 
>> Make sense?
>
>I see the point, but I don't think devl_register() (at least not the only place)
>is the right place.
>
>There is a small but important difference between userspace doing
>"devlink eswitch set" after register is done, and devlink core calling
>eswitch_mode_set() from inside the register flow.
>
>Some drivers call devlink_register() while holding the device lock.
>liquidio is one example. If devlink core calls ops->eswitch_mode_set() from
>there, we may start the full eswitch mode change while holding that lock.
>That mode change can create representors, register netdevs, take rtnl,
>allocate resources, etc. I don't think we want this to become an implicit
>side effect of devlink registration.

I believe your AI may untagle liquidio locking :)


>
>For mlx5, the placement after intf_state_mutex is also intentional:
>
>mutex_unlock(&dev->intf_state_mutex);
>mlx5_devl_apply_default_esw_mode(dev);
>
>We can't call it while holding intf_state_mutex because the mode set path
>takes it internally, and switchdev mode may also create IB representors.
>
>Also, devl_register() only covers the first registration. The mlx5 call in
>mlx5_load_one_devl_locked() is for reload/fw reset recovery kind of flows.
>In those flows devlink is already registered, so devl_register() is not
>called again, but the driver state was rebuilt and we may need to apply the
>default again.

Call it from reload too, right?


>
>Same for reload, fw reset and pci recovery in general. If the driver tears
>down and rebuilds eswitch related state, the place to apply the default is
>in that driver's reinit flow, not in devl_register().
>
>When I went over the other drivers, the right place was not always the same
>as devlink registration. I'm not an expert in any of them, so I hope I got
>the details right, but for example octeontx2 AF needs sr-iov and the
>representor switch state to be initialized first. nfp can do it after
>app/vNIC init while the devlink lock is already held. liquidio should do it
>only after dropping the PCI device lock.

Idk, perhaps do it from devlink_post_register_work of some kind? That
would allow you to have the same locking ordering as a userspace call.

>
>Mark
>
>> 
>> 
>>>
>>> Also, since this knob is only about eswitch mode, I don't think we need to
>>> touch every devlink driver. Drivers that don't implement eswitch_mode_set()
>>> would just ignore it anyway. The follow-up only wires the default into
>>> drivers that actually support changing eswitch mode.
>>>
>>> Mark
>>>
>>>>
>>>>> 	return 0;
>>>>>
>>>>> err_register:
>>>>> @@ -1538,6 +1554,7 @@ int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery)
>>>>> 		goto err_attach;
>>>>>
>>>>> 	mutex_unlock(&dev->intf_state_mutex);
>>>>> +	mlx5_devl_apply_default_esw_mode(dev);
>>>>> 	return 0;
>>>>>
>>>>> err_attach:
>>>>> -- 
>>>>> 2.44.0
>>>>>
>>>
>

^ permalink raw reply

* [PATCH net-next 10/10] docs: net: fix minor issues with segmentation offloads
From: Jakub Kicinski @ 2026-05-26 16:01 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
	vladimir.oltean, willemb, sdf.kernel, ecree.xilinx,
	jesse.brandeburg, linux-doc, Jakub Kicinski
In-Reply-To: <20260526160151.2793354-1-kuba@kernel.org>

Update the segmentation offload documentation to match current GSO types:

- clarify csum_start for encapsulated TSO
- document TCP AccECN GSO and NETIF_F_GSO_ACCECN
- distinguish legacy UFO from UDP L4 GSO
- add ESP and fraglist GSO entries

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 .../networking/segmentation-offloads.rst      | 37 ++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/Documentation/networking/segmentation-offloads.rst b/Documentation/networking/segmentation-offloads.rst
index 72f69b22b28c..25a8b7eca847 100644
--- a/Documentation/networking/segmentation-offloads.rst
+++ b/Documentation/networking/segmentation-offloads.rst
@@ -14,10 +14,13 @@ to take advantage of segmentation offload capabilities of various NICs.
 The following technologies are described:
  * TCP Segmentation Offload - TSO
  * UDP Fragmentation Offload - UFO
+ * UDP Segmentation Offload - USO
  * IPIP, SIT, GRE, and UDP Tunnel Offloads
  * Generic Segmentation Offload - GSO
  * Generic Receive Offload - GRO
  * Partial Generic Segmentation Offload - GSO_PARTIAL
+ * ESP Segmentation Offload
+ * Fraglist Generic Segmentation Offload - GSO_FRAGLIST
  * SCTP acceleration with GSO - GSO_BY_FRAGS
 
 
@@ -38,7 +41,8 @@ In order to support TCP segmentation offload it is necessary to populate
 the network and transport header offsets of the skbuff so that the device
 drivers will be able determine the offsets of the IP or IPv6 header and the
 TCP header.  In addition as CHECKSUM_PARTIAL is required csum_start should
-also point to the TCP header of the packet.
+also point to the TCP header of the packet, or to the inner transport header
+for encapsulated TSO.
 
 For IPv4 segmentation we support one of two types in terms of the IP ID.
 The default behavior is to increment the IP ID with every segment.  If the
@@ -57,6 +61,10 @@ DF bit is not set on the outer header, in which case the device driver must
 guarantee that the IP ID field is incremented in the outer header with every
 segment.
 
+SKB_GSO_TCP_ACCECN is a modifier used with TCP segmentation offload for
+AccECN packets where the CWR bit must not be cleared during segmentation.
+Devices advertise support for this using NETIF_F_GSO_ACCECN.
+
 
 UDP Fragmentation Offload
 =========================
@@ -71,6 +79,16 @@ still receive them from tuntap and similar devices. Offload of UDP-based
 tunnel protocols is still supported.
 
 
+UDP Segmentation Offload
+========================
+
+UDP segmentation offload allows a device to segment a large UDP packet into
+multiple UDP datagrams.  Unlike UFO, these are not IP fragments.  The payload
+size of each datagram is specified in skb_shinfo()->gso_size and the GSO type
+is SKB_GSO_UDP_L4.  Devices advertise support for this using
+NETIF_F_GSO_UDP_L4.
+
+
 IPIP, SIT, GRE, UDP Tunnel, and Remote Checksum Offloads
 ========================================================
 
@@ -154,6 +172,23 @@ that the IPv4 ID field is incremented in the case that a given header does
 not have the DF bit set.
 
 
+ESP Segmentation Offload
+========================
+
+ESP segmentation offload uses SKB_GSO_ESP to mark packets that require
+IPsec ESP segmentation.  This type is set by the XFRM output path for GSO
+packets handled by ESP hardware offload.
+
+
+Fraglist Generic Segmentation Offload
+=====================================
+
+Fraglist GSO uses SKB_GSO_FRAGLIST to mark packets whose segments are
+already arranged as a list of skbs.  The segmentation path splits the skb
+based on that list rather than by creating segments of skb_shinfo()->gso_size
+bytes from the linear and page-fragment data.
+
+
 SCTP acceleration with GSO
 ===========================
 
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next 09/10] docs: net: render the checksum comment in checksum-offloads.rst
From: Jakub Kicinski @ 2026-05-26 16:01 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
	vladimir.oltean, willemb, sdf.kernel, ecree.xilinx,
	jesse.brandeburg, linux-doc, Jakub Kicinski
In-Reply-To: <20260526160151.2793354-1-kuba@kernel.org>

checksum-offloads.rst seems like a better place to render
the checksum comment than skbuff.rst.

Remove the stale references to sections in that comment
(it no longer has A, B, C, D, E sections).

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 Documentation/networking/checksum-offloads.rst | 18 ++++++++++--------
 Documentation/networking/skbuff.rst            |  6 ------
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/Documentation/networking/checksum-offloads.rst b/Documentation/networking/checksum-offloads.rst
index d838fe5c1606..d4ded890011b 100644
--- a/Documentation/networking/checksum-offloads.rst
+++ b/Documentation/networking/checksum-offloads.rst
@@ -25,10 +25,8 @@ take advantage of checksum offload capabilities of various NICs.
 TX Checksum Offload
 ===================
 
-The interface for offloading a transmit checksum to a device is explained in
-detail in comments near the top of include/linux/skbuff.h.
-
-In brief, it allows to request the device fill in a single ones-complement
+In brief, Tx checksum offload allows to request the device fill in a single
+ones-complement
 checksum defined by the sk_buff fields skb->csum_start and skb->csum_offset.
 The device should compute the 16-bit ones-complement checksum (i.e. the
 'IP-style' checksum) from csum_start to the end of the packet, and fill in the
@@ -47,8 +45,7 @@ mechanism such as LCO or RCO.
 SCTP CRC32c can also be offloaded using this interface, by means of filling
 skb->csum_start and skb->csum_offset as described above, setting
 skb->csum_not_inet, and advertising NETIF_F_SCTP_CRC. Drivers must not treat
-ordinary IP checksum offload as SCTP CRC32c support. See the skbuff.h comment
-(section 'D') for more details.
+ordinary IP checksum offload as SCTP CRC32c support.
 
 No offloading of the IP header checksum is performed; it is always done in
 software.  This is OK because when we build the IP header, we obviously have it
@@ -56,8 +53,7 @@ in cache, so summing it isn't expensive.  It's also rather short.
 
 The requirements for GSO are more complicated, because when segmenting an
 encapsulated packet both the inner and outer checksums may need to be edited or
-recomputed for each resulting segment.  See the skbuff.h comment (section 'E')
-for more details.
+recomputed for each resulting segment.
 
 A driver declares its offload capabilities in netdev->hw_features; see
 Documentation/networking/netdev-features.rst for more. NETIF_F_IP_CSUM and
@@ -154,3 +150,9 @@ or left at ``CHECKSUM_NONE``. Drivers **must not discard** packets with
 bad TCP/UDP checksum and must not configure the device to drop them.
 Checksum validation is relatively inexpensive and having bad packets reflected
 in SNMP counters is crucial for network monitoring.
+
+skb checksum documentation
+==========================
+
+.. kernel-doc:: include/linux/skbuff.h
+   :doc: skb checksums
diff --git a/Documentation/networking/skbuff.rst b/Documentation/networking/skbuff.rst
index 5b74275a73a3..94681523e345 100644
--- a/Documentation/networking/skbuff.rst
+++ b/Documentation/networking/skbuff.rst
@@ -29,9 +29,3 @@ dataref and headerless skbs
 
 .. kernel-doc:: include/linux/skbuff.h
    :doc: dataref and headerless skbs
-
-Checksum information
---------------------
-
-.. kernel-doc:: include/linux/skbuff.h
-   :doc: skb checksums
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next 08/10] docs: net: add Rx notes to the checksum guide
From: Jakub Kicinski @ 2026-05-26 16:01 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
	vladimir.oltean, willemb, sdf.kernel, ecree.xilinx,
	jesse.brandeburg, linux-doc, Jakub Kicinski
In-Reply-To: <20260526160151.2793354-1-kuba@kernel.org>

The Rx checksum processing gives people pause. The two main questions
in my experience are:
 - what to do with bad IPv4 checksum; and
 - what to do with packets with bad checksum.

Folks often feel the urge to drop the latter, to "avoid overloading
the host".

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 Documentation/networking/checksum-offloads.rst | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/Documentation/networking/checksum-offloads.rst b/Documentation/networking/checksum-offloads.rst
index 907aed9f3a3b..d838fe5c1606 100644
--- a/Documentation/networking/checksum-offloads.rst
+++ b/Documentation/networking/checksum-offloads.rst
@@ -19,7 +19,6 @@ take advantage of checksum offload capabilities of various NICs.
 
 Things that should be documented here but aren't yet:
 
-* RX Checksum Offload
 * CHECKSUM_UNNECESSARY conversion
 
 
@@ -139,3 +138,19 @@ In Linux, RCO is implemented individually in each encapsulation protocol, and
 most tunnel types have flags controlling its use. For instance, VXLAN has the
 configuration flag VXLAN_F_REMCSUM_TX to indicate that RCO should be used when
 transmitting.
+
+
+RX Checksum Offload
+===================
+
+RX checksum offload is controlled via NETIF_F_RXCSUM. When disabled the driver
+must not set skb->ip_summed on ingress packets. As mentioned, IPv4 checksum
+is not offloaded, the RXCSUM feature controls the offload of verification of
+transport layer checksums.
+
+Note that packets with bad TCP/UDP checksums must still be passed
+to the stack. skb->ip_summed of such packets can be set to ``CHECKSUM_COMPLETE``
+or left at ``CHECKSUM_NONE``. Drivers **must not discard** packets with
+bad TCP/UDP checksum and must not configure the device to drop them.
+Checksum validation is relatively inexpensive and having bad packets reflected
+in SNMP counters is crucial for network monitoring.
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next 07/10] docs: net: fix minor issues with checksum offloads
From: Jakub Kicinski @ 2026-05-26 16:01 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
	vladimir.oltean, willemb, sdf.kernel, ecree.xilinx,
	jesse.brandeburg, linux-doc, Jakub Kicinski
In-Reply-To: <20260526160151.2793354-1-kuba@kernel.org>

Update the checksum offload documentation to match current code:

- SCTP CRC32c offload requires NETIF_F_SCTP_CRC, not ordinary IP
  checksum offload
- NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM are restricted legacy
  features; new devices should use NETIF_F_HW_CSUM
- GRE LCO is handled by the shared gre_build_header() helper used by
  both IPv4 and IPv6 GRE
- VXLAN_F_REMCSUM_TX is a VXLAN configuration flag, not a field of
  struct vxlan_rdst

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 .../networking/checksum-offloads.rst          | 36 +++++++++----------
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/Documentation/networking/checksum-offloads.rst b/Documentation/networking/checksum-offloads.rst
index 69b23cf6879e..907aed9f3a3b 100644
--- a/Documentation/networking/checksum-offloads.rst
+++ b/Documentation/networking/checksum-offloads.rst
@@ -45,9 +45,11 @@ encapsulation is used, the packet may have multiple checksum fields in
 different header layers, and the rest will have to be handled by another
 mechanism such as LCO or RCO.
 
-CRC32c can also be offloaded using this interface, by means of filling
-skb->csum_start and skb->csum_offset as described above, and setting
-skb->csum_not_inet: see skbuff.h comment (section 'D') for more details.
+SCTP CRC32c can also be offloaded using this interface, by means of filling
+skb->csum_start and skb->csum_offset as described above, setting
+skb->csum_not_inet, and advertising NETIF_F_SCTP_CRC. Drivers must not treat
+ordinary IP checksum offload as SCTP CRC32c support. See the skbuff.h comment
+(section 'D') for more details.
 
 No offloading of the IP header checksum is performed; it is always done in
 software.  This is OK because when we build the IP header, we obviously have it
@@ -59,14 +61,12 @@ recomputed for each resulting segment.  See the skbuff.h comment (section 'E')
 for more details.
 
 A driver declares its offload capabilities in netdev->hw_features; see
-Documentation/networking/netdev-features.rst for more.  Note that a device
-which only advertises NETIF_F_IP[V6]_CSUM must still obey the csum_start and
-csum_offset given in the SKB; if it tries to deduce these itself in hardware
-(as some NICs do) the driver should check that the values in the SKB match
-those which the hardware will deduce, and if not, fall back to checksumming in
-software instead (with skb_csum_hwoffload_help() or one of the
-skb_checksum_help() / skb_crc32c_csum_help functions, as mentioned in
-include/linux/skbuff.h).
+Documentation/networking/netdev-features.rst for more. NETIF_F_IP_CSUM and
+NETIF_F_IPV6_CSUM are restricted legacy features and are being deprecated in
+favor of NETIF_F_HW_CSUM. New devices should use NETIF_F_HW_CSUM to advertise
+generic checksum offload. The skb_csum_hwoffload_help() helper can resolve
+CHECKSUM_PARTIAL according to the device's advertised checksum capabilities,
+falling back to software when needed.
 
 The stack should, for the most part, assume that checksum offload is supported
 by the underlying device.  The only place that should check is
@@ -108,11 +108,9 @@ LCO is performed by the stack when constructing an outer UDP header for an
 encapsulation such as VXLAN or GENEVE, in udp_set_csum().  Similarly for the
 IPv6 equivalents, in udp6_set_csum().
 
-It is also performed when constructing an IPv4 GRE header, in
-net/ipv4/ip_gre.c:build_header().  It is *not* currently performed when
-constructing an IPv6 GRE header; the GRE checksum is computed over the whole
-packet in net/ipv6/ip6_gre.c:ip6gre_xmit2(), but it should be possible to use
-LCO here as IPv6 GRE still uses an IP-style checksum.
+It is also performed when constructing GRE headers with the shared
+gre_build_header() helper in include/net/gre.h, which is used by both IPv4 and
+IPv6 GRE.
 
 All of the LCO implementations use a helper function lco_csum(), in
 include/linux/skbuff.h.
@@ -138,6 +136,6 @@ For this reason, it is disabled by default.
 * https://tools.ietf.org/html/draft-herbert-vxlan-rco-00
 
 In Linux, RCO is implemented individually in each encapsulation protocol, and
-most tunnel types have flags controlling its use.  For instance, VXLAN has the
-flag VXLAN_F_REMCSUM_TX (per struct vxlan_rdst) to indicate that RCO should be
-used when transmitting to a given remote destination.
+most tunnel types have flags controlling its use. For instance, VXLAN has the
+configuration flag VXLAN_F_REMCSUM_TX to indicate that RCO should be used when
+transmitting.
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next 06/10] docs: net: refresh netdev feature guidance
From: Jakub Kicinski @ 2026-05-26 16:01 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
	vladimir.oltean, willemb, sdf.kernel, ecree.xilinx,
	jesse.brandeburg, linux-doc, Jakub Kicinski
In-Reply-To: <20260526160151.2793354-1-kuba@kernel.org>

Update netdev feature documentation for current locking rules and
feature semantics. Clarify hw_features updates and netdev_update_features()
locking, keep the NETIF_F_NEVER_CHANGE rule with the VLAN challenged
exception, fix the HSR duplication wording, and document netdev->netmem_tx
as a device flag rather than a feature bit.

Split the list of basic feature sets from the "extra" ones like
vlan_features. A bunch of the newer fields weren't documented and
having them all together would be confusing.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 Documentation/networking/netdev-features.rst | 60 +++++++++++++-------
 1 file changed, 39 insertions(+), 21 deletions(-)

diff --git a/Documentation/networking/netdev-features.rst b/Documentation/networking/netdev-features.rst
index 02bd7536fc0c..6293d47e5b09 100644
--- a/Documentation/networking/netdev-features.rst
+++ b/Documentation/networking/netdev-features.rst
@@ -18,29 +18,38 @@ that relieve an OS of various tasks like generating and checking checksums,
 splitting packets, classifying them.  Those capabilities and their state
 are commonly referred to as netdev features in Linux kernel world.
 
-There are currently three sets of features relevant to the driver, and
-one used internally by network core:
+There are currently three main sets of features on each netdevice,
+first and second are initialized by the driver:
 
  1. netdev->hw_features set contains features whose state may possibly
     be changed (enabled or disabled) for a particular device by user's
-    request.  This set should be initialized in ndo_init callback and not
-    changed later.
+    request.  Drivers normally initialize this set before registration or
+    in the ndo_init callback. Changes after registration should be made
+    very carefully as other parts of the code may assume hw_features are
+    static. At the very least changes must be made under rtnl_lock and
+    the netdev instance lock, and followed by netdev_update_features().
 
  2. netdev->features set contains features which are currently enabled
     for a device.  This should be changed only by network core or in
     error paths of ndo_set_features callback.
 
- 3. netdev->vlan_features set contains features whose state is inherited
-    by child VLAN devices (limits netdev->features set).  This is currently
-    used for all VLAN devices whether tags are stripped or inserted in
-    hardware or software.
-
- 4. netdev->wanted_features set contains feature set requested by user.
+ 3. netdev->wanted_features set contains feature set requested by user.
     This set is filtered by ndo_fix_features callback whenever it or
     some device-specific conditions change. This set is internal to
     networking core and should not be referenced in drivers.
 
+On top of those three main sets, each netdev has:
 
+ 1. Sets which control features inherited by child devices (VLAN, MPLS,
+    hw_enc for L3/L4 tunnels). These sets allow the driver to limit which
+    netdev->features are propagated, in case HW cannot perform the offloads
+    with the extra headers present.
+
+ 2. netdev->mangleid_features, TSO features which are supported only when
+    IP ID field can be mangled (constant instead of incrementing) during TSO.
+
+ 3. netdev->gso_partial_features, additional TSO features which HW can
+    support via NETIF_F_GSO_PARTIAL.
 
 Part II: Controlling enabled features
 =====================================
@@ -62,11 +71,15 @@ ndo_*_features callbacks are called with rtnl_lock held. Missing callbacks
 are treated as always returning success.
 
 A driver that wants to trigger recalculation must do so by calling
-netdev_update_features() while holding rtnl_lock. This should not be done
-from ndo_*_features callbacks. netdev->features should not be modified by
-driver except by means of ndo_fix_features callback.
-
+netdev_update_features() while holding rtnl_lock. If the device uses the
+netdev instance lock, that lock must be held as well. This should not be
+done from ndo_*_features callbacks. netdev->features should not be modified
+by driver except by means of ndo_fix_features callback.
 
+ndo_features_check is called for each skb before that skb is passed to
+ndo_start_xmit. Driver may perform any non-trivial checks (e.g. exact
+header geometry / length) and withdraw features like HW_CSUM or TSO,
+requesting the networking stack to fall back to the software implementation.
 
 Part III: Implementation hints
 ==============================
@@ -83,8 +96,9 @@ stateless).  It can be called multiple times between successive
 ndo_set_features calls.
 
 Callback must not alter features contained in NETIF_F_SOFT_FEATURES or
-NETIF_F_NEVER_CHANGE sets. The exception is NETIF_F_VLAN_CHALLENGED but
-care must be taken as the change won't affect already configured VLANs.
+NETIF_F_NEVER_CHANGE, except that NETIF_F_VLAN_CHALLENGED may be changed.
+Care must be taken as changes to NETIF_F_VLAN_CHALLENGED won't affect already
+configured VLANs.
 
  * ndo_set_features:
 
@@ -186,10 +200,14 @@ Redundancy) frames from one port to another in hardware.
 * hsr-dup-offload
 
 This should be set for devices which duplicate outgoing HSR (High-availability
-Seamless Redundancy) or PRP (Parallel Redundancy Protocol) tags automatically
-frames in hardware.
+Seamless Redundancy) or PRP (Parallel Redundancy Protocol) frames
+automatically in hardware.
 
-* netmem-tx
+Part V: Related device flags
+============================
 
-This should be set for devices which support netmem TX. See
-Documentation/networking/netmem.rst
+* netdev->netmem_tx
+
+This is not a netdev feature bit. Drivers support netmem TX by setting
+netdev->netmem_tx to one of the values in enum netmem_tx_mode.
+See Documentation/networking/netmem.rst.
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next 05/10] docs: net: fix minor issues with the NAPI guide
From: Jakub Kicinski @ 2026-05-26 16:01 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
	vladimir.oltean, willemb, sdf.kernel, ecree.xilinx,
	jesse.brandeburg, linux-doc, Jakub Kicinski
In-Reply-To: <20260526160151.2793354-1-kuba@kernel.org>

Update the NAPI documentation to match current API behavior:

- repeated napi_disable() calls hang waiting for ownership, rather
  than deadlock
- NAPI IDs are exposed through SO_INCOMING_NAPI_ID and netdev Netlink
- epoll uses the maxevents parameter spelling
- add that drivers holding the netdev instance lock may need _locked()
  variants

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 Documentation/networking/napi.rst | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/Documentation/networking/napi.rst b/Documentation/networking/napi.rst
index 4e008efebb35..c719924f36ce 100644
--- a/Documentation/networking/napi.rst
+++ b/Documentation/networking/napi.rst
@@ -49,7 +49,11 @@ instance to be released.
 The control APIs are not idempotent. Control API calls are safe against
 concurrent use of datapath APIs but an incorrect sequence of control API
 calls may result in crashes, deadlocks, or race conditions. For example,
-calling napi_disable() multiple times in a row will deadlock.
+calling napi_disable() multiple times in a row will hang waiting for
+ownership of the NAPI instance to be released.
+
+Drivers using the netdev instance lock may need to use the ``_locked()``
+variants of the control APIs when that lock is already held.
 
 Datapath API
 ------------
@@ -190,7 +194,8 @@ User API
 ========
 
 User interactions with NAPI depend on NAPI instance ID. The instance IDs
-are only visible to the user thru the ``SO_INCOMING_NAPI_ID`` socket option.
+are visible to the user through the ``SO_INCOMING_NAPI_ID`` socket option
+and the netdev Netlink API.
 
 Users can query NAPI IDs for a device or device queue using netlink. This can
 be done programmatically in a user application or by using a script included in
@@ -371,7 +376,7 @@ efficiency.
      the application has stalled. This value should be chosen so that it covers
      the amount of time the user application needs to process data from its
      call to epoll_wait, noting that applications can control how much data
-     they retrieve by setting ``max_events`` when calling epoll_wait.
+     they retrieve by setting ``maxevents`` when calling epoll_wait.
 
   2. The sysfs parameter or per-NAPI config parameters ``gro_flush_timeout``
      and ``napi_defer_hard_irqs`` can be set to low values. They will be used
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next 04/10] docs: net: update devmem code examples
From: Jakub Kicinski @ 2026-05-26 16:01 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
	vladimir.oltean, willemb, sdf.kernel, ecree.xilinx,
	jesse.brandeburg, linux-doc, Jakub Kicinski
In-Reply-To: <20260526160151.2793354-1-kuba@kernel.org>

Update the code examples
 - update the YNL sample with the latest(?) APIs
 - struct dmabuf_tx_cmsg does not exist, use __u32 directly

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 Documentation/networking/devmem.rst | 27 +++++++++++----------------
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/Documentation/networking/devmem.rst b/Documentation/networking/devmem.rst
index a6cd7236bfbd..6a3f3c2ac19c 100644
--- a/Documentation/networking/devmem.rst
+++ b/Documentation/networking/devmem.rst
@@ -103,24 +103,22 @@ The user must bind a dmabuf to any number of RX queues on a given NIC using
 the netlink API::
 
 	/* Bind dmabuf to NIC RX queue 15 */
-	struct netdev_queue *queues;
-	queues = malloc(sizeof(*queues) * 1);
+	struct netdev_queue_id *queues;
 
-	queues[0]._present.type = 1;
-	queues[0]._present.idx = 1;
-	queues[0].type = NETDEV_RX_QUEUE_TYPE_RX;
-	queues[0].idx = 15;
+	queues = netdev_queue_id_alloc(1);
+	netdev_queue_id_set_type(&queues[0], NETDEV_QUEUE_TYPE_RX);
+	netdev_queue_id_set_id(&queues[0], 15);
 
 	*ys = ynl_sock_create(&ynl_netdev_family, &yerr);
 
 	req = netdev_bind_rx_req_alloc();
 	netdev_bind_rx_req_set_ifindex(req, 1 /* ifindex */);
-	netdev_bind_rx_req_set_dmabuf_fd(req, dmabuf_fd);
-	__netdev_bind_rx_req_set_queues(req, queues, n_queue_index);
+	netdev_bind_rx_req_set_fd(req, dmabuf_fd);
+	__netdev_bind_rx_req_set_queues(req, queues, 1);
 
 	rsp = netdev_bind_rx(*ys, req);
 
-	dmabuf_id = rsp->dmabuf_id;
+	dmabuf_id = rsp->id;
 
 
 The netlink API returns a dmabuf_id: a unique ID that refers to this dmabuf
@@ -302,13 +300,12 @@ The user should create a msghdr where,
 * iov_base is set to the offset into the dmabuf to start sending from
 * iov_len is set to the number of bytes to be sent from the dmabuf
 
-The user passes the dma-buf id to send from via the dmabuf_tx_cmsg.dmabuf_id.
+The user passes the dma-buf id to send from as a u32 cmsg payload.
 
 The example below sends 1024 bytes from offset 100 into the dmabuf, and 2048
 from offset 2000 into the dmabuf. The dmabuf to send from is tx_dmabuf_id::
 
-       char ctrl_data[CMSG_SPACE(sizeof(struct dmabuf_tx_cmsg))];
-       struct dmabuf_tx_cmsg ddmabuf;
+       char ctrl_data[CMSG_SPACE(sizeof(__u32))];
        struct msghdr msg = {};
        struct cmsghdr *cmsg;
        struct iovec iov[2];
@@ -327,11 +324,9 @@ The example below sends 1024 bytes from offset 100 into the dmabuf, and 2048
        cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_DEVMEM_DMABUF;
-       cmsg->cmsg_len = CMSG_LEN(sizeof(struct dmabuf_tx_cmsg));
+       cmsg->cmsg_len = CMSG_LEN(sizeof(__u32));
 
-       ddmabuf.dmabuf_id = tx_dmabuf_id;
-
-       *((struct dmabuf_tx_cmsg *)CMSG_DATA(cmsg)) = ddmabuf;
+       *((__u32 *)CMSG_DATA(cmsg)) = tx_dmabuf_id;
 
        sendmsg(socket_fd, &msg, MSG_ZEROCOPY);
 
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next 03/10] docs: net: statistics: fix kernel-internal stats list
From: Jakub Kicinski @ 2026-05-26 16:01 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
	vladimir.oltean, willemb, sdf.kernel, ecree.xilinx,
	jesse.brandeburg, linux-doc, Jakub Kicinski
In-Reply-To: <20260526160151.2793354-1-kuba@kernel.org>

Update the kernel-internal ethtool stats list to match current code:

- spell the entries as "struct ethtool_*_stats", not as functions
- list the full set of structures, not only pause and fec
- mention that fields are pre-initialized to ETHTOOL_STAT_NOT_SET by
  ethtool_stats_init() and drivers should leave unsupported fields at
  that value rather than zeroing them

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 Documentation/networking/statistics.rst | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/Documentation/networking/statistics.rst b/Documentation/networking/statistics.rst
index 66b0ef941457..824ebc549383 100644
--- a/Documentation/networking/statistics.rst
+++ b/Documentation/networking/statistics.rst
@@ -231,8 +231,19 @@ Kernel-internal data structures
 -------------------------------
 
 The following structures are internal to the kernel, their members are
-translated to netlink attributes when dumped. Drivers must not overwrite
-the statistics they don't report with 0.
+translated to netlink attributes when dumped. Fields are pre-initialized
+to ``ETHTOOL_STAT_NOT_SET`` (by ``ethtool_stats_init()``); drivers must
+leave fields they do not report at that value rather than overwriting
+them with 0.
 
-- ethtool_pause_stats()
-- ethtool_fec_stats()
+- ``struct ethtool_eth_ctrl_stats``
+- ``struct ethtool_eth_mac_stats``
+- ``struct ethtool_eth_phy_stats``
+- ``struct ethtool_fec_hist``
+- ``struct ethtool_fec_stats``
+- ``struct ethtool_link_ext_stats``
+- ``struct ethtool_mm_stats``
+- ``struct ethtool_pause_stats``
+- ``struct ethtool_phy_stats``
+- ``struct ethtool_rmon_stats``
+- ``struct ethtool_ts_stats``
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next 02/10] docs: net: fix minor issues with driver guide
From: Jakub Kicinski @ 2026-05-26 16:01 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
	vladimir.oltean, willemb, sdf.kernel, ecree.xilinx,
	jesse.brandeburg, linux-doc, Jakub Kicinski
In-Reply-To: <20260526160151.2793354-1-kuba@kernel.org>

Update the driver documentation TX queue example to match current APIs:

- use the ring-local tx_ring_mask field in drv_tx_avail()
- stop the selected netdev_queue with netif_tx_stop_queue() instead of
  stopping queue 0 with netif_stop_queue()

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 Documentation/networking/driver.rst | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/networking/driver.rst b/Documentation/networking/driver.rst
index 4f5dfa9c022e..195a916dc0de 100644
--- a/Documentation/networking/driver.rst
+++ b/Documentation/networking/driver.rst
@@ -51,7 +51,7 @@ Instead it must maintain the queue properly.  For example,
 	{
 		u32 used = READ_ONCE(dr->prod) - READ_ONCE(dr->cons);
 
-		return dr->tx_ring_size - (used & bp->tx_ring_mask);
+		return dr->tx_ring_size - (used & dr->tx_ring_mask);
 	}
 
 	static netdev_tx_t drv_hard_start_xmit(struct sk_buff *skb,
@@ -69,7 +69,7 @@ Instead it must maintain the queue properly.  For example,
 		//...
 		/* This should be a very rare race - log it. */
 		if (drv_tx_avail(dr) <= skb_shinfo(skb)->nr_frags + 1) {
-			netif_stop_queue(dev);
+			netif_tx_stop_queue(txq);
 			netdev_warn(dev, "Tx Ring full when queue awake!\n");
 			return NETDEV_TX_BUSY;
 		}
@@ -103,6 +103,9 @@ Lockless queue stop / wake helper macros
 .. kernel-doc:: include/net/netdev_queues.h
    :doc: Lockless queue stopping / waking helpers.
 
+The standard macros like netif_txq_maybe_stop(), netif_txq_try_stop() etc.
+are well tested, prefer them over local synchronization schemes.
+
 No exclusive ownership
 ----------------------
 
-- 
2.54.0


^ permalink raw reply related

* [PATCH net-next 01/10] docs: net: netdevices: small fixes and clarifications
From: Jakub Kicinski @ 2026-05-26 16:01 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
	vladimir.oltean, willemb, sdf.kernel, ecree.xilinx,
	jesse.brandeburg, linux-doc, Jakub Kicinski
In-Reply-To: <20260526160151.2793354-1-kuba@kernel.org>

A handful of unrelated nits:

 - free_netdevice() does not exist; replace two stray references
   with free_netdev().
 - The simple-driver probe example fell through into err_undo after
   register_netdev() success; add return 0 for clarity.
 - Clarify the netdev_priv() paragraph: "(netdev_priv())" was easy
   to misread as the thing that needs explicit freeing; spell out
   that it refers to extra pointers stored in the device private
   struct.
 - ndo_setup_tc synchronization note: TC_SETUP_BLOCK / TC_SETUP_FT
   actually run under block->cb_lock, not "NFT locks", and rtnl_lock
   may or may not be held depending on path.
 - ->lltx guidance reads as very outdated, it's not really deprecated.
   I suspect people may have been trying to use it for HW drivers
   in the past but I can't think of such a case in the last decade.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 Documentation/networking/netdevices.rst | 31 ++++++++++++++-----------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/Documentation/networking/netdevices.rst b/Documentation/networking/netdevices.rst
index 93e06e8d51a9..60492d4df2ee 100644
--- a/Documentation/networking/netdevices.rst
+++ b/Documentation/networking/netdevices.rst
@@ -21,13 +21,14 @@ by free_netdev(). This is required to handle the pathological case cleanly
 alloc_netdev_mqs() / alloc_netdev() reserve extra space for driver
 private data which gets freed when the network device is freed. If
 separately allocated data is attached to the network device
-(netdev_priv()) then it is up to the module exit handler to free that.
+(extra pointers stored in the device private struct) then it is up
+to the module exit handler to free that.
 
 There are two groups of APIs for registering struct net_device.
 First group can be used in normal contexts where ``rtnl_lock`` is not already
 held: register_netdev(), unregister_netdev().
 Second group can be used when ``rtnl_lock`` is already held:
-register_netdevice(), unregister_netdevice(), free_netdevice().
+register_netdevice(), unregister_netdevice(), free_netdev().
 
 Simple drivers
 --------------
@@ -58,6 +59,7 @@ In that case the struct net_device registration is done using
       goto err_undo;
 
     /* net_device is visible to the user! */
+    return 0;
 
   err_undo:
     /* ... undo the device setup ... */
@@ -73,7 +75,7 @@ In that case the struct net_device registration is done using
 
 Note that after calling register_netdev() the device is visible in the system.
 Users can open it and start sending / receiving traffic immediately,
-or run any other callback, so all initialization must be done prior to
+or run any other callback, so all initialization must be **complete** prior to
 registration.
 
 unregister_netdev() closes the device and waits for all users to be done
@@ -157,7 +159,7 @@ register_netdevice() fails. The callback may be invoked with or without
 There is no explicit constructor callback, driver "constructs" the private
 netdev state after allocating it and before registration.
 
-Setting struct net_device.needs_free_netdev makes core call free_netdevice()
+Setting struct net_device.needs_free_netdev makes core call free_netdev()
 automatically after unregister_netdevice() when all references to the device
 are gone. It only takes effect after a successful call to register_netdevice()
 so if register_netdevice() fails driver is responsible for calling
@@ -256,7 +258,7 @@ struct net_device synchronization rules
 	lock if the driver implements queue management or shaper API.
 	Context: process
 
-ndo_get_stats:
+ndo_get_stats / ndo_get_stats64:
 	Synchronization: RCU (can be called concurrently with the stats
 	update path).
 	Context: atomic (can't sleep under RCU)
@@ -264,12 +266,9 @@ struct net_device synchronization rules
 ndo_start_xmit:
 	Synchronization: __netif_tx_lock spinlock.
 
-	When the driver sets dev->lltx this will be
-	called without holding netif_tx_lock. In this case the driver
-	has to lock by itself when needed.
-	The locking there should also properly protect against
-	set_rx_mode. WARNING: use of dev->lltx is deprecated.
-	Don't use it for new drivers.
+	When the driver sets dev->lltx this will be called without holding
+	netif_tx_lock. dev->lltx is meant for software drivers only, since
+	they often have no per-queue state.
 
 	Context: Process with BHs disabled or BH (timer),
 		 will be called with interrupts disabled by netconsole.
@@ -304,11 +303,15 @@ struct net_device synchronization rules
 	lock if the driver implements queue management or shaper API.
 
 ndo_setup_tc:
-	``TC_SETUP_BLOCK`` and ``TC_SETUP_FT`` are running under NFT locks
-	(i.e. no ``rtnl_lock`` and no device instance lock). The rest of
-	``tc_setup_type`` types run under netdev instance lock if the driver
+	Locking depends on ``tc_setup_type``. For most types the callback
+	is invoked under ``rtnl_lock`` and netdev instance lock if the driver
 	implements queue management or shaper API.
 
+	For ``TC_SETUP_BLOCK`` and ``TC_SETUP_FT`` ``rtnl_lock`` may or
+	may not be held, and the netdev instance lock is not held.
+	``TC_SETUP_BLOCK`` runs under ``block->cb_lock`` and ``TC_SETUP_FT``
+	runs under ``flowtable->flow_block_lock``.
+
 Most ndo callbacks not specified in the list above are running
 under ``rtnl_lock``. In addition, netdev instance lock is taken as well if
 the driver implements queue management or shaper API.
-- 
2.54.0


^ permalink raw reply related


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