Linux Kernel Development (LKD)

Similar documents
Linux Kernel Development (LKD)

Linux Kernel Development (LKD)

Linux Kernel Development (LKD)

SFO The Linux Kernel Scheduler. Viresh Kumar (PMWG)

Linux Task Scheduling

Linux Scheduler. Minsoo Ryu. Department of Computer Science and Engineering. Hanyang University. Real-Time Computing and Communications Lab.

Linux Kernel Development (LKD)

Linux Task Scheduling

Periodic scheduler for Linux OS. Mike Athanasakis Operating System TA Winter

Loadable Kernel Module

Thread and Synchronization

Operating Systems 16 - CS 323 Assignment #2

Virtual File System (VFS) Implementation in Linux. Tushar B. Kute,

CS 423 Operating System Design: Introduction to Linux Kernel Programming (MP1 Q&A)

1 #include <linux/module.h> 2 #include <linux/sched.h> 3 #include <linux/interrupt.h> 4 #include <linux/init.h> 5 #include <linux/kernel.

Linux Device Drivers Interrupt Requests

7.3 Simplest module for embedded Linux drivers

PROCESS MANAGEMENT Operating Systems Design Euiseong Seo

ASE++ : Linux Kernel Programming

CS5460/6460: Operating Systems. Lecture 24: Device drivers. Anton Burtsev April, 2014

/dev/hello_world: A Simple Introduction to Device Drivers under Linux

Scheduling policy. Reference: ULK3e 7.1. Scheduling in Linux 1 / 20

NPTEL Course Jan K. Gopinath Indian Institute of Science

Finish up OS topics Group plans

NPTEL Course Jan K. Gopinath Indian Institute of Science

Operating System Project / Lecture 1 Tasks and scheduling. Bon Keun Seo

Concurrency Aspects of Project 2

CS 453: Operating Systems Programming Project 5 (100 points) Linux Device Driver

REVISION HISTORY NUMBER DATE DESCRIPTION NAME

USB. Development of a USB device driver working on Linux and Control Interface. Takeshi Fukutani, Shoji Kodani and Tomokazu Takahashi

7.4 Simple example of Linux drivers

Embedded Systems Programming

Linux drivers - Exercise

Linux Kernel PROCESS. Copyrighted to

OS Customization versus OS Code Modularity

Linux Scheduler. OS 323 (Spring 2013)

Operating System. Hanyang University. Hyunmin Yoon Operating System Hanyang University

Process Sheduling Lab

Using kgdb and the kgdb Internals

Linux Kernel Development (LKD)

Project No. 2: Process Scheduling in Linux Submission due: April 12, 2013, 11:59pm

Introduction to the Linux Kernel. Hao-Ran Liu

Using SCHED DEADLINE in Linux. Luca Abeni

T. Cucinotta Real-Time Systems Lab (ReTiS) Scuola Superiore Sant'Anna Pisa Italy 1. Real-Time Scheduling on Linux and SCHED_DEADLINE

High level scheduling: Medium level scheduling: Low level scheduling. Scheduling 0 : Levels

Processes. Operating System CS 217. Supports virtual machines. Provides services: User Process. User Process. OS Kernel. Hardware

Proxy Execution. Peter Zijlstra Intel OTC

Linux process scheduling. David Morgan

Kernel Modules. Kartik Gopalan

Linux Device Drivers. 3. Char Drivers. 1. Introduction 2. Kernel Modules 3. Char Drivers 4. Advanced Char Drivers 5. Interrupts

CS 378 (Spring 2003)

Load Balancing. Minsoo Ryu. Department of Computer Science and Engineering. Hanyang University. Real-Time Computing and Communications Lab.

University of Colorado at Colorado Springs CS4500/ Fall 2018 Operating Systems Project 1 - System Calls and Processes

University of Texas at Arlington. CSE Spring 2018 Operating Systems Project 4a - The /Proc File Systems and mmap. Instructor: Jia Rao

Scheduling II. ! Multilevel queue scheduling. ! Multiprocessor scheduling issues. ! Real-time scheduling. ! Linux scheduling

Process Management. Changwoo Min

Device Drivers. CS449 Fall 2017

This Document describes the API provided by the DVB-Multicast-Client library

ELEC 377 Operating Systems. Week 4 Lab 2 Tutorial

Scheduling: Case Studies. CS 161: Lecture 5 2/14/17

ECEN 449: Microprocessor System Design Department of Electrical and Computer Engineering Texas A&M University

Introduction. This project will focus primarily on processes.

CPSC 8220 FINAL EXAM, SPRING 2016

Unix (Linux) Device Drivers

PFStat. Global notes

CS356 Operating System Projects Spring Project 2: Android scheduler

CPU/Process Management : Objectives & Challenges. Data Structures for CPU Management

Introduction to Linux Device Drivers Recreating Life One Driver At a Time

Linux Linux #! "! Linux

Class average is Undergraduates are performing better. Working with low-level microcontroller timers

W4118: advanced scheduling

CS 326 Operating Systems C Programming. Greg Benson Department of Computer Science University of San Francisco

ECEN 449: Microprocessor System Design Department of Electrical and Computer Engineering Texas A&M University

Scalable Linux Scheduling (Paper # 9)

Linux Kernel Module Programming. Tushar B. Kute,

CSE 333 SECTION 3. POSIX I/O Functions

Analyzing Kernel Behavior by SystemTap

Itron Riva Kernel Module Building

Processes & Threads. Today. Next Time. ! Process concept! Process model! Implementing processes! Multiprocessing once again. ! More of the same J

1 The Linux MTD, YAFFS Howto

CS356 Operating System Projects Spring Project 2: Android scheduler

RF-IDs in the Kernel -- Episode III: I want to File Away

Operating Systems (234123) Spring 2017 (Homework Wet 1) Homework 1 Wet

Virtual Machine Introspection Bhushan Jain

Interrupt handling. Interrupt handling. Deferred work. Interrupt handling. Remove an interrupt handler. 1. Link a struct work to a function

Computer Science 162, Fall 2014 David Culler University of California, Berkeley Midterm 1 September 29, 2014

Processes COMPSCI 386

Step Motor. Step Motor Device Driver. Step Motor. Step Motor (2) Step Motor. Step Motor. source. open loop,

FILE SYSTEMS. Jo, Heeseung

INF1060: Introduction to Operating Systems and Data Communication. Pål Halvorsen. Wednesday, September 29, 2010

Microkernel Construction

Lecture 20. Log into Linux. Copy directory /home/hwang/cs375/lecture20 Project 5 due today. Project 6 posted, due Tuesday, April 8. Questions?

SSE3052: Embedded Systems Practice

/sleeper Work: VOL CS: IVOL CS: /CPU Work: VOL CS: IVOL CS: /IO Work: VOL CS: IVOL CS: Each of the

Ineffective and effective way to find out latency bottlenecks by Ftrace

CPU Scheduling (Part II)

Embedded Linux. Session 4: Introduction to the GPIO Kernel API. Martin Aebersold BFH-TI Dipl. El.-Ing. FH.

What we will learn. Multi Process Systems: Processes &Threads. Architectural support: Processor Modes. Processes (classic vs.

Project 2: Android Scheduler

PetaLinux SDK User Guide. Application Development Guide

Transcription:

Linux Kernel Development (LKD) Session 2 CISTER Framework: Laboratory 2 Paulo Baltarejo Sousa pbs@isep.ipp.pt 2017

1 Introduction The goal of the CISTER framework is to create a set of tools that help CISTER Summer School Internship students to explore and to learn the how to develop code for Linux kernel. 2 Preparing One of the goals is to avoid spreading out files for many directories in the Linux kernel source code tree. So, it will be created a directory, called cister in the Linux kernel to encompass all files required for such a framework. For that purpose, open a terminal and type: > cd kernel_sc > cd linux-4.12.4-cister > cd kernel > mkdir cister 3 Configuration menu The next step is to add a new configuration option entry that is used to wrap all the CISTER framework code. Then, the Kconfig file has to be created in the linux-4.12.4-cister/kernel/cister directory. The content of the Kconfig file is: menu "CISTER framework" config CISTER_FRAMEWORK bool "CISTER Framework" default y endmenu In spite of the entry name is CISTER_FRAMEWORK, in the code it will be referred as CONFIG_CISTER_FRAMEWORK. The CONFIG_ prefix is assumed but is not written. The bool directive states that this option entry is a feature and can only be set using two values (y or n). The quoted text following the directive provides the name of this option in the various configuration utilities, like make menuconfig. The default value of this option is defined using default directive. Since the host system used in this document is based on a x86 architecture, the linux-4.12.4-cister/kernel/cister/kconfig configuration file must be included into the root configuration file for x86 architecture located 1

at linux-4.12.4-cister/arch/x86/kconfig file.... source "crypto/kconfig" source "arch/x86/kvm/kconfig" source "lib/kconfig" source "kernel/cister/kconfig" Open a terminal, move to the linux-4.12.4-cister directory and type: > make menuconfig Use the "Down" arrow key to move to the last option, called "CISTER Framework" that you have just created. 4 Preparing As mentioned before, all CISTER framework implementation source code files will be placed into the linux-4.12.4-cister/kernel/cister directory. The next step is to create a Makefile file for compiling the CISTER Framework source code. Create an empty file called Makefile in the linu x-4.12.4-cister/kernel/cister directory. Next, change the linux-4.12.4-cister/kernel/makefile file to include cister directory in the compilation process: 2

... obj-$(config_membarrier) += membarrier.o obj-$(config_has_iomem) += memremap.o $(obj)/configs.o: $(obj)/config_data.h targets += config_data.gz $(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE $(call if_changed,gzip) filechk_ikconfiggz = (echo "static const char kernel_config_data[] used = MAGIC_START"; cat $< scripts/basic/bin2c; echo "MAGIC_END;") targets += config_data.h $(obj)/config_data.h: $(obj)/config_data.gz FORCE $(call filechk,ikconfiggz) #including CISTER Framework in the compilation process obj-$(config_cister_framework) += cister/ CORRIGIR Now, you are ready to compile the Linux kernel. Open a terminal and move to the Linux kernel source code parent directory: > cd kernel_sc > sudo./kcompile.sh > cd kernel_sc > cd linux-4.12.4-cister > make menuconfig Check if the CISTER Framework is included. 5 Scheduling Tracing Mechanism The goal of this feature is to create scheduling tracing mechanism in the Linux kernel. The purpose is to register the event types: SCHED_TICK, SWITCH_TO and SWITCH_AWAY. 3

The SCHED_TICK event happens whenever the periodic interrupt, called tick, is fired. Note that, there is always a task executing when such event occurs. The SWITCH_TO event happens whenever a task is assigned to CPU for execution, while SWITCH_AWAY event happens whenever a task is removed from CPU. It must be created the CISTER_TRACING configuration entry that depends on CISTER_FRAMEWORK entry. This feature must be a module, because it will be created an entry in the proc directory to pass the scheduling information from kernel to user space. So, the interaction will be through a proc entry. So, it must be created a proc/cister_trace entry. To store the scheduling data, this module must implement a ring buffer. It must save the the following information: event type, event timestamp, task policy, task prio, task state, task pid and task comm. 1. Open the linux-4.12.4-cister/kernel/cister/kconfig file and update it by adding: menu "CISTER framework" config CISTER_FRAMEWORK bool "CISTER Framework" default y config CISTER_TRACING bool "CISTER tracing" default y depends on CISTER_FRAMEWORK endmenu 2. Create the trace.h file in the linux-4.12.4-cister/kernel/ciste r/ directory and code with: 4

#ifndef TRACE_H_ #define TRACE_H_ #include <linux/sched.h> #define TRACE_ENTRY_NAME "cister_trace" #define TRACE_BUFFER_SIZE 1000 #define TRACE_BUFFER_LEN 200 enum evt SCHED_TICK = 0, SWITCH_AWAY, SWITCH_TO, ; #define TRACE_TASK_COMM_LEN 16 struct trace_evt enum evt event; unsigned long long time; pid_t pid; int state; int prio; int policy; char comm[trace_task_comm_len]; ; struct trace_evt_buffer struct trace_evt events[trace_buffer_size]; int write_item; int read_item; spinlock_t lock; ; void cister_trace(enum evt event, struct task_struct *p); 3. Create the trace.c file in the linux-4.12.4-cister/kernel/ciste r/ directory and code with: #include <linux/module.h> #include <linux/kernel.h> #include <linux/proc_fs.h> #include <linux/uaccess.h> #include "trace.h" /////////////////////////////////////////////////////////////////////// // Ring Buffer implementation struct trace_evt_buffer trace; unsigned char enabled = 0; static void increment(int * item) *item = *item + 1; if(*item >= TRACE_BUFFER_SIZE) *item = 0; static int is_empty(int r, int w) return!(r ^ w); //xor 5

static int is_full(int r, int w) int write = w; increment(&write); return write == r; static int dequeue (char *buffer) int ret = 0, len; char evt[20]; spin_lock(&trace.lock); if(!is_empty(trace.read_item,trace.write_item)) //if it is not empty switch((int)trace.events[trace.read_item].event) case SCHED_TICK: strcpy(evt,"sch_tk"); break; case SWITCH_AWAY: strcpy(evt,"swt_ay"); break; case SWITCH_TO: strcpy(evt,"swt_to"); break; len = sprintf(buffer,"%llu,",trace.events[trace.read_item].time); len += sprintf(buffer+len,"%s,",evt); len += sprintf(buffer+len,"pid,%d,",(int)trace.events[trace.read_item].pid); len += sprintf(buffer+len,"prio,%d,",(int)trace.events[trace.read_item].prio); len += sprintf(buffer+len,"policy,%d,",(int)trace.events[trace.read_item].policy); len += sprintf(buffer+len,"state,%d,",(int)trace.events[trace.read_item].state); len += sprintf(buffer+len,"%s\n",trace.events[trace.read_item].comm); increment(&trace.read_item); ret = 1; spin_unlock(&trace.lock); return ret; static int enqueue (enum evt event, unsigned long long time, struct task_struct *p) spin_lock(&trace.lock); if(is_full(trace.read_item, trace.write_item)) increment(&trace.read_item); trace.events[trace.write_item].event = event; trace.events[trace.write_item].time = time; trace.events[trace.write_item].pid = p->pid; trace.events[trace.write_item].state = p->state; trace.events[trace.write_item].prio = p->prio; trace.events[trace.write_item].policy = p->policy; strcpy(trace.events[trace.write_item].comm, p->comm); increment(&trace.write_item); spin_unlock(&trace.lock); return 1; ssize_t trace_read(struct file *filp, char user *buf, size_t count, loff_t *f_pos) char buffer[trace_buffer_len]; int ret = 0, len = 0; printk(kern_info "%s:[%d] read\n",trace_entry_name, current->pid); if(!dequeue(buffer)) return 0; len = strlen(buffer); if(len <= 0) return -EFAULT; if(count < len) 6

return -EFAULT; ret=copy_to_user(buf,buffer,len); if(ret!= 0) return -EFAULT; return len; static const struct file_operations trace_fops =.owner = THIS_MODULE,.read = trace_read, ; static int init proc_trace_init(void) proc_create(trace_entry_name,0444, NULL, &trace_fops); printk("cister:/proc/%s created\n", TRACE_ENTRY_NAME); spin_lock_init(&trace.lock); trace.write_item = 0; trace.read_item = 0; enabled = 1; return 0; module_init(proc_trace_init); //This function will be used to get the event. void cister_trace(enum evt event, struct task_struct *p) if(enabled) unsigned long long time = ktime_to_ns(ktime_get()); enqueue(event, time, p); 4. Open the linux-4.12.4-cister/kernel/sched/sched.h file and update it by adding:... #ifdef CONFIG_PARAVIRT #include <asm/paravirt.h> #include "cpupri.h" #include "cpudeadline.h" #include "cpuacct.h" #ifdef CONFIG_SCHED_DEBUG #define SCHED_WARN_ON(x) WARN_ONCE(x, #x) #else #define SCHED_WARN_ON(x) ((void)(x)) #ifdef CONFIG_CISTER_TRACING #include "../cister/trace.h" struct rq; struct cpuidle_state;... 5. Open the linux-4.12.4-cister/kernel/cister/makefile file and update it by adding: 7

# CISTER Framework makefile obj-$(config_cister_tracing) += trace.o 6. Now, let collect events. So, open the linux-4.12.4-cister/kernel /sched/core.c file and update it by adding to the schedule function: static void sched notrace schedule(bool preempt)... next = pick_next_task(rq, prev, &rf); clear_tsk_need_resched(prev); clear_preempt_need_resched(); if (likely(prev!= next)) rq->nr_switches++; rq->curr = next; ++*switch_count; trace_sched_switch(preempt, prev, next); #ifdef CONFIG_CISTER_TRACING cister_trace(switch_away, prev); cister_trace(switch_to, next); /* Also unlocks the rq: */ rq = context_switch(rq, prev, next, &rf); else rq->clock_update_flags &= ~(RQCF_ACT_SKIP RQCF_REQ_SKIP); rq_unlock_irq(rq, &rf); balance_callback(rq); 7. Update the schedule_tick function located at linux-4.12.4-ciste r/kernel/sched/core.c file: 8

/* * This function gets called by the timer code, with HZ frequency. * We call it with interrupts disabled. */ void scheduler_tick(void) int cpu = smp_processor_id(); struct rq *rq = cpu_rq(cpu); struct task_struct *curr = rq->curr; struct rq_flags rf; sched_clock_tick(); rq_lock(rq, &rf); update_rq_clock(rq); curr->sched_class->task_tick(rq, curr, 0); #ifdef CONFIG_CISTER_TRACING cister_trace(sched_tick, curr); cpu_load_update_active(rq); calc_global_load_tick(rq); rq_unlock(rq, &rf); perf_event_task_tick(); #ifdef CONFIG_SMP rq->idle_balance = idle_cpu(cpu); trigger_load_balance(rq); rq_last_tick_reset(rq); 8. Check if the CISTER Tracing is included. > cd kernel_sc > cd linux-4.12.4-cister > make menuconfig 9. Compile the Linux kernel: > sudo./kcompile.sh In the end of the compilation process, it is created a text file called 9

errors_4.12.4-cister that outputs the result of the compilation. item Reboot the system > sudo reboot 10. Open a terminal for getting the scheduling trace: > cat /proc/cister_trace > trace.csv The first column refers to the timestamp and second one to the event type. The following columns presents task s data: the process identifier (pid), priority level (prio), scheduling policy (policy), process state and process name. For that it is used a tuple description, value. 59973586110,SWT_TO,pid,1325,prio,120,policy,0,state,0,compiz 59985440808,SCH_TK,pid,1325,prio,120,policy,0,state,0,compiz 59985557088,SWT_AY,pid,1325,prio,120,policy,0,state,0,compiz 59985564316,SWT_TO,pid,1043,prio,120,policy,0,state,0,notify-osd 59985627929,SWT_AY,pid,1043,prio,120,policy,0,state,1,notify-osd 59985627967,SWT_TO,pid,657,prio,120,policy,0,state,0,Xorg 59985716747,SWT_AY,pid,657,prio,120,policy,0,state,1,Xorg 59985716829,SWT_TO,pid,1043,prio,120,policy,0,state,0,notify-osd 59985731767,SWT_AY,pid,1043,prio,120,policy,0,state,1,notify-osd 59985731791,SWT_TO,pid,657,prio,120,policy,0,state,0,Xorg 59985766302,SWT_AY,pid,657,prio,120,policy,0,state,1,Xorg 59985766370,SWT_TO,pid,1043,prio,120,policy,0,state,0,notify-osd 59985787054,SWT_AY,pid,1043,prio,120,policy,0,state,1,notify-osd 59985787093,SWT_TO,pid,1325,prio,120,policy,0,state,0,compiz 59986244493,SCH_TK,pid,1325,prio,120,policy,0,state,0,compiz 59987338003,SCH_TK,pid,1325,prio,120,policy,0,state,0,compiz 59988032604,SCH_TK,pid,1325,prio,120,policy,0,state,0,compiz 59992995163,SWT_AY,pid,1325,prio,120,policy,0,state,0,compiz 59992995376,SWT_TO,pid,657,prio,120,policy,0,state,0,Xorg 59993044422,SCH_TK,pid,657,prio,120,policy,0,state,0,Xorg 59993400639,SWT_AY,pid,657,prio,120,policy,0,state,1,Xorg 59993403222,SWT_TO,pid,1325,prio,120,policy,0,state,0,compiz 59993427231,SWT_AY,pid,1325,prio,120,policy,0,state,0,compiz 59993428212,SWT_TO,pid,657,prio,120,policy,0,state,0,Xorg 59993462589,SWT_AY,pid,657,prio,120,policy,0,state,1,Xorg 59993462667,SWT_TO,pid,1325,prio,120,policy,0,state,0,compiz 59993472288,SWT_AY,pid,1325,prio,120,policy,0,state,0,compiz 59993472313,SWT_TO,pid,657,prio,120,policy,0,state,0,Xorg The pid value varies from 0 to approximately 4 millions (2 22 ) and prio from 0 to 139. The policy range of values are: /* * Scheduling policies */ #define SCHED_NORMAL 0 #define SCHED_FIFO 1 #define SCHED_RR 2 #define SCHED_BATCH 3 /* SCHED_ISO: reserved but not implemented yet */ #define SCHED_IDLE 5 #define SCHED_DEADLINE 6 The state range of values are: 10

/* Used in tsk->state: */ #define TASK_RUNNING 0 #define TASK_INTERRUPTIBLE 1 #define TASK_UNINTERRUPTIBLE 2 #define TASK_STOPPED 4 #define TASK_TRACED 8 /* Used in tsk->exit_state: */ #define EXIT_DEAD 16 #define EXIT_ZOMBIE 32 #define EXIT_TRACE (EXIT_ZOMBIE EXIT_DEAD) /* Used in tsk->state again: */ #define TASK_DEAD 64 #define TASK_WAKEKILL 128 #define TASK_WAKING 256 #define TASK_PARKED 512 #define TASK_NOLOAD 1024 #define TASK_NEW 2048 #define TASK_STATE_MAX 4096 11