Issue
I am trying to implement a new syscall in linux kernel, so I wrote:
asmlinkage int my_func(void) {
return my_func_internal();
}
my question, should I define my_func_internal
as asmlinkage or not?
in other words, should I write A or B?
A) asmlinkage int my_func_internal(void) {return 1;}
B) int my_func_internal(void) {return 1;}
I would like some explanation too
Note: I have added my_func to syscalls.h should I add the internal one too (probably the answer is no)
Solution
It doesn't matter (for correctness) what calling convention you use for functions that aren't called directly by hand-written asm. (Which syscall implementation functions might be on some architectures, that's why they should be asmlinkage
.) As long as all callers can see a prototype that matches the definition, it will work.
If asmlinkinkage
is a different calling convention from the default one (e.g. on i386, asmlinkage
means to use stack args, overriding the -mregparm=3
build option that makes internal functions use register args), the compiler will have to emit a definition for my_func
that handles the difference if it calls a function that isn't asmlinkage
. Or simply inline my_func_internal()
into it.
If they use the same calling convention, and the compiler chooses not to inline, it could just do an optimized tailcall to my_func_internal
, e.g. on x86 jmp my_func_internal
. So there's a possible efficiency advantage to using the same calling convention if there's a possibility of an optimized tailcall. Otherwise don't; asmlinkage
makes the calling convention less efficient on i386.
(IIRC, asmlinkage
has no effect on x86-64 and most other modern ISAs with register-args calling conventions; the default calling convention on x86 is already good so the kernel doesn't need to override it with -mregparm=3
like it does on i386.)
In your example where there are no args, there's no difference.
BTW, the usual naming convention for the function name is sys_foo
to implement a system-call called foo
. i.e. the function that will get called when user-space passes __NR_foo
as the call number.
Note: I have added my_func to syscalls.h should I add the internal one too (probably the answer is no)
Of course not, unless my_func_internal
implements a different system call that you want user-space to be able to call directly.
Answered By - Peter Cordes