Commit a1259dd8 authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Catalin Marinas
Browse files

arm64/sve: Delay freeing memory in fpsimd_flush_thread()



fpsimd_flush_thread() invokes kfree() via sve_free()+sme_free() within a
preempt disabled section which is not working on -RT.

Delay freeing of memory until preemption is enabled again.

Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: default avatarMark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20220505163207.85751-2-bigeasy@linutronix.de


Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent d158a060
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -1562,6 +1562,9 @@ static void fpsimd_flush_thread_vl(enum vec_type type)

void fpsimd_flush_thread(void)
{
	void *sve_state = NULL;
	void *za_state = NULL;

	if (!system_supports_fpsimd())
		return;

@@ -1573,18 +1576,28 @@ void fpsimd_flush_thread(void)

	if (system_supports_sve()) {
		clear_thread_flag(TIF_SVE);
		sve_free(current);

		/* Defer kfree() while in atomic context */
		sve_state = current->thread.sve_state;
		current->thread.sve_state = NULL;

		fpsimd_flush_thread_vl(ARM64_VEC_SVE);
	}

	if (system_supports_sme()) {
		clear_thread_flag(TIF_SME);
		sme_free(current);

		/* Defer kfree() while in atomic context */
		za_state = current->thread.za_state;
		current->thread.za_state = NULL;

		fpsimd_flush_thread_vl(ARM64_VEC_SME);
		current->thread.svcr = 0;
	}

	put_cpu_fpsimd_context();
	kfree(sve_state);
	kfree(za_state);
}

/*