All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Pasha Tatashin" <pasha.tatashin@soleen.com>
To: "Mike Rapoport" <rppt@kernel.org>,
	"Pasha Tatashin" <pasha.tatashin@soleen.com>
Cc: <linux-kselftest@vger.kernel.org>, <shuah@kernel.org>,
	<linux-mm@kvack.org>, <skhan@linuxfoundation.org>,
	<linux-doc@vger.kernel.org>, <vipinsh@google.com>,
	<linux-kernel@vger.kernel.org>, <corbet@lwn.net>,
	<dmatlack@google.com>, <kexec@lists.infradead.org>,
	<pratyush@kernel.org>, <rdunlap@infradead.org>, <graf@amazon.com>
Subject: Re: [PATCH v5 3/6] liveupdate: luo: serialize sessions via per-session publish helper
Date: Wed, 11 Nov 2026 10:37:40 -0500	[thread overview]
Message-ID: <DMSHRWYSS8FJ.2H4W2E388G00V@soleen.com> (raw)
In-Reply-To: <179439592040.425130.1571434550510654411.b4-review@b4>

On Wed Nov 11, 2026 at 6:18 AM EST, Mike Rapoport wrote:
> Hi,
>
>> With incremental kho_block publication in place, LUO sessions can be
>> published into sh->block_set individually as they are committed, rather
>> than rebuilding the entire session serialization chain during reboot.
>> 
>> Currently, luo_session_serialize() resets *sh->sessions_pa and
>> serializes all outgoing sessions from scratch in a single pass at reboot
>> time.
>> 
>> Introduce luo_session_publish_one() to append a session's
>> luo_session_ser entry via kho_block_set_it_append() and move the session
>> onto sh->published_list. Update luo_session_serialize() to freeze all
>> remaining unpublished sessions first (rolling back via
>> luo_session_unfreeze_one() on failure) and then publish them in a second
>> pass.
>> 
>> Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
>> ---
>>  kernel/liveupdate/luo_session.c | 92 ++++++++++++++++++++++-----------
>>  1 file changed, 63 insertions(+), 29 deletions(-)
>>
>> diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c
>> index 6dea359111818..caf0e85081e87 100644
>> --- a/kernel/liveupdate/luo_session.c
>> +++ b/kernel/liveupdate/luo_session.c
>> @@ -103,20 +103,30 @@
>>  static DECLARE_RWSEM(luo_session_serialize_rwsem);
>>  /**
>>   * struct luo_session_header - Header struct for managing LUO sessions.
>> - * @count:       The number of sessions currently tracked in the @list.
>> + * @count:       The number of sessions currently tracked in the header.
>> + * @published_count: The number of outgoing sessions currently published in
>> + *                   @block_set.
>>   * @list:        The head of the linked list of `struct luo_session` instances.
>
> Add "yet unpublished" to the description?

Yeap, will clarify list holds yet-unserialized sessions.

>> + * @published_list:  The head of the linked list of published outgoing
>> + *                   sessions, ordered identically to their entries in
>> + *                   @block_set.
>>   * @rwsem:       A read-write semaphore providing synchronized access to the
>>   *               session list and other fields in this structure.
>>   * @block_set:   The set of serialization blocks.
>> + * @it:          Iterator tracking the next slot in @block_set for outgoing
>> + *               session serialization.
>>   * @sessions_pa: Points to the location of sessions_pa within struct luo_ser.
>>   * @active:      Set to true when first initialized. If previous kernel did not
>>   *               send session data, active stays false for incoming.
>>   */
>>  struct luo_session_header {
>>  	long count;
>> +	long published_count;
>>  	struct list_head list;
>> +	struct list_head published_list;
>>  	struct rw_semaphore rwsem;
>>  	struct kho_block_set block_set;
>> +	struct kho_block_set_it it;
>>  	u64 *sessions_pa;
>>  	bool active;
>>  };
>> @@ -134,12 +144,14 @@ struct luo_session_global {
>>  static struct luo_session_global luo_session_global = {
>>  	.incoming = {
>>  		.list = LIST_HEAD_INIT(luo_session_global.incoming.list),
>> +		.published_list = LIST_HEAD_INIT(luo_session_global.incoming.published_list),
>>  		.rwsem = __RWSEM_INITIALIZER(luo_session_global.incoming.rwsem),
>>  		.block_set = KHO_BLOCK_SET_INIT(luo_session_global.incoming.block_set,
>>  						sizeof(struct luo_session_ser)),
>>  	},
>>  	.outgoing = {
>>  		.list = LIST_HEAD_INIT(luo_session_global.outgoing.list),
>> +		.published_list = LIST_HEAD_INIT(luo_session_global.outgoing.published_list),
>>  		.rwsem = __RWSEM_INITIALIZER(luo_session_global.outgoing.rwsem),
>>  		.block_set = KHO_BLOCK_SET_INIT(luo_session_global.outgoing.block_set,
>>  						sizeof(struct luo_session_ser)),
>> @@ -186,6 +198,10 @@ static int luo_session_insert(struct luo_session_header *sh,
>>  		if (!strncmp(it->name, session->name, sizeof(it->name)))
>>  			return -EEXIST;
>>  	}
>> +	list_for_each_entry(it, &sh->published_list, list) {
>> +		if (!strncmp(it->name, session->name, sizeof(it->name)))
>> +			return -EEXIST;
>> +	}
>>  
>>  	/*
>>  	 * For outgoing we should make sure there is room in serialization array
>> @@ -203,6 +219,42 @@ static int luo_session_insert(struct luo_session_header *sh,
>>  	return 0;
>>  }
>>  
>> +static void luo_session_publish_one(struct luo_session *session)
>> +{
>> +	struct luo_session_header *sh = &luo_session_global.outgoing;
>> +	struct luo_session_ser entry = {};
>> +
>> +	lockdep_assert_held_write(&sh->rwsem);
>> +	lockdep_assert_held(&session->mutex);
>> +
>> +	if (!sh->active || !sh->sessions_pa)
>> +		return;
>> +
>> +	if (!sh->published_count)
>> +		kho_block_set_it_init(&sh->it, &sh->block_set);
>> +
>> +	strscpy(entry.name, session->name, sizeof(entry.name));
>> +	entry.file_set_ser.count = session->file_set.count;
>> +	entry.file_set_ser.files =
>> +		kho_block_set_head_pa(&session->file_set.block_set);
>> +
>> +	/* This should not fail normally as blocks were pre-allocated */
>> +	if (WARN_ON_ONCE(!kho_block_set_it_append(&sh->it, &entry)))
>> +		return;
>> +
>> +	if (!sh->published_count) {
>> +		/*
>> +		 * Ensure the first block header and entry are visible before
>> +		 * publishing sessions_pa to concurrent KHO readers.
>> +		 */
>> +		smp_store_release(sh->sessions_pa,
>> +				  kho_block_set_head_pa(&sh->block_set));
>> +	}
>
>
>> +
>> +	list_move_tail(&session->list, &sh->published_list);
>> +	sh->published_count++;
>> +}
>> +
>>  static void luo_session_remove(struct luo_session_header *sh,
>>  			       struct luo_session *session)
>>  {
>> @@ -636,50 +688,32 @@ int luo_session_deserialize(void)
>>  int luo_session_serialize(void)
>>  {
>>  	struct luo_session_header *sh = &luo_session_global.outgoing;
>> -	struct luo_session *session;
>> -	struct kho_block_set_it it;
>> +	struct luo_session *session, *tmp;
>>  	int err;
>>  
>>  	down_write(&luo_session_serialize_rwsem);
>>  	down_write(&sh->rwsem);
>> -	*sh->sessions_pa = 0;
>> -
>> -	kho_block_set_it_init(&it, &sh->block_set);
>>  
>>  	list_for_each_entry(session, &sh->list, list) {
>> -		struct luo_session_ser *ser = kho_block_set_it_reserve_entry(&it);
>> -
>> -		/* This should not fail normally as blocks were pre-allocated */
>> -		if (WARN_ON_ONCE(!ser)) {
>> -			err = -ENOSPC;
>> -			goto err_undo;
>> -		}
>> -
>>  		err = luo_session_freeze_one(session);
>>  		if (err) {
>> -			kho_block_set_it_prev(&it);
>> -			goto err_undo;
>> +			list_for_each_entry_continue_reverse(session, &sh->list, list)
>> +				luo_session_unfreeze_one(session);
>> +			goto err_unlock;
>
> Why goto err_ can do this?
> I really prefer to avoid error handling inside if (err) blocks whenever
> possible.

Makes sense, will move it.

>
>>  		}
>> +	}
>>  
>> -		strscpy(ser->name, session->name, sizeof(ser->name));
>> -		ser->file_set_ser.count = session->file_set.count;
>> -		ser->file_set_ser.files =
>> -			kho_block_set_head_pa(&session->file_set.block_set);
>> +	list_for_each_entry_safe(session, tmp, &sh->list, list) {
>> +		mutex_lock(&session->mutex);
>> +		luo_session_publish_one(session);
>
> And running a loop of _publish() in _serialize() makes my bikeshedding
> argument stronger ;-)

+1, will fix it in v6.

-- 
Pasha



  reply	other threads:[~2026-11-11 15:37 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05  5:00 [PATCH v5 0/6] liveupdate: Add LIVEUPDATE_SESSION_FREEZE ioctl Pasha Tatashin
2026-11-05  5:00 ` [PATCH v5 1/6] liveupdate: Move file_set_ser handling to luo_session_serialize() Pasha Tatashin
2026-11-05  5:00 ` [PATCH v5 2/6] kho: support incremental entry publication in kho_block Pasha Tatashin
2026-11-11 11:18   ` Mike Rapoport
2026-11-11 15:15     ` Pasha Tatashin
2026-11-05  5:00 ` [PATCH v5 3/6] liveupdate: luo: serialize sessions via per-session publish helper Pasha Tatashin
2026-11-11 11:18   ` Mike Rapoport
2026-11-11 15:37     ` Pasha Tatashin [this message]
2026-11-05  5:00 ` [PATCH v5 4/6] liveupdate: luo_flb: support incremental outgoing FLB publication Pasha Tatashin
2026-11-11 11:18   ` Mike Rapoport
2026-11-11 21:08     ` Pasha Tatashin
2026-11-05  5:00 ` [PATCH v5 5/6] liveupdate: Add LIVEUPDATE_SESSION_FREEZE ioctl to freeze sessions early Pasha Tatashin
2026-11-11 11:18   ` Mike Rapoport
2026-11-11 21:13     ` Pasha Tatashin
2026-11-05  5:00 ` [PATCH v5 6/6] selftests: liveupdate: Add tests for LIVEUPDATE_SESSION_FREEZE Pasha Tatashin
2026-11-11  9:56 ` [PATCH v5 0/6] liveupdate: Add LIVEUPDATE_SESSION_FREEZE ioctl Mike Rapoport
2026-11-11 11:18 ` Mike Rapoport
2026-11-11 11:45   ` Pasha Tatashin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DMSHRWYSS8FJ.2H4W2E388G00V@soleen.com \
    --to=pasha.tatashin@soleen.com \
    --cc=corbet@lwn.net \
    --cc=dmatlack@google.com \
    --cc=graf@amazon.com \
    --cc=kexec@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=pratyush@kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=rppt@kernel.org \
    --cc=shuah@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --cc=vipinsh@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.