[Kernel] How to know KBUILD_MODNAME of each files.

Kernel build system defines KBUILD_MODNAME automatically from each Makefile.
You can easily find below string from build command of each files of modules.

-D"KBUILD_MODNAME=KBUILD_STR(xxxxx)"
('xxxxx' is given module name)

This name xxxxx comes from Makefile.
Below is simple example.

[ in Makefile ]
xxxxx-y := a.o b.o c.o d.o

In above case, KBUILD_MODNAME of a.c, b.c, c.c and d.c becomes xxxxx.
This can be easily confirmed by checking command line of each objects – a.o, b.o, c.o and d.o.

[Kernel] Analyzing linux kernel Oops report easily…

In Linux, usually, kernel crashes with so-called Oops report.
This Oops report includes lots of useful information for debugging.

Therefore, I have seen lots of developer suffering from analyzing register, memory and stack dump in the report.
To analyze dumped information, memory information should be matched with source code.
But, this is not easy process.
So, I want to introduce the way to do this easily.

Main concept is, we can make tool to parse Oops report and pass these to debugging tool.
Here is introduction of my case.
I uses TRACE32 software – ARM simulator for debugging tool.
What I did is, implementing simple Perl script that parses Oops report and make cmm file that set register and memory information given by the report.
For example, auto generated cmm file is like this.

R.S cpsr 0x20000013
R.S r0 0x0
R.S r1 0x0
...
D.S 0xc035a248 %long 0xe3a02000
D.S 0xc035a24c %long 0xe3a03020
...

It’s time to use TRACE32 PowerView for ARM to analyze the report.
Launching t32marm with simulator mode -> Loading issued ‘vmlinux’ -> Runnig auto-generated cmm script
Finally, I can see stack frame with local variables and interpreted memory information by virtue of T32.

I’m sorry not to share parsing tool – Perl script – due to … as you know, something like legal issue… (I hate this.)
I hope this post is helpful for others…

[Kernel] SMP and IRQ – case (2011-Sep)

In SMP system, to save power, not all cpus are active if system is not heavy loaded.
But let’s image this case.
System is not heavy loaded – only cpu0 is active, but at some moment IRQ is issued very often in short time.
In this case, some of issued IRQs may be abandoned.

Let’s assume a IC does abnormal operation if issued interrupt is not handled by MPU and system status is like above.
Then, system works abnormally when it is not loaded, but system works well when it is loaded.
(This is opposite of usual case. Most case, system may do abnormal operation when it is loaded.)
default IRQ affinity is usually, masked for all cores – IRQ can be handled by any cpu.
And, more than one cpus are active when system is loaded. So, there is less chance for IRQ to be abandoned – these are several cpus to handle!

This case shows very interesting issues at system!

 

[Linux][Shell] Cleaning PATH environment variable.

With using terminal for a long time, PATH variable tends to be longer and longer due to duplicated path.
Here is simple sample script – with Perl – to resolve this.

# remove duplication at give PATH-format-string
unique_path() {
perl -w -e '
    my %path_hash;
    exit unless (defined $ARGV[0]);
    foreach $p (split (/\:/, $ARGV[0])) {
        unless (defined $path_hash{$p}) {
            $path_hash{$p} = 1;
            push @newpath, $p;
        }
    }
    print join ":", @newpath;
' $1
}
...(skip)...
PATH=$(unique_path "$PATH")
...(skip)

Done :-).

[Kernel] Potential bug for using jiffies – ex. schedule_timeout() – at Linux kernel.

There is function for sleep in kernel – ex. msleep(). And schedule_timeout() is used in those.
And, schedule_timeout() calculates time for expiration based on current jiffies.
But some functions disable local irq or irq for a while in it.
For example, printk does this – disabling local irq.
But, jiffies is updated based on local timer irq (In case of SMP, one defined core – usually cpu0 – is used.)
So, disabling local irq – for timer core – may prevent system from updating jiffies.
At this moment, calling schedule_timeout() leads to set timer which expiring time is earlier than it should be because jiffies are behind of real time.
So, for example, msleep(100) may wake up after 50ms at this scenario.
This is very dangerous.
But, actually, lots of code uses jiffies directly in kernel.
So, I’m not sure that all those codes are safe in case that jiffies is behind.
Anyway, here is my sample fix for this potential issue of schedule_timeout().
I couldn’t find any fix regarding this issue even in kernel-3.0.
So, I’m not sure I missed something.
But, as for me, this is definitely issue to consider when variable jiffies is directly used.
I hope that my sample fix regarding schedule_timeout is helpful for others.
(In my opinion, fundamentally, all codes that uses jiffies directly should be re-examined whether it is really safe or not in case that jiffies is behind.)

diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 6811f4b..6c89958 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -290,6 +290,8 @@ extern unsigned long preset_lpj;

 #endif

+extern unsigned long exact_jiffies(void);
+
 /*
  * Convert various time units to each other:
  */
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 56f87fa..37e7bbf 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -99,6 +99,32 @@ static ktime_t tick_init_jiffy_update(void)
        return period;
 }

+/**
+ * exact_jiffies - return real jiffies value
+ *
+ * You can't sure that value from %jiffies varaible is real current time.
+ * Jiffies may not be updated for a while due to several reasones.
+ * So, to get exact value, current ktime and %last_jiffies_update should be used
+ */
+unsigned long exact_jiffies(void)
+{
+       unsigned long exact = jiffies;
+       if (tick_period.tv64
+           && last_jiffies_update.tv64) {
+               unsigned long seq, ticks;
+               ktime_t delta;
+               do {
+                       seq = read_seqbegin(&xtime_lock);
+                       delta = ktime_sub(ktime_get(), last_jiffies_update);
+                       ticks = ktime_divns(delta, ktime_to_ns(tick_period));
+                       /* +1 to compensate loss at division */
+                       exact = jiffies + ticks + 1;
+               } while (read_seqretry(&xtime_lock, seq));
+       }
+       return exact;
+}
+EXPORT_SYMBOL_GPL(exact_jiffies);
+
 /*
  * NOHZ - aka dynamic tick functionality
  */
diff --git a/kernel/timer.c b/kernel/timer.c
index c4714a6..628a714 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1304,7 +1304,6 @@ void run_local_timers(void)
  * without sampling the sequence number in xtime_lock.
  * jiffies is defined in the linker script...
  */
-
 void do_timer(unsigned long ticks)
 {
        jiffies_64 += ticks;
@@ -1457,7 +1456,7 @@ signed long __sched schedule_timeout(signed long timeout)
                }
        }

-       expire = timeout + jiffies;
+       expire = timeout + exact_jiffies();

        setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);
        __mod_timer(&timer, expire, false, TIMER_NOT_PINNED);
@@ -1467,6 +1466,13 @@ signed long __sched schedule_timeout(signed long timeout)
        /* Remove the timer from the object tracker */
        destroy_timer_on_stack(&timer);

+       /*
+        * Reaching here means "timer interrupt is issued
+        *   and 'jiffies' is updated."
+        * So, 'jiffies' here is recently-updated-value
+        *   and 'jiffies' can be directly used
+        *   instead of using 'exact_jiffies()'
+        */
        timeout = expire - jiffies;

  out:

done.

[Kernel] Debugging/Controlling GPIO at user space on Linux Kernel.

To use sysfs, enable kernel config : CONFIG_GPIO_SYSFS
Core files related with this : gpiolib.c at Kernel
sysfs nodes can be found at /sys/class/gpio

[ Prerequisite ]
writing value to ‘/sys/class/gpio/export’ uses ‘gpio_request()’ function at gpiolib in kernel.
So, if given gpio is already requested by other owner, exporting is failed.
Therefore, gpio should not be owned by others in kernel to control gpio at user space.

[ How to use at user space ]
Assumption : current working directory is ‘/sys/class/gpio

#> echo [gpio num] > export
=> export give gpio to sysfs. gpioN link is newly created if gpio number is valid one.

#> cd gpioN
=> Then, several nodes (active_low, direction, value etc) can be found.
Writing or reading following nodes, is one of useful way to debug/control gpio at user space.
(attribute functions for each node are defined at gpiolib.c)

[ Detail Example ]

* at /sys/class/gpio
export, unexport : gpio number
#> echo 86 > export
#> echo 86 > unexport

* at /sys/class/gpio/gpioN
direction : in, out, low, high
value : 0, 1
edge : none, rising, falling, both
active_low : 0, 1
#> echo in > direction
#> echo 1 > value
#> echo both > edge

< See gpio.txt of Kernel document for details about each sysfs node. >

[Kernel] module & parameter initialization.

Linux kernel uses lot’s of sections to modularize it’s code structure easily.
In case of kernel module and parameter, following section is used.

[ Module ]
macro   : module_init()
section : device_initcall (section name : .initcall6.init) <see init.h>
[ Parameter ]
macro   : module_param_named(), module_param(), core_param() etc.
section : __param <see moduleparam.h>

core_param() macro works like other module parameter. But this is NOT for module BUT for kernel booting parameter.
Kernel parameter doesn’t have any prefix unlike other modules.
Module parameter’s name has <module name> as it’s prefix.
For example, parameter <param> of module <module> has name <module>.<param>
See source code for details.

KBUILD_MODNAME is preprocessor value for module name.
This is defined through complex script processing. See Makefile.lib, Makefile.mod* in scripts/.
But in most case, you can know it by intuition. That is,  name that seems like module name, is set as KBUILD_MODNAME.
(ex. <mod name>-y, <mod-name>-m in Makefile)
So, usually, deep analysis about above scripts are not required.

Note:
It’s possible that one object gets potentially linked into more than one module.
In that case KBUILD_MODNAME will be set to  foo_bar, where foo and bar are the name of the modules.

Module and parameter initialization.

[ Built-in module ]
module initialization : do_initcalls() <see 'main.c'> => initcall section is used
parameter sysfs node  : param_sysfs_init() -> param_sysfs_builtin() => __param section is used
[ Dynamic module ]
module & parameter initialization is done at system call
SYSCALL_DEFINE3(init_module, ...) => load_module()

Each parameter has permission mask. So, parameter value can be read or written at runtime through sysfs node.

/sys/module/<module name>/parameter/<parameter name>

But module parameter whose  permission is 0, is ignored at sysfs (Not shown at sysfs).
( See module_param_sysfs_setup(…) function. )