What should I do with nonexistent _bh RCU functions? - linux-kernel

There are many RCU functions that don't have a _bh counterpart.
Examples are:
list_entry_rcu()
list_for_each_entry_rcu()
Is this because...
they can be called from bottom halves just fine (think list_empty() vs list_empty_rcu())?
Does this mean I can use rcu_read_lock() and rcu_read_lock_bh() interchangeably in these cases?
no one has so far needed them (and therefore I's supposed to roll out my own version of them)?
Rule 9 of the RCU checklist says "in which case the matching rcu_dereference() primitive must be used in order to keep lockdep happy". So I guess the second option above is true. But then I find code that reads like this:
rcu_read_lock_bh();
c = __clusterip_config_find(clusterip);
And then, during __clusterip_config_find():
list_for_each_entry_rcu(c, &clusterip_configs, list) {
What is going on!? list_for_each_entry_rcu() uses rcu_dereference_check(), not rcu_dereference_bh_check()...

This true:
No one has so far needed them (and therefore I's supposed to roll out my own version of them).
More precise, there is so many RCU list traversal functions, so one decide to not include all their _rcu_bh counterpairs because of rare needs. But see below.
You cannot use rcu_read_lock() and rcu_read_lock_bh interchangably. But difference between rcu_dereference and rcu_dereference_check only in annotation: them both expanded to __rcu_dereference_check() macro call with different c argument.
So, implementation of __clusterip_config_find is correct from the processor's view, but may produce warnings when checker is enabled. (Of cource, every driver should tend to work without warnings).

Related

Is there a way to somehow group several symbols from different files together so that if one of them is referenced, all are linked?

A bit of context first.
I'm curently working on a modular (embedded) microOS with drivers, ports, partitions and other such objects represented as structures, with distinct "operations" structures containing pointer to what you would call their methods. Nothing fancy there.
I have macros and linker script bits to make it so that all objects of a given type (say, all drivers), though their definitions are scattered across source files, are disposed as in an array, somewhere in flash, but in a way that lets the linker (I work with GNU GCC/LD.) garbage collected those who aren't explicitly referenced in the code.
However, after a few years refining the system and increasing its flexibility, I come at a point where it is too flash-greedy for small to medium microcontrollers. (I work only with 32 bits architectures, nothing too small.) I was to be exepected, you might say, but I'm trying to go further and do better, and currently I'm doubting LD will let me do it.
What I would like to get is that methods/functions which aren't used by the code get garbage collected too. This isn't currently the case, since they are all referred to by the pointer structures of the objects owning them. I would like to avoid using macro configuration switches and the application developper having to go through several layers of code to determine which functions are currently used and which ones can be safely disabled. I would really, really like that the linker's garbage collection let me automatize all the process.
First I thought I could split each methods structure between sections, so that, say, all the ports' "probe" methods end up in a section called .struct_probe, and that the wrapping port_probe() function could reference a zero-length object inside that function, so that all ports' probe references get linked if and only if the port_probe() function is called somewhere.
But I was wrong in that, for the linker, the "input sections" which are his resolution for garbage collection (since at this point there's no more alignment information inside, and it couldn't afford to take advantage of a symbol - and afferent object - being removed by reordering the insides of the containing section and shrinking it) aren't identified solely by a section name, but by a section name and a source file. So if I implement what I intended to, none of my methods will get linked in the final executable, and I will be toast.
That's where I'm at currently, and frankly I'm quite at a loss. I wondered if maybe someone here would have a better idea for either having each method "backward reference" the wrapping function or some other object which would in turn be referenced by the function and take all methods along, or as the title says, somehow group those methods / sections (without gathering all the code in a single file, please) so that referencing one means linking them all.
My gratitude for all eternity is on the line, here. ;)
Since I have spent some time documenting and experimenting on the following lead, even though without success, I would like to expose here what I found.
There's a feature of ELF called "group sections", which are used to define sections groups, or groups of sections, such as if one member section of the group is live (hence linked), all are.
I hoped this was the answer to my question. TL;DR: It wasn't, because group sections are meant to group sections inside a module. Actually, the only type of groups currently defined is COMDAT groups, which are by definition exclusive from groups with the same name defined in other modules.
Documentation on that feature and its implementation(s) is scarce to say the least. Currently, the standard's definition of group sections can be found here.
GCC doesn't provide a construct to manipulate section groups (or any kind of sections flags/properties for that matter). The GNU assembler's documentation specifies how to affect a section to a group here.
I've found no evocation in any GNU document about LD's handling of group sections. It is mentioned here and here, though.
As a bonus, I've found a way to specify sections properties (including grouping) in C code with GCC. This is a dirty hack, so it may be it won't work anymore by the time you read this.
Apparently, when you write
int bar __attribute__((section("<name>")));
GCC takes what's between the quotes an blindly pastes it so in the assembly output:
.section <name>,"aw"
(The actual flags can differ if the name matches one of a few predefined patterns.)
From there, it's all a matter of code injection. If you write
int bar __attribute__((section("<name>,\"awG\",%probbits,<group> //")));
you get
.section <name>,"awG",%progbits,<group> //"aw"
and the job is done. If you wonder why simply characterizing the section in a separate inline assembly statement isn't enough, if you do that you get an empty grouped section and a stuffed solitary section with the same name, which won't have any effect at link time. So.
This isn't entierely satisfying, but for lack of a better way, that's what I went for:
It seems the only way you have to effectively merge sections from several compilation units from the linker's point of view is to first link the resulting objects together in one big object, then link the final program using that big object instead of the small ones. Sections that had the same name in the small objects will be merged in the big one.
This is a bit dirty, though, and has also some drawbacks, such as perhaps merging some sections you wouldn't want to be, for garbage collecting purposes, and hiding which file each section comes from (though the information remains in the debug sections) if, say, you wanted to split the main sections (.text, .data, .bss...) in the final ELF so as to be able to see what file contributes what amount to flash and RAM usage, for instance.

Why do we need to separate or breakdown one Use Case into two or more use cases?

Why do you need to, in many instances, separate or breakdown one Use Case into two or more use cases?
The only reason to split a use case in multiple use cases is to share a significant piece of functionality among multiple use cases by isolating that piece of functionality in a separate use case.
Example: 'search product information' may be a separate use case included by use cases 'buy product' and 'hire product'.
Apart from 'include' there are also examples of the same principle using 'extend' or 'generalize'.
By doing so, you prevent that the shared behaviour is copied in multiple use cases, with the chance of growing inconsistencies.
In the previous example: We want to make sure that customers don't get a different way to search for product information when buying compared to when hiring products. With an included use case, people who read the use cases are immediately aware of that fact.
First of all: you don't. Starting to do that means you are doing functional analysis. The point in use case synthesis is to find the goal(s) (aka. added value) the different actors have when interacting with the system under consideration. It's quite futile to separate a goal into sub-goals at that level. Either you have some added value or you don't have it. So if someone has settled a use case and tries to break it down then the use case is either wrong (no use case) or it's useless since the use case already shows the added value.
My personal opinion about include and extend: they are basically evil and a wrong concept introduced by techies (which most of the UML designers are) with no business background. Using them means you are already starting functional analysis. But UCs are synthesized from requirements. That is, you drag your net through that requirements soup and fish out those that fit together to build a story which makes sense - and which delivers added value: a use case.
And as always: read Bittner/Spence about use cases.

How do I reinstate constraints collected with copy_term/3 in SICStus Prolog?

The documentation says that
copy_term(+Term, -Copy, -Body) makes a copy of Term in which all
variables have been replaced by new variables that occur nowhere
outside the newly created term. If Term contains attributed
variables, Body is unified with a term such that executing Body
will reinstate equivalent attributes on the variables in Copy.
I'm previously affirming numerical CLP(R) constraints over some variables, and at some point I collect these constraints using copy_term/3. Later, when I try to reinstate the constraints using 'call(Body)', I get an "Instantiation error" in arguments of the form [nfr:resubmit_eq(...)]
Here's a simplified example that demonstrates the problem:
:-use_module(library(clpr)).
{Old>=0, A>=0,A=<10, NR= Old+Z, Z=Old*(A/D)}, copy_term(Old,New,CTR), call(CTR).
Results in:
Instantiation error in argument 1 of '.'/2
! goal: [nfr:resubmit_eq([v(-1.0,[_90^ -1,_95^1,_100^1]),v(1.0,[_113^1])])]
My question is: how do I reinstate the constraints in Body over New? I haven't been able to find concrete examples.
copy_term/3 is a relatively new built-in predicate, that has been first introduced in SICStus about 2006. Its motivation was to replace the semantically cumbersome call_residue/2 which originated from SICStus 0.6 of 1987 by a cleaner and more efficient interface that splits the functionality in two:
call_residue_vars(Goal, Vars) which is like call(Goal) and upon success unifies Vars with a list variables (in unspecified order) that are attached to constraints and have been created or affected in Goal.
copy_term(Term, Copy, Body) like copy_term/2 and upon success unifies Body with a term to reinstate the actual constraints involved. Originally, Body was a goal that could be executed directly. Many systems that adopted this interface (like SWI, YAP) however, switched to use a list of goals instead. This simplifies frequent operations since you have less defaultyness, but at the expense of making reinstating more complex. You need to use maplist(call,Goals).
Most of the time, these two built-in predicates will be used together. You are using only one which makes me a bit suspicious. You first need to figure out which variables are involved, and only then you can copy them. Typically you will use call_residue_vars/2 for that. If you are copying only a couple of variables (as in your exemple) you are effectively projecting the constraints on these variables. This may or may not be your intention.
This is simply a bug in CLPR, which is unsupported. We lost touch with the CLPR supplier a long time ago.

GCC hidden/little-known features

This is my attempt to start a collection of GCC special features which usually do not encounter. this comes after #jlebedev in the another question mentioned "Effective C++" option for g++,
-Weffc++
This option warns about C++ code which breaks some of the programming guidelines given in the books "Effective C++" and "More Effective C++" by Scott Meyers. For example, a warning will be given if a class which uses dynamically allocated memory does not define a copy constructor and an assignment operator. Note that the standard library header files do not follow these guidelines, so you may wish to use this option as an occasional test for possible problems in your own code rather than compiling with it all the time.
What other cool features are there?
From time to time I go through the current GCC/G++ command line parameter documentation and update my compiler script to be even more paranoid about any kind of coding error. Here it is if you are interested.
Unfortunately I didn't document them so I forgot most, but -pedantic, -Wall, -Wextra, -Weffc++, -Wshadow, -Wnon-virtual-dtor, -Wold-style-cast, -Woverloaded-virtual, and a few others are always useful, warning me of potentially dangerous situations. I like this aspect of customizability, it forces me to write clean, correct code. It served me well.
However they are not without headaches, especially -Weffc++. Just a few examples:
It requires me to provide a custom copy constructor and assignment operator if there are pointer members in my class, which are useless since I use garbage collection. So I need to declare empty private versions of them.
My NonInstantiable class (which prevents instantiation of any subclass) had to implement a dummy private friend class so G++ didn't whine about "only private constructors and no friends"
My Final<T> class (which prevents subclassing of T if T derived from it virtually) had to wrap T in a private wrapper class to declare it as friend, since the standard flat out forbids befriending a template parameter.
G++ recognizes functions that never return a return value, and throw an exception instead, and whines about them not being declared with the noreturn attribute. Hiding behind always true instructions didn't work, G++ was too clever and recognized them. Took me a while to come up with declaring a variable volatile and comparing it against its value to be able to throw that exception unmolested.
Floating point comparison warnings. Oh god. I have to work around them by writing x <= y and x >= y instead of x == y where it is acceptable.
Shadowing virtuals. Okay, this is clearly useful to prevent stupid shadowing/overloading problems in subclasses but still annoying.
No previous declaration for functions. Kinda lost its importance as soon as I started copypasting the function declaration right above it.
It might sound a bit masochist, but as a whole, these are very cool features that increased my understanding of C++ and general programming.
What other cool features G++ has? Well, it's free, open, it's one of the most widely used and modern compilers, consistently outperforms its competitors, can eat almost anything people throw at it, available on virtually every platform, customizable to hell, continuously improved, has a wide community - what's not to like?
A function that returns a value (for example an int) will return a random value if a code path is followed that ends the function without a 'return value' statement. Not paying attention to this can result in exceptions and out of range memory writes or reads.
For example if a function is used to obtain the index into an array, and the faulty code path is used (the one that doesn't end with a return 'value' statement) then a random value will be returned which might be too big as an index into the array, resulting in all sorts of headaches as you wrongly mess up the stack or heap.

Cross version line matching

I'm considering how to do automatic bug tracking and as part of that I'm wondering what is available to match source code line numbers (or more accurate numbers mapped from instruction pointers via something like addr2line) in one version of a program to the same line in another. (Assume everything is in some kind of source control and is available to my code)
The simplest approach would be to use a diff tool/lib on the files and do some math on the line number spans, however this has some limitations:
It doesn't handle cross file motion.
It might not play well with lines that get changed
It doesn't look at the information available in the intermediate versions.
It provides no way to manually patch up lines when the diff tool gets things wrong.
It's kinda clunky
Before I start diving into developing something better:
What already exists to do this?
What features do similar system have that I've not thought of?
Why do you need to do this? If you use decent source version control, you should have access to old versions of the code, you can simply provide a link to that so people can see the bug in its original place. In fact the main problem I see with this system is that the bug may have already been fixed, but your automatic line tracking code will point to a line and say there's a bug there. Seems this system would be a pain to build, and not provide a whole lot of help in practice.
My suggestion is: instead of trying to track line numbers, which as you observed can quickly get out of sync as software changes, you should decorate each assertion (or other line of interest) with a unique identifier.
Assuming you're using C, in the case of assertions, this could be as simple as changing something like assert(x == 42); to assert(("check_x", x == 42)); -- this is functionally identical, due to the semantics of the comma operator in C and the fact that a string literal will always evaluate to true.
Of course this means that you need to identify a priori those items that you wish to track. But given that there's no generally reliable way to match up source line numbers across versions (by which I mean that for any mechanism you could propose, I believe I could propose a situation in which that mechanism does the wrong thing) I would argue that this is the best you can do.
Another idea: If you're using C++, you can make use of RAII to track dynamic scopes very elegantly. Basically, you have a Track class whose constructor takes a string describing the scope and adds this to a global stack of currently active scopes. The Track destructor pops the top element off the stack. The final ingredient is a static function Track::getState(), which simply returns a list of all currently active scopes -- this can be called from an exception handler or other error-handling mechanism.

Resources