Thursday, May 19, 2011

iotop: Per Process I/O Usage | Linux Magazine

Monitoring the IO usage of individual processes on a system has been much easier with iotop. It also includes some interesting and very useful performance monitoring features.

iotop: Per Process I/O Usage | Linux Magazine


Friday, April 29, 2011

Receive Packet Steering (RPS) on Linux 2.6.35

This patch implements software receive side packet steering (RPS). RPS distributes the load of received packet processing across multiple CPUs. Problem statement: Protocol processing done in the NAPI context for received packets is serialized per device queue and becomes a bottleneck under high packet load. This substantially limits pps that can be achieved on a single queue NIC and provides no scaling with multiple cores. (lwn.net: Software receive packet steering)


If you want to find out whether RPS is working, you have to look at /proc/softirqs instead (eg. with watch -n1 cat /proc/softirqs):
                CPU0       CPU1
       HI:          0          0
    TIMER:  480622794  476948579
   NET_TX:   25311134   27075847     <-----
   NET_RX: 1388399338 4191697027     <-----
    BLOCK:    4632803          3
 BLOCK_IOPOLL:          0          0
  TASKLET:         21          4
    SCHED:  154913375  158601463
  HRTIMER:    1576760    2361409
      RCU:  421549961  407634645 

Enabling RPS specifically for a particular interface:

# cat /sys/class/net/eth0/queues/rx-0/rps_cpus 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000, 00000000,00000000,00000000,00000000,00000000,00000000,00000000  # echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus # cat /sys/class/net/eth0/queues/rx-0/rps_cpus 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000, 00000000,00000000,00000000,00000000,00000000,00000000,0000000f

Concept of Cache Line

cache line - The smallest unit of memory than can be transferred between the main memory and the L1/L2 cache.
Rather than reading a single word or byte from main memory at a time, each cache entry is usually holds a certain number of words, known as a "cache line" or "cache block" and a whole line is read and cached at once. This takes advantage of the principle of locality of reference: if one location is read then nearby locations (particularly following locations) are likely to be read soon afterward. It can also take advantage of page-mode DRAM which allows faster access to consecutive locations.
The cache line is generally fixed in size, typically ranging from 16 to 256 bytes. The effectiveness of the line size depends on the application, and cache circuits may be configurable to a different line size by the system designer. There are also numerous algorithms for dynamically adjusting line size in real time.

Tuesday, February 23, 2010

Coulomb Counter

One technique for battery capacity reporting relies on the coulomb counter. The principle of operation involved in coulomb counting is computing the difference between the coulombs injected into a battery and the coulombs taken out of the battery. The capacity of the battery is then reported by comparing the coulomb count relative to a reference coulomb count value that corresponds to maximum battery capacity. For instance, if the coulomb count of a battery is half of the reference value, the battery capacity is reported to be 50 percent. Other known existing techniques of battery capacity reporting are primarily based on measuring battery voltage.

Monday, February 22, 2010

Hints for writing a battery driver in linux

This was my very first driver development in linux, a battery/energy/power driver.

Linux kernel provides a power supply core driver located in drivers/power/. The core power supply driver includes power_supply_core.c, power_supply_sysfs.c.

This core driver includes a structure power_supply defined in include/linux/power_supply.h. Here is the snapshot of the structure

struct power_supply {
const char *name;
enum power_supply_type type;
enum power_supply_property *properties;
size_t num_properties;

char **supplied_to;
size_t num_supplicants;

int (*get_property)(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val);
void (*external_power_changed)(struct power_supply *psy);

/* For APM emulation, think legacy userspace. */
int use_for_apm;

/* private */
struct device *dev;
struct work_struct changed_work;

#ifdef CONFIG_LEDS_TRIGGERS
struct led_trigger *charging_full_trig;
char *charging_full_trig_name;
struct led_trigger *charging_trig;
char *charging_trig_name;
struct led_trigger *full_trig;
char *full_trig_name;
struct led_trigger *online_trig;
char *online_trig_name;
#endif
};

It also creates a class entry in /sys/class/power_supply/ to expose the properties to the user space from the kernel space. This can be achieved by filling appropriate data to the structure power_supply.

In simple words the battery/energy/power driver has to provide API or data and hook up with the core driver structure power_supply and register to the kernel core power supply driver. The rest of the part of exposing the driver data to the user space is taken care by the core driver.

Brief overview of the structure and means of hooking up to it.
The structre power_supply has 11 elements and 19 in case led in involved.
  1. name - refers to the name of the battery/energy/power driver. Should not involve white space and an entry by this name is being created in /sys/class/power_supply/
  2. type - specify the type. Can be either of the following defined in the enum power_supply_type(include/linux/power_supply.h)
  3. properties - this plays a very important role and is the most important of all. This is of type enum and includes the one defined in enum power_supply_property(defined in include/linux/power_supply.h)
  4. num_properties - number of properties. In the definition enum power_supply_properties there are 36 elements. The driver is free to have only the requiered elements among these 36 elements. This is mentioned in the above element properties and the count is num_properties.
  5. supplied_to - a meaningful string representing the name of the driver different from the first element name. This indicated as to for which device the supply is being provided.
  6. get_property - it is a function pointer. This function has a switch statement with the elements of properties (enum power_supply_property) as cases. The aim of this function is to provide/update your battery/energy/power driver parameters.
  7. external_power_supply_changed - a function pointer. This is a function that tell what has to be done if there is a change in power resource.
  8. changed_work - work function to update the parameters of the driver.
As already said the element properties(enum power_supplu_property) is the most important one. Here is the brief description
  • POWER_SUPPLY_PROP_STATUS - status of the device can be one of the following (POWER_SUPPLY_STATUS_UNKNOWN, POWER_SUPPLY_STATUS_CHARGING, POWER_SUPPLY_STATUS_DISCHARGING, POWER_SUPPLY_STATUS_NOT_CHARGING, POWER_SUPPLY_STATUS_FULL)
  • POWER_SUPPLY_PROP_HEALTH - battery health, can be one among(POWER_SUPPLY_HEALTH_UNKNOWN, POWER_SUPPLY_HEALTH_GOOD, POWER_SUPPLY_HEALTH_OVERHEAT, POWER_SUPPLY_HEALTH_DEAD, POWER_SUPPLY_HEALTH_OVERVOLTAGE, POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, POWER_SUPPLY_HEALTH_COLD)
  • POWER_SUPPLY_PROP_PRESENT - this can have a boolean value. If the device is present the value should be one, else zero
  • POWER_SUPPLY_PROP_ONLINE - this can have a boolean value. If this device is doing some work then its value should be one. For ex consider the device as AC/Mains, if the charging is through Mains/AC then its value is one.
  • POWER_SUPPLY_PROP_TECHNOLOGY - represents the technology of the battery(POWER_SUPPLY_TECHNOLOGY_UNKNOWN, POWER_SUPLY_TECHNOLOGY_NiMH, POWER_SUPLY_TECHNOLOGY_LION, POWER_SUPPLY_TECHNOLOGY_LIPO, POWER_SUPPLY_TECHNOLOGY_LiFe, POWER_SUPPLY_TECHNOLOGY_NiCd, POWER_SUPPLY_TECHNOLOGY_LiMn)
  • POWER_SUPPLY_PROP_VOLTAGE_MAX - the maximum threshold voltage of the device(in uV)
  • POWER_SUPPLY_PROP_VOLTAGE_MIN - the lower threshold voltage of the device upto which the device is powered on.(in uV)
  • POWER_SUPPLY_PROP_VOLTAGE_NOW - present voltage of the device(in uV)
  • POWER_SUPPLY_PROP_VOLTAGE_AVG - average voltage of the device(in uV)
  • POWER_SUPPLY_PROP_CURRENT_NOW - present current of the device(in uA)
  • POWER_SUPPLY_PROP_CURRENT_AVG - average current(in uA)
  • POWER_SUPPLY_PROP_CHARGE_NOW - amount of charge in the device(in uAh)
  • POWER_SUPPLY_PROP_CHARGE_AVG - average charge in the device(in uAh)
  • POWER_SUPPLY_PROP_CAPACITY - the present capacity of the battery in terms of percentage. This is being used by application to graphically show the current capacity of the battery.
  • POWER_SUPPLY_PROP_TEMP - present temperature of the device in deg cel

Wednesday, November 25, 2009

CCS v4 Linux Aware Debugging

CCS v4 Linux Aware Debugging

Below are the steps for debugging linux running on beagleboard using CCS v4.

My target Environment:
MMC Card: U-boot.bin, uImage, ramdisk,gz, MLO, noraml.src

After compiling the kernel do a objdump with the linux image i.e.vmlinux
arm-none-guneabi-objdump -D vmlinux >> vmlinux.obj

Insert MMC card and power on the target board. Now the target board is up with linux
Open CCS v4
Tools-> New target configuration
After configuring the debugger and target go to Advanced tab and under each core delete "initialization script" whihc is a GEL file.
Target->Launch TI debugger
Target->Load Symbols (browse to vmlinux)
On the debug tag right click on the emulator -> Edit Source lookup (browse to vmlinux.obj and add the linux source dir)

Now the various process and threads appear on the debug window.
To tarace the kernel flow from boot apply breakpoint at 0x80008000 and Target->Reset->System Reset

Friday, May 22, 2009

Debugging Linux on CCS

Though Linux cant be debugged using CCS, by doing some changes to the memory, CCS can be used to debug linux untill is MMC is turned ON. This is most required in board bring up projects.

On compiling linux code we get the image vmlinux in elf32 format. In order to lead this image through CCS this needs to be converted to the .out type.
The kernel image vmlinux, has a start address, VMA and LMA set to 0xC0008000. But 0xC0008000 does not map to a valid loadable address in the DaVinci/OMAP system. So, when vmlinux image is tried to download via CCS on the target, CCS complainsthat the memory map of the target does not match the program address. Hence vmlinux cannot be downloaded to the target directly.To circumvent this problem, the LMA of the vmlinux image is changed from 0xC0008000 to 0x80008000 which maps correctly into the target system memory. This conversion of vmlinux can be done by the script conv-elf-to-out.sh.This also helps in direct debugging of the kernel with ICE without necessarily flashing the kernel into the NOR flash.

conv-elf-to-out.sh
#!/bin/sh
# This shell script converts given input file of elf32-littlearm

# format to output file which is also elf32-littlearm format but
# the LMA (load memory addresses) are shifted by 0x40000000 so
# that it can be downlaodable by CCS on the target. This script
# is used to mainly, convert compiled linux image vmlinux to
# downloadable image vmlinux.out whose LMA starts from 0x80008000
usage()

{
echo ""
echo " Incomplete command line .. missing inputs " ;
echo " Usage : sh conv-elf-to-out.sh " ;
echo " Example : sh conv-elf-to-out.sh /home/linux/vmlinux /home/linux/vmlinux.out" ;
echo ""
exit 0;
}
if [ -z "$1" -o -z "$2" ] ;

then usage
fi
if [ ! -f "$1" ] ;

then echo " File not found : $1 "
exit 0;
fi
echo "Converting "$1" to "$2" "
arm-none-linux-gnueabi-objcopy $1 $2
arm-none-linux-gnueabi-objcopy $(arm_v5t_le-objdump -h $2 awk '$1~/^[0-9]/ && $5 {print $2}' while read s; do echo --change-section-lma $s-0x40000000; done) $2
arm-none-linux-gnueabi-objcopy --set-start 0x80008000 $2
echo "Changed the LMA of ""$1"" to 0x80008000 in ""$2"" "

Note: Once the MMU is turned ON, CCS can further not be used to debug, but can be used to trace the code in assembly code. In order to do this disable memory mapping by Options->Memory Map and Disable Memory Map