Saturday, November 21, 2015

When does a Page Fault occur?

When does a Page Fault occur? Why ?




Page Fault generation




#include 
#include 
#include 
#include 
#include 

#define CHUNK_SIZE (20 * 1024 * 1024)
#define CHUNK_NUM 100
#define CHUNKS_COMMIT 7

int main(int arg, char **argv)
{
  int i,j;
  void *chunks[CHUNK_NUM];
  unsigned long totaltime = 0;
  
  printf("Program start\n");
 
  for (i=0; i



http://www.hanbit.co.kr/ebook/ebookmain.html

http://www.hanbit.co.kr/network/view.html?bi_id=1108

http://www.hanbit.co.kr/network/view.html?bi_id=1062

ARM Linux Interrupts Code Flow

ARM Vector Table vector_irq         -> Interrupt Dispatcher vector_dabt      -> Data Abort Dispatcher vector_pabt      -> Perfetch Abort Dispatcher vector_und       -> Undefined Instruction Dispatcher vector_fiq        -> Fast Interrupt Dispatcher vector_addrexcptn   -> Address Exception Dispatcher
Once an exception occurs , one of the above functions gets called.
IRQ Exceptions:
From there ,
/* Assembly Code */
vector_irq   ->> Depending on the ARM mode call the corresponding function
irq_svc
irq_handler
arch_irq_handler_default(arch/arm/kernel) ->> get_irqnr_preamble(arch/arm/mach-omap2) -> set Soc Specific irq base ->>  get_irqnr_and_base -> Check Pending Interrupts /* C Code */ asm_do_IRQ ->> routine called with r0 = irq number, r1 = struct pt_regs *
Data Aborts: Control Processor Register is CP15 DFSR & DFAR Register. vector_dabt(called from ROM code) ( __dabt_svc | __dabt_usr ) do_DataAbort ( do_translation_fault | do_page_fault | do_sect_fault | )
Prefetch Aborts: Control Processor Register is CP15 IFSR & IFAR Register. vector_pabt(called from ROM code) ( __pabt_svc | __pabt_usr ) do_PrefetchAbort ( do_translation_fault | do_page_fault | do_sect_fault | )
List of Instruction Faults static struct fsr_info fsr_info[] = {         { do_bad,               SIGBUS,  0,             "unknown 0"                     },         { do_bad,               SIGBUS,  0,             "unknown 1"                     },         { do_bad,               SIGBUS,  0,             "unknown 2"                     },         { do_bad,               SIGBUS,  0,             "unknown 3"                     },         { do_bad,               SIGBUS,  0,             "reserved translation fault"    },         { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 1 translation fault"     },         { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 2 translation fault"     },         { do_page_fault,        SIGSEGV, SEGV_MAPERR,   "level 3 translation fault"     },         { do_bad,               SIGBUS,  0,             "reserved access flag fault"    },         { do_bad,               SIGSEGV, SEGV_ACCERR,   "level 1 access flag fault"     },         { do_bad,               SIGSEGV, SEGV_ACCERR,   "level 2 access flag fault"     },         { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 3 access flag fault"     },         { do_bad,               SIGBUS,  0,             "reserved permission fault"     },         { do_bad,               SIGSEGV, SEGV_ACCERR,   "level 1 permission fault"      },         { do_sect_fault,        SIGSEGV, SEGV_ACCERR,   "level 2 permission fault"      },         { do_page_fault,        SIGSEGV, SEGV_ACCERR,   "level 3 permission fault"      },         { do_bad,               SIGBUS,  0,             "synchronous external abort"    },         { do_bad,               SIGBUS,  0,             "asynchronous external abort"   },         { do_bad,               SIGBUS,  0,             "unknown 18"                    },         { do_bad,               SIGBUS,  0,             "unknown 19"                    },         { do_bad,               SIGBUS,  0,             "synchronous abort (translation table walk)" },         { do_bad,               SIGBUS,  0,             "synchronous abort (translation table walk)" },         { do_bad,               SIGBUS,  0,             "synchronous abort (translation table walk)" },         { do_bad,               SIGBUS,  0,             "synchronous abort (translation table walk)" },         { do_bad,               SIGBUS,  0,             "synchronous parity error"      },         { do_bad,               SIGBUS,  0,             "asynchronous parity error"     },         { do_bad,               SIGBUS,  0,             "unknown 26"                    },         { do_bad,               SIGBUS,  0,             "unknown 27"                    },         { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },         { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },         { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },         { do_bad,               SIGBUS,  0,             "synchronous parity error (translation table walk" },         { do_bad,               SIGBUS,  0,             "unknown 32"                    },         { do_bad,               SIGBUS,  BUS_ADRALN,    "alignment fault"               },         { do_bad,               SIGBUS,  0,             "debug event"                   },         { do_bad,               SIGBUS,  0,             "unknown 35"                    },
        { do_bad,               SIGBUS,  0,             "unknown 36"                    },
        { do_bad,               SIGBUS,  0,             "unknown 37"                    },
        { do_bad,               SIGBUS,  0,             "unknown 38"                    },
        { do_bad,               SIGBUS,  0,             "unknown 39"                    },
        { do_bad,               SIGBUS,  0,             "unknown 40"                    },
        { do_bad,               SIGBUS,  0,             "unknown 41"                    },
        { do_bad,               SIGBUS,  0,             "unknown 42"                    },
        { do_bad,               SIGBUS,  0,             "unknown 43"                    },
        { do_bad,               SIGBUS,  0,             "unknown 44"                    },
        { do_bad,               SIGBUS,  0,             "unknown 45"                    },
        { do_bad,               SIGBUS,  0,             "unknown 46"                    },
        { do_bad,               SIGBUS,  0,             "unknown 47"                    },
        { do_bad,               SIGBUS,  0,             "unknown 48"                    },
        { do_bad,               SIGBUS,  0,             "unknown 49"                    },
        { do_bad,               SIGBUS,  0,             "unknown 50"                    },
        { do_bad,               SIGBUS,  0,             "unknown 51"                    },
        { do_bad,               SIGBUS,  0,             "implementation fault (lockdown abort)" },
        { do_bad,               SIGBUS,  0,             "unknown 53"                    },
        { do_bad,               SIGBUS,  0,             "unknown 54"                    },
        { do_bad,               SIGBUS,  0,             "unknown 55"                    },
        { do_bad,               SIGBUS,  0,             "unknown 56"                    },
        { do_bad,               SIGBUS,  0,             "unknown 57"                    },
        { do_bad,               SIGBUS,  0,             "implementation fault (coprocessor abort)" },
        { do_bad,               SIGBUS,  0,             "unknown 59"                    },
        { do_bad,               SIGBUS,  0,             "unknown 60"                    },
        { do_bad,               SIGBUS,  0,             "unknown 61"                    },
        { do_bad,               SIGBUS,  0,             "unknown 62"                    },
        { do_bad,               SIGBUS,  0,             "unknown 63"                    },
};

Interprocessor Interrupts

IPIs are used to maintain synchronisation between the processors. For example, if a kernel page table entry changes, both processors must either flush their TLBs or invalidate that particular page table entry. Whichever processor changed the mapping knows to do this automatically, but the other processor does not; therefore, the processor which changed the mapping must send an IPI to the other processor to tell it to flush its TLB or invalidate the page table entry.
Using the local APIC, you can send interrupts to all processors, all processors but the one sending the interrupt, or a specific processor or logical address as well as self-interrupts. To send an IPI, write the destination APIC ID, if needed, into the high word of the ICR, then write the low word of ICR with the destination shorthand and interrupt vector set to send the IPI. Be sure to wrap these functions in spinlocks. You might want to turn off interrupts as well while sending IPIs. 31  Private nIRQ - Each CPU only sees its own legacy nIRQ pin 30  Private watchdog - Each CPU has its own watchdog timer 29  Private timer - Each CPU has its own timer 28:16  Spare - available for future private peripherals 15:0    Private inter-processor interrupts - See below Inter-processor interrupts (IPI) can, for example, be used for interrupt-driven communication between CPUs in an SMP system. The GIC implements IPI using 16 software interrupts. To generate an IPI, an MPCore CPU must write to the primary GIC's Software Interrupt register specifying an interrupt ID in the range 0 to 15 and which CPU(s) will receive the interrupt.
Technique
Recommended for
Not recommended for
a) Uncached mappings
Infrequently or sparsely accessed DMA data blocks
Simplest implementation
Correctness/reliability
Intensively accessed DMA blocks will not benefit from caching, in which case performance can suffer.
b) Set affinity
Minimizing cache line migration overheads
In complex applications, a manual procedure will be required to map the IRQ part of device drivers and user processes to CPUs.  Thorough testing will be required.
In complex applications, the enforced mapping of processes to CPUs might mean that the maximum aggregate performance is not achievable due to unbalanced CPU loading.
c) Read for ownership
Small DMA data blocks.
Can be done by OS kernel
Large DMA data blocks – must read/write completely – will cause extra memory traffic and potentially thrash L1 cache.
d) Broadcast of cache maintenance operations
Can be done by OS kernel
Currently done by Linux 2.6.28-arm1
Small DMA blocks – overhead of synchronous IPI is likely to be significant.
Performance – scheduling of IPI depends on IRQ loading –  process blocks until all CPUs have responded.

Thursday, November 19, 2015

Monday, November 16, 2015

Saturday, November 14, 2015

QCOM RPM SMEM :)

Generic ARM debug modes and symbols and Address space maps ::



https://lwn.net/Articles/614224/

soc: qcom: Add device tree binding for SMEM
  soc: qcom: Add device tree binding for SMD
  mfd: devicetree: bindings: Add Qualcomm SMD based RPM DT binding
  soc: qcom: Add Shared Memory Manager driver
  soc: qcom: Add Shared Memory Driver
  mfd: qcom-smd-rpm: Driver for the Qualcomm RPM over SMD
  regulator: qcom-smd-rpm: Regulator driver for the Qualcomm RPM