mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
liveupdate: defer session block allocation and physical address setting
Currently, luo_session_setup_outgoing() allocates the session block and sets its physical address in the header immediately. With upcoming dynamic block-based session management, this makes the first block different from the rest. Move the allocation to where it is first needed. Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org> Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com> Link: https://patch.msgid.link/20260603154402.468928-9-pasha.tatashin@soleen.com Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
This commit is contained in:
parent
0349ff2887
commit
b5a58a922e
|
|
@ -165,9 +165,7 @@ static int __init luo_state_setup(void)
|
|||
strscpy(luo_ser->compatible, LUO_ABI_COMPATIBLE, sizeof(luo_ser->compatible));
|
||||
luo_ser->liveupdate_num = luo_global.liveupdate_num + 1;
|
||||
|
||||
err = luo_session_setup_outgoing(&luo_ser->sessions_pa);
|
||||
if (err)
|
||||
goto exit_free_luo_ser;
|
||||
luo_session_setup_outgoing(&luo_ser->sessions_pa);
|
||||
|
||||
err = luo_flb_setup_outgoing(&luo_ser->flbs_pa);
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ extern struct rw_semaphore luo_register_rwlock;
|
|||
|
||||
int luo_session_create(const char *name, struct file **filep);
|
||||
int luo_session_retrieve(const char *name, struct file **filep);
|
||||
int __init luo_session_setup_outgoing(u64 *sessions_pa);
|
||||
void __init luo_session_setup_outgoing(u64 *sessions_pa);
|
||||
int __init luo_session_setup_incoming(u64 sessions_pa);
|
||||
int luo_session_serialize(void);
|
||||
int luo_session_deserialize(void);
|
||||
|
|
|
|||
|
|
@ -108,15 +108,16 @@ 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.
|
||||
* @list: The head of the linked list of `struct luo_session` instances.
|
||||
* @rwsem: A read-write semaphore providing synchronized access to the
|
||||
* session list and other fields in this structure.
|
||||
* @header_ser: The header data of serialization array.
|
||||
* @ser: The serialized session data (an array of
|
||||
* `struct luo_session_ser`).
|
||||
* @active: Set to true when first initialized. If previous kernel did not
|
||||
* send session data, active stays false for incoming.
|
||||
* @count: The number of sessions currently tracked in the @list.
|
||||
* @list: The head of the linked list of `struct luo_session` instances.
|
||||
* @rwsem: A read-write semaphore providing synchronized access to the
|
||||
* session list and other fields in this structure.
|
||||
* @header_ser: The header data of serialization array.
|
||||
* @ser: The serialized session data (an array of
|
||||
* `struct luo_session_ser`).
|
||||
* @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;
|
||||
|
|
@ -124,6 +125,7 @@ struct luo_session_header {
|
|||
struct rw_semaphore rwsem;
|
||||
struct luo_session_header_ser *header_ser;
|
||||
struct luo_session_ser *ser;
|
||||
u64 *sessions_pa;
|
||||
bool active;
|
||||
};
|
||||
|
||||
|
|
@ -171,10 +173,30 @@ static void luo_session_free(struct luo_session *session)
|
|||
kfree(session);
|
||||
}
|
||||
|
||||
static int luo_session_grow_ser(struct luo_session_header *sh)
|
||||
{
|
||||
struct luo_session_header_ser *header_ser;
|
||||
|
||||
if (sh->count == LUO_SESSION_MAX)
|
||||
return -ENOMEM;
|
||||
|
||||
if (sh->header_ser)
|
||||
return 0;
|
||||
|
||||
header_ser = kho_alloc_preserve(LUO_SESSION_PGCNT << PAGE_SHIFT);
|
||||
if (IS_ERR(header_ser))
|
||||
return PTR_ERR(header_ser);
|
||||
|
||||
sh->header_ser = header_ser;
|
||||
sh->ser = (void *)(header_ser + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luo_session_insert(struct luo_session_header *sh,
|
||||
struct luo_session *session)
|
||||
{
|
||||
struct luo_session *it;
|
||||
int err;
|
||||
|
||||
guard(rwsem_write)(&sh->rwsem);
|
||||
|
||||
|
|
@ -183,8 +205,9 @@ static int luo_session_insert(struct luo_session_header *sh,
|
|||
* for new session.
|
||||
*/
|
||||
if (sh == &luo_session_global.outgoing) {
|
||||
if (sh->count == LUO_SESSION_MAX)
|
||||
return -ENOMEM;
|
||||
err = luo_session_grow_ser(sh);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -524,21 +547,10 @@ int luo_session_retrieve(const char *name, struct file **filep)
|
|||
return err;
|
||||
}
|
||||
|
||||
int __init luo_session_setup_outgoing(u64 *sessions_pa)
|
||||
void __init luo_session_setup_outgoing(u64 *sessions_pa)
|
||||
{
|
||||
struct luo_session_header_ser *header_ser;
|
||||
|
||||
header_ser = kho_alloc_preserve(LUO_SESSION_PGCNT << PAGE_SHIFT);
|
||||
if (IS_ERR(header_ser))
|
||||
return PTR_ERR(header_ser);
|
||||
|
||||
*sessions_pa = virt_to_phys(header_ser);
|
||||
|
||||
luo_session_global.outgoing.header_ser = header_ser;
|
||||
luo_session_global.outgoing.ser = (void *)(header_ser + 1);
|
||||
luo_session_global.outgoing.sessions_pa = sessions_pa;
|
||||
luo_session_global.outgoing.active = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init luo_session_setup_incoming(u64 sessions_pa)
|
||||
|
|
@ -644,6 +656,8 @@ int luo_session_serialize(void)
|
|||
|
||||
down_write(&luo_session_serialize_rwsem);
|
||||
down_write(&sh->rwsem);
|
||||
*sh->sessions_pa = 0;
|
||||
|
||||
list_for_each_entry(session, &sh->list, list) {
|
||||
err = luo_session_freeze_one(session, &sh->ser[i]);
|
||||
if (err)
|
||||
|
|
@ -653,7 +667,11 @@ int luo_session_serialize(void)
|
|||
sizeof(sh->ser[i].name));
|
||||
i++;
|
||||
}
|
||||
sh->header_ser->count = sh->count;
|
||||
|
||||
if (sh->header_ser && sh->count > 0) {
|
||||
sh->header_ser->count = sh->count;
|
||||
*sh->sessions_pa = virt_to_phys(sh->header_ser);
|
||||
}
|
||||
up_write(&sh->rwsem);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user