diff options
| author | Manuel Traut <manut@linutronix.de> | 2010-10-13 05:07:23 +0200 |
|---|---|---|
| committer | Manuel Traut <manut@linutronix.de> | 2010-10-13 05:07:23 +0200 |
| commit | 533c32df10d6dcd42d0d3701c03c571ad6839b6f (patch) | |
| tree | 8bb13210eba3f5535ed388ff617e980f03cf1f05 | |
| parent | c9cbceab01d4afa983dbfa7ee12c5d5e438b78f5 (diff) | |
| parent | 5c4103df94f354dc37e8b2f072336b71e46e1921 (diff) | |
Merge branch 'master' of ssh://tglx.de/home/linutronix/git/schulung
| -rw-r--r-- | linux-basics/Makefile | 2 | ||||
| -rw-r--r-- | linux-basics/linux-mm-basics/Makefile | 9 | ||||
| -rw-r--r-- | linux-basics/linux-mm-basics/handout_linux-mm-basics_en.tex | 17 | ||||
| -rw-r--r-- | linux-basics/linux-mm-basics/hints_linux-mm-basics_en.tex | 25 | ||||
| -rw-r--r-- | linux-basics/linux-mm-basics/pres_linux-mm-basics_en.tex | 253 | ||||
| -rw-r--r-- | realtime/rt-app-basics/Makefile | 10 | ||||
| -rw-r--r-- | realtime/rt-app-basics/pres_rt-app-basics_en.tex | 308 |
7 files changed, 623 insertions, 1 deletions
diff --git a/linux-basics/Makefile b/linux-basics/Makefile index ab3b327..10d4fc6 100644 --- a/linux-basics/Makefile +++ b/linux-basics/Makefile @@ -1,4 +1,4 @@ -SUBDIRS = boot-process filesystem-structure important-tools linux-processes sh-programming what-is-linux +SUBDIRS = boot-process filesystem-structure important-tools linux-processes sh-programming what-is-linux linux-mm-basics all clean:: for dir in $(SUBDIRS) ; do \ diff --git a/linux-basics/linux-mm-basics/Makefile b/linux-basics/linux-mm-basics/Makefile new file mode 100644 index 0000000..5a7cfbe --- /dev/null +++ b/linux-basics/linux-mm-basics/Makefile @@ -0,0 +1,9 @@ +all: + pdflatex pres_linux-mm-basics_en.tex + pdflatex hints_linux-mm-basics_en.tex + pdflatex handout_linux-mm-basics_en.tex + pdflatex handout_linux-mm-basics_en.tex + +clean: + rm -f *.aux *.log *.pdf *.log *.snm *.toc *.vrb *.nav *.out + diff --git a/linux-basics/linux-mm-basics/handout_linux-mm-basics_en.tex b/linux-basics/linux-mm-basics/handout_linux-mm-basics_en.tex new file mode 100644 index 0000000..4c391b2 --- /dev/null +++ b/linux-basics/linux-mm-basics/handout_linux-mm-basics_en.tex @@ -0,0 +1,17 @@ +\documentclass{article} +\usepackage{german} +\usepackage[utf8]{inputenc} + +\begin{document} + +\section*{Titel} + +\subsection*{Abschnitt1} + +Text + +\subsection*{Abschnitt2} + +Text + +\end{document} diff --git a/linux-basics/linux-mm-basics/hints_linux-mm-basics_en.tex b/linux-basics/linux-mm-basics/hints_linux-mm-basics_en.tex new file mode 100644 index 0000000..b2b8a2b --- /dev/null +++ b/linux-basics/linux-mm-basics/hints_linux-mm-basics_en.tex @@ -0,0 +1,25 @@ +\documentclass{article} +\usepackage{german} +\usepackage[utf8]{inputenc} + +\begin{document} + +\section*{Block \lq Linux-Prozesse\rq} + +\subsection*{Lernziele} +\begin{itemize} +\item Begriffe Prozess und Thread +\item Bedeutung von User-/Group-IDs, Executable-Flag +\item Verstehen, wie Prozesse unter Linux erzeugt werden +\item Kennenlernen der wichtigsten Tools +\end{itemize} + +\subsection*{Unterrichts-Ablauf} + +Hinweise zur Präsentation, Zeitplanung, etc. + +\subsection*{Ăœbungen bei vorhandener Hardware} + +Tools ps, top, kill + +\end{document} diff --git a/linux-basics/linux-mm-basics/pres_linux-mm-basics_en.tex b/linux-basics/linux-mm-basics/pres_linux-mm-basics_en.tex new file mode 100644 index 0000000..8ff0da7 --- /dev/null +++ b/linux-basics/linux-mm-basics/pres_linux-mm-basics_en.tex @@ -0,0 +1,253 @@ +\documentclass{beamer} +\usetheme{linutronix} +\usepackage{german} +\usepackage[utf8]{inputenc} +\usepackage{pgf} +\usepackage{graphicx} + +\title{Linux Memory Management basics} +\institute{Linutronix GmbH} + +\begin{document} + +\maketitle +\begin{frame} +\frametitle{Overview} +\tableofcontents +\end{frame} + +\section{Basics} +\subsection{Overview} +\begin{frame} +\frametitle{Overview} +\begin{itemize} +\item over-committing +\item Copy-On-Write +\item Page relocation +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{over-committing} +\begin{itemize} +\item Comparable to those low-cost airlines ;) +\pause +\item ...selling more tickets than available seats +\pause +\item ...hoping not everyone will come ;) +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{over-commit settings} +\begin{verbatim} +/proc/sys/vm/overcommit_memory +\end{verbatim} +Possible settings are: +\begin{itemize} +\item 0: Heuristic overcommit handling (default) +\item 1: Always overcommit +\item 2: Don't overcommit +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{The OOM Killer} +...is invoked if you ask for more memory than available.\\ +\pause +\textbf{Result}: The kernel kills a task +\end{frame} + +\begin{frame} +\frametitle{Copy-On-Write} +\begin{itemize} +\item completely transparently for userspace +\item you don't need the same data twice +\item only updated if one virtual memory area is updated +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{Page relocation} +\begin{itemize} +\item AKA paging or swapping +\item Linux can move a page to / from swap +\item also completely transparently for userspace +\end{itemize} +\end{frame} + +\subsection{The stack} +\begin{frame} +\frametitle{The stack} +\begin{itemize} +\item Grows top - down +\item Configurable stack size +\item Stack grows on demand. Access beyond current size ends up in a +''Stackfault'' which is handled by the kernel +\item ulimit -a shows the current maximum stack size +\item ulimit -s \emph{size} sets the maximum stack size +\item Default maximum stack size is 8MiB +\end{itemize} +\end{frame} + +\subsection{The heap} + +\begin{frame} +\frametitle{The heap: Userland handling} +\begin{itemize} +\item Memory is allocated using malloc() +\item Memory is freed using free() +\item malloc() uses the mmap() and the sbrk() system calls +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{The heap: Userland handling} +\begin{itemize} +\item For small junks, malloc() allocates memory from the heap and adjusts the +size using sbrk() +\item For larger blocks (larger than defined in MMAP\_THRESHOLD) the memory is +allocated as private, anonymous mapping +\item MMAP\_THRESHOLD is 128kb by default +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{malloc()} +\begin{itemize} +\item Keep over-commit in mind! +\item If over-commit is enabled: A non-null return value from malloc() doesn't +guarantee that the memory really is available. +\end{itemize} +\end{frame} + +\section{Do's and Dont's} +\subsection{The heap} +% fragmentation +% check return value +% ulimit (limit memory consumption) +\begin{frame} +\frametitle{Return value} +Always check malloc's return value!! +\end{frame} + +\begin{frame} +\frametitle{How to avoid heap fragmentation} +\begin{itemize} +\item GLIBCs malloc() itself tries to avoid fragmentation +\item The allocator can't avoid fragmentation caused by a bad application +design! +\item Try to re-use memory pools +\item free memory you don't need anymore! +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{How to limit memory consumption} +ulimit: +\begin{itemize} +\item ulimit -d sets a limit for the data segment +\item ulimit -v sets a limit for the virtual memory +\item Check limits with ulimit -a +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{ulimit example} +\scriptsize +\begin{verbatim} +$ ulimit -a +core file size (blocks, -c) 0 +data seg size (kbytes, -d) unlimited +scheduling priority (-e) 20 +file size (blocks, -f) unlimited +pending signals (-i) 16382 +max locked memory (kbytes, -l) 64 +max memory size (kbytes, -m) unlimited +open files (-n) 1024 +pipe size (512 bytes, -p) 8 +POSIX message queues (bytes, -q) 819200 +real-time priority (-r) 0 +stack size (kbytes, -s) 8192 +cpu time (seconds, -t) unlimited +max user processes (-u) unlimited +virtual memory (kbytes, -v) unlimited +file locks (-x) unlimited +\end{verbatim} +\end{frame} + +\section{Realtime} +\subsection{General} +\begin{frame}[fragile] +\frametitle{Locking the memory} +\begin{verbatim} +/* Lock memory */ +if(mlockall(MCL_CURRENT|MCL_FUTURE) == -1) { + perror("mlockall failed"); + exit(-2); +} +\end{verbatim} +\end{frame} +\subsection{Stack} +\begin{frame}[fragile] +\frametitle{Stack prefaulting} +\begin{verbatim} +#define MAX_SAFE_STACK (8*1024) + +void stack_prefault(void) { + unsigned char dummy[MAX_SAFE_STACK]; + + memset(&dummy, 0, MAX_SAFE_STACK); + return; +} +\end{verbatim} +\end{frame} + +\subsection{Heap} +\begin{frame} +\frametitle{Allocations from Realtime context} +\begin{itemize} +\item If possible, avoid memory allocations from Realtime context +\item Try to use a pre-allocated buffer +\end{itemize} +\end{frame} + + +\begin{frame}[fragile] +\frametitle{Disable malloc trimming and mmap usage} +\begin{verbatim} +mallopt(M_TRIM_THRESHOLD, -1); +mallopt(M_MMAP_MAX, 0); +\end{verbatim} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Reserve process memory} +\begin{verbatim} +static void reserve_process_memory(int size) +{ + int i; + char *buffer; + + buffer = malloc(size); + + /* Touch each page in this piece of + * memory to get it mapped into RAM */ + for (i = 0; i < size; i += sysconf(_SC_PAGESIZE)) + buffer[i] = 0; + + free(buffer); +} +\end{verbatim} +\end{frame} + +\section*{sources} +\begin{frame} +\frametitle{sources} +\begin{thebibliography}{1} +\bibitem{mmm} http://cftw.wordpress.com/2009/11/02/introduction-to-the-linux-memory-management/ +\bibitem{mmm} http://rt.wiki.kernel.org/ +\end{thebibliography} +\end{frame} + +\end{document} diff --git a/realtime/rt-app-basics/Makefile b/realtime/rt-app-basics/Makefile new file mode 100644 index 0000000..c525117 --- /dev/null +++ b/realtime/rt-app-basics/Makefile @@ -0,0 +1,10 @@ +all: + pdflatex pres_rt-app-basics_de.tex + pdflatex pres_rt-app-basics_en.tex + pdflatex hints_rt-app-basics_de.tex + pdflatex handout_rt-app-basics_de.tex + pdflatex handout_rt-app-basics_de.tex + +clean: + rm -f *.aux *.log *.pdf *.log *.snm *.toc *.vrb *.nav *.out + diff --git a/realtime/rt-app-basics/pres_rt-app-basics_en.tex b/realtime/rt-app-basics/pres_rt-app-basics_en.tex new file mode 100644 index 0000000..6179851 --- /dev/null +++ b/realtime/rt-app-basics/pres_rt-app-basics_en.tex @@ -0,0 +1,308 @@ +\documentclass[11pt]{beamer} + +%\usepackage{ngerman} +\usepackage{times} +\usepackage{graphicx} +\usepackage{pgf,pgfarrows,pgfnodes,pgfautomata,pgfheaps} +\usepackage{amsmath,amssymb} +\usepackage[latin1]{inputenc} +\usepackage{listings,color} +\definecolor{lbcolor}{RGB}{255,210,150} +\lstset{ + language=C, + numbers=left, + stepnumber=1, + numbersep=5pt, + numberstyle=\tiny, + breaklines=true, + breakautoindent=true, + postbreak=\space, + tabsize=2, + basicstyle=\ttfamily\footnotesize, + showspaces=false, + showstringspaces=false, + extendedchars=true, + backgroundcolor=\color{lbcolor}, + keywordstyle=\bf , + commentstyle=\color{green}, + stringstyle=\color{red} +} + +\mode<presentation> +{ + \usetheme{linutronix} +} + +% on the following slides, include icon in the left sidebar +\def\lximg{/usr/share/lx/icons/fueller.png} + +\title{Realtime application development using Linux-RT\_PREEMPT} +\institute{Linutronix GmbH} + +\begin{document} + +\frame{ \titlepage } + +% stop displaying 'fueller.png' on the following slides +\def\lximg{none} + +%\AtBeginSection[] +%{ +% \begin{frame}<beamer> +% \tableofcontents[currentsection,currentsubsection] +% \end{frame} +%} + +\AtBeginSubsection[] +{ + \begin{frame}<beamer> + \tableofcontents[currentsection,currentsubsection] + \end{frame} +} + +\begin{frame} + \tableofcontents +\end{frame} + +\section{Basics} +\begin{frame}[fragile] +\frametitle{Check sched\_rt\_runtime\_us!!} +\begin{verbatim} +echo -1 > \ +/proc/sys/kernel/sched_rt_runtime_us +\end{verbatim} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Setting RT priority} +\begin{lstlisting} +/* Set realtime priority */ +struct sched_param param; +param.sched_priority = 99; +if (sched_setscheduler(0, SCHED_FIFO, ¶m) < 0) + perror("Can't set scheduling policy"); +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Lock memory} +\begin{lstlisting} +if (mlockall(MCL_CURRENT | MCL_FUTURE)) + perror("mlockall failed:"); +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Configure malloc() behaviour} +\begin{lstlisting} +/* Turn off malloc trimming.*/ +mallopt(M_TRIM_THRESHOLD, -1); + +/* Turn off mmap usage. */ +mallopt(M_MMAP_MAX, 0); +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Reserve process memory} +\begin{lstlisting} +buffer = malloc(MSIZE); + +for (i = 0; i < MSIZE; i += sysconf(_SC_PAGESIZE)) + buffer[i] = 0; + +free(buffer); +\end{lstlisting} +\textbf{BUT: Please avoid memory allocation from realtime context!!} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Prefault the stack (per Thread!)} +\begin{lstlisting} +/* Prove that this thread is behaving well */ +for (i = 0; i < SAVE_STACK_SIZE; i += sysconf(_SC_PAGESIZE)) + buffer[i] = i; +\end{lstlisting} +\end{frame} + +\section{Clocks and Timers} + +\begin{frame} +\frametitle{Clocks: Basic} +\begin{itemize} +\item Use POSIX! +\item clock\_getres() +\item clock\_gettime() +\item clock\_settime() +\item clock\_nanosleep() +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{Clock types} +\begin{itemize} +\item CLOCK\_MONOTONIC: Clock that cannot be set and represents monotonic time +since some unspecified starting point. +\item CLOCK\_REALTIME: System-wide real-time clock. Can be set (by NTP, User, +...)! +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Getting the time} +\begin{lstlisting} +struct timespec tv; +struct timespec res; + +clock_gettime(CLOCK_MONOTONIC, &tv); + +clock_getres(CLOCK_MONOTONIC, &res); +\end{lstlisting} +\end{frame} + +\begin{frame} +\frametitle{Cyclic tasks} +\begin{itemize} +\item Use clock\_nanosleep! +\item Do not use signals! +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Example: 1 / 2} +\begin{lstlisting} +#include <stdio.h> +#include <time.h> + +#define CYCLE_TIME_NS (100 * 1000 * 1000) +#define NSEC_PER_SEC 1000000000 + +void norm_ts(struct timespec *tv) +{ + if(tv->tv_nsec > NSEC_PER_SEC) { + tv->tv_sec++; + tv->tv_nsec -= NSEC_PER_SEC; + } +} +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Example: 2 / 2} +\begin{lstlisting} +int main(void) +{ + struct timespec tv; + + clock_gettime(CLOCK_MONOTONIC, &tv); + do { + /* Do the work */ + + /* Wait for next cycle */ + tv.tv_nsec += CYCLE_TIME_NS; + norm_ts(&tv); + clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &tv, NULL); + } while(1); +} +\end{lstlisting} +\end{frame} + +\section{Locking} +\begin{frame} +\frametitle{Locking} +\begin{itemize} +\item Use pthread\_mutexes +\item Activate PRIO\_INHERIT +\item Activate robustness +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Locking example} +\begin{lstlisting} +pthread_mutex_t master_lock; +pthread_mutexattr_t mattr; + +pthread_mutexattr_init(&mattr); +pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); +pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT); +pthread_mutexattr_setrobust_np(&mattr, PTHREAD_MUTEX_ROBUST_NP); +pthread_mutex_init(&master_lock, &mattr); + +pthread_mutex_lock(&master_lock); +/* Do critical work */ +pthread_mutex_unlock(&master_lock); + +pthread_mutex_destroy(&master_lock); +\end{lstlisting} +\end{frame} + +\section{Signalling} +\begin{frame} +\frametitle{Signalling mechanisms} +\begin{itemize} +\item Do not use signals +\item Use pthread\_cond\_vars +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{pthread\_cond\_var: Initialization 1 / 2} +\begin{lstlisting} +pthread_mutexattr_t mattr; +pthread_condattr_t cattr; +pthread_cond_t cond; +pthread_mutex_t mutex; + +pthread_mutexattr_init (&mattr); +pthread_mutexattr_setpshared (&mattr, PTHREAD_PROCESS_SHARED); +pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT); +pthread_mutexattr_setrobust_np(&mattr, PTHREAD_MUTEX_ROBUST_NP); +pthread_mutex_init (&mutex, &mattr); +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{pthread\_cond\_var: Initialization 2 / 2} +\begin{lstlisting} +pthread_condattr_init (&cattr); +pthread_condattr_setpshared (&cattr, PTHREAD_PROCESS_SHARED); +pthread_cond_init (&cond, &cattr); +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{pthread\_cond\_var: Send signal} +\begin{lstlisting} +/* Send signal */ +pthread_mutex_lock(&mutex); +/* Do the homework */ +/* ... */ +pthread_cond_broadcast (&cond); +pthread_mutex_unlock(&mutex); +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{pthread\_cond\_var: Wait for signal} +\begin{lstlisting} +/* Wait for signal */ +pthread_mutex_lock(&mutex); +pthread_cond_wait (&cond, &mutex); +/* -> We've been signalled */ +pthread_mutex_unlock(&mutex); +\end{lstlisting} +\end{frame} + +\section*{sources} +\begin{frame} +\frametitle{sources} +\small +\begin{thebibliography}{1} +\bibitem{rt1} https://rt.wiki.kernel.org/ +\bibitem{rt2} https://rt.wiki.kernel.org/index.php/ Dynamic\_memory\_allocation\_example +\bibitem{rt3} https://rt.wiki.kernel.org/index.php/ Threaded\_RT-application\_with\_memory\_locking\_and\_stack\_handling\_example +\end{thebibliography} +\end{frame} + +\end{document} |
