what does __init_refok keyword means in linux kernel code? - linux-kernel

While browsing the kernel code, I came accross a keyword that is used in several kernel init functions, __init_refok.
some of the lines I came accross are like
void __init_refok free_initmem(void)
static void __init_refok vgacon_scrollback_startup(void)
const struct linux_logo * __init_refok fb_find_logo(int depth)
void noinline __init_refok rest_init(void)
and others.
I searched for the reference , from that I came to know that it is defined as a preprocessor macro in include/linux/init.h, line 71.
After browsing that, I got the following codes
#define __init_refok __ref
and
#define __ref __section(.ref.text) noinline
After that, I am losing track.
If anyone can let me know what is the purpose of using that keyword in the code, it will be very helpful.
[I am looking for the basic functionality achieved by using this keyword, just like using __init helps to put the initialization code in seperate memory location to be cleared after init process has been completed.]
Thanks in advance.
EDIT
In the include/linux/init.h, it is mentioned like __init_refok is to supress the warning from modpost check, due to any reference form normal code to init section code, but still, I am not getting it exactly. Does that mean that these codes will ba place somewhere else? How actually the behaviour differs from the normal behaviour by using __init_refok keyword?

To my understanding, include/linux/init.h clearly documents the purpose of __init_refok. As you have mentioned
using __init helps to put the initialization code in separate memory
location to be cleared after init process has been completed.
compiler generates a warning when we use the data or code from the separate memory as they might will be removed at the time of the execution of the particular code referencing them.
__init_refok is a way to tell the compiler that you are aware and consciously referencing the initialization code or data. It means ref erencing init section is ok for you. Thus compiler does not generate any warning.
The file also documents that, though the warning is suppressed, it is the programmer's responsibility write such code that refers init section data or code.
of course, no warning does not mean code is correct, so optimally
document why the __ref is needed and why it's OK
In your example, the functions free_initmem(void) is probably referring to some data or code, that are tagged with _init.
The _init_refok tag does not remove the code neither relocate. The code is treated as ordinary except, if it contains any reference to init code or data, warning will be suppressed.

Related

c++ Hidden Unique Pointer

I have some code which depends on some include files which are partly defined at the start of source files (which is usual) and others which are used within functions.
I typical example for that are the OpenFOAM solver sources.
Because the scheme of this code is highly procedural, but I want to put all this into a class which provides init(), run() and maybe release(), I plan to put some of the variables into the classes as private making them members.
I don't want to modify the included files because they belong to a library.
The reason for using a class is that other routines classes run together with this code.
Here is the thing. init() must prepare some variable and there situations that theses variables (being type of other clases) not explicit constructors and special arguments. It is called once. run() is called several times. The procedural code has a loop only and the contents of that loop are put into the run() method.
So the best solution was to put these variables into std::unique_ptr and init can construct whatever it needs to. Obviously with that trick the variable signature changed, so I created a second declaration of a reference like this:
std::unique_ptr<volScalarField> mp_p;
volScalarField &p = *mp_p;
Now this is a bit tedious so I created a macro
FOAMPTR(volVectorField, p)
which does all the work for me:
#define FOAMPTR(TYPE,NAME) std::unique_ptr<TYPE> mp_##NAME; TYPE &NAME=*mp_##NAME
It works pretty well, but I'm not fan of macros in general, especially if you need to debug code.
Now my question is: Is there a better way to tackle this and use something else like a template definition which might do all the magic?
Edit: With 'works pretty well' I mean, that the compiler can translate that. The reference though still is invalid.
Edit: Okay, I solved the invalid pointer problem using two Macros:
#define FOAMPTR(TYPE,NAME) std::unique_ptr<TYPE> mp_##NAME
#define FETCHFOAMREF(NAME) auto &NAME=*mp_##NAME
Now I put FOAMPTR(TYPE,NAME) to the member and I get my unique ptrs. In the run() method the second macro FETCHFOAMREF(NAME) is used. Of course init() must be sure to correctly initialize the object or else the program is going to crash.
I still leave the question open because I'm not satisfied with that solution.

Prefixing printk / pr_* calls

I would like to prefix my drivers (debug) output with its name, i.e. [myDriver] Actual message. Since it is tiresome to write printk(level NAMEMACRO "Actual message\n") every time I was thinking of overwriting printk/pr_* to actually include the [myDriver] part. However I can not think of a way to do this. In the best case the solution would not force me to change the printk/pr_* calls in the code (With changed calls this becomes trivial).
Is this possible? (Since I included other headers which in turn include the printk header it will always be defined this rules out not linking to the original as suggested in a different so answer)
Are there any reasons why current drivers do not at this to the text? (Is there another way to filter dmesg by driver?)
I am somewhat aware of dev_dbg but I have not found anything dev specific for warnings in general so I will use printk/pr_err for that.
Its standard to use pr_{debug,warn,err}() with [drivername] prefixed.
ex:
pr_debug("kvm: matched tsc offset for %llu\n", data);
Alternatively you can use dev_warn()
ex:
dev_warn(&adap->dev, "Bus may be unreliable\n");
Is there another way to filter dmesg by driver?
Not unless you want to run dmesg -c to clear the logs, before getting the your driver loaded. Its always recommenced prefixing the driver name in your debug / print messages. As when you receives logs from customers, you don't want to waste time reading through each line manually.
The relevant answer (found in the duplicate) is to #define pr_fmt (code from the duplicate question linked above):
/* At the top of the file, before any includes */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/printk.h>
As an additional note, if I include variables, sometime pr_fmt is not automatically applied for me. Manual use as in printk(pr_fmt("message %p"), (void*)ptr) fixes those occasions, and adheres to the convention of defining pr_fmt
Since I did not find the duplicate question, I will not delete this question for other googlers like me.

Looking for C source code for snprintf()

I need to port snprintf() to another platform that does not fully support GLibC.
I am looking for the underlying declaration in the Glibc 2.14 source code. I follow many function calls, but get stuck on vfprintf(). It then seems to call _IO_vfprintf(), but I cannot find the definition. Probably a macro is obfuscating things.
I need to see the real C code that scans the format string and calculates the number of bytes it would write if input buffer was large enough.
I also tried looking in newlib 1.19.0, but I got stuck on _svfprintf_r(). I cannot find the definition anywhere.
Can someone point me to either definition or another one for snprintf()?
I've spent quite a while digging the sources to find _svfprintf_r() (and friends) definitions in the Newlib. Since OP asked about it, I'll post my finding for the poor souls who need those as well. The following holds true for Newlib 1.20.0, but I guess it is more or less the same across different versions.
The actual sources are located in the vfprintf.c file. There is a macro _VFPRINTF_R set to one of _svfiprintf_r, _vfiprintf_r, _svfprintf_r, or _vfprintf_r (depending on the build options), and then the actual implementation function is defined accordingly:
int
_DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
struct _reent *data _AND
FILE * fp _AND
_CONST char *fmt0 _AND
va_list ap)
{
...
http://www.ijs.si/software/snprintf/ has what they claim is a portable implementation of snprintf, including vsnprintf.c, asnprintf, vasnprintf, asprintf, vasprintf. Perhaps it can help.
The source code of the GNU C library (glibc) is hosted on sourceware.org.
Here is a link to the implementation of vfprintf(), which is called by snprintf():
https://sourceware.org/git/?p=glibc.git;a=blob;f=stdio-common/vfprintf.c

SymtabAPI doesn't implicity change binary

I'm using the DyninstAPI (namely, the SymtabAPI component) to rewrite the symbol tables in binaries. I'm using the following methods to do so:
data_region->setPtrToRawData((void*) new_raw, data_region->getRegionSize())
The method returns successfully, I check my error codes, and I even re-read the data section which has successfully been replaced. The problem is that the original binary isn't rewritten with the new raw .data section, and the original raw .data section persists.
I've scoured the manual to see if there is some sort of commit function but none is documented and nothing of the sort is mentioned in the examples. EDIT: I just read through some of the source code for the Region class, and it looks like I'm essentially doing what patchData does (in case that is the method I should be using).
Suggestions?
The programming manuals are available at http://www.paradyn.org/html/manuals.html.
P.S. hopefully a more reputable user can add the tags DyninstAPI and SymtabAPI for me.
After consulting with the developers, they alerted me that the function I needed to call was emit and the syntax I ended up using was:
symtab_obj->emit("new_binary.out");
Thanks Drew!

GCC 4.7 fails to inline with message "function body not available"

I am trying to compile some legacy code with more modern toolchains. I have tracked down one of my issues to the switch from gcc 4.6 to gcc 4.7:
Some of the functions are annotated with the inline keyword. Gcc fails on these with the error message:
error: inlining failed in call to always_inline 'get_value_global': function body not available
What is the correct way of dealing with this issue? How could the function body not be available? Should the compiler not make sure that it is available in all situations that require it?
Edit
As requested (in a deleted comment), an example of a signature of a function resulting in the error:
inline struct a_value_fmt const *find_a_value_format(struct base_fmt *base)
{
/* the code */
}
That error is typical to inline functions declared in source files, rather than in header files, in which case the compiler is not able to inline them (as the code of the function to be inlined must be visible to the compiler in the same source file being compiled). So, first thing I would check is that all functions declared inline are indeed defined in header files.
It may be that a change in GCC diagnostics in 4.7 caused the error to surface, and that it went silent in GCC 4.6 (but that's just a speculation).
The quoted error indicates that the function is declared with __attribute__((always_inline)). Note that GCC may fail to inline and report a different (and quite obscure) error if function is declared always_inline, but not with the inline keyword - so make sure that any function declared as always_inline is also declared as inline.
Few more tips:
General advice, which may not be applicable: since this is a legacy codebase, you may want to re-evaluate which functions should be inlined, being on the critical path, and which aren't, based on updated profiling results. Sometimes, inline is used generously, even when it is not required, or redundant. In some cases, the fix may be to remove the inline keyword in places where it is not needed.
When functions are declared in header files, the compiler considers them for inlining automatically (given they are small enough, and the compiler thinks that inlining them will improve performance, based on its heuristics) - even when the inline keyword is not used. inline is sort of a "recommendation" to the compiler, and it doesn't have to obey (unless it is given along with the always_inline attribute).
Modern compilers make relatively smart inlining decisions, so it's usually best to let the compiler do it's thing, and declare functions as inline (and moving their implementations to header files) in the appliation hot spots, based on profiling results.

Resources