/tmp/l4check/full_tree/trunk/l4/pkg/dde_linux/lib/src/softirq.c File Reference

Deferred Activities (BHs, Tasklets, real softirqs). More...

#include <l4/env/errno.h>
#include <l4/sys/syscalls.h>
#include <l4/thread/thread.h>
#include <l4/semaphore/semaphore.h>
#include <l4/lock/lock.h>
#include <l4/dde_linux/dde.h>
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/tqueue.h>
#include "internal.h"
#include "__config.h"

Go to the source code of this file.

Tasklets

This is from kernel/softirq.c and include/linux/interrupt.h)

Tasklets are the multithreaded analogue of BHs.

Main feature differing them of generic softirqs: one tasklet is running only on one CPU simultaneously.

Main feature differing them of BHs: different tasklets may be run simultaneously on different CPUs.

Properties:

  • If tasklet_schedule() is called, then tasklet is guaranteed to be executed on some cpu at least once after this.
  • If the tasklet is already scheduled, but its excecution is still not started, it will be executed only once.
  • If this tasklet is already running on another CPU (or schedule() is called from tasklet itself), it is rescheduled for later.
  • Tasklet is strictly serialized wrt itself, but not wrt another tasklets. If client needs some intertask synchronization, he makes it with spinlocks.

  • these functions are thread-safe
  • no assumption how much softirq threads
  • one driver seldom uses more than 1 tasklet/bh therefore 1 tasklet thread is enough ?!

Tasklet lists are CPU local in Linux and so tasklet related synchonization is. This is not in Linux DDE - local_irq_disable()/enable() is not sufficient. We use our cli()/sti() implementation.

Todo:
Rethink tasklet_vec[1] for more than 1 softirq thread; so NR_CPUS will become NR_SOFTIRQ_THREADS later


static struct tasklet_head tasklet_vec [NR_CPUS]
 tasklet list head 1-element vector (NR_CPUS==1)
static struct tasklet_head tasklet_hi_vec [NR_CPUS]
 high prio tasklet list head 1-element vector (NR_CPUS==1)
static void tasklet_action (void)
 Tasklet Execution.
static int tasklet_hi_action (void)
 High-Priority Tasklet Execution.
void tasklet_init (struct tasklet_struct *t, void(*func)(unsigned long), unsigned long data)
 Tasklet Initialization.
void tasklet_kill (struct tasklet_struct *t)
 Tasklet Termination.
void tasklet_schedule (struct tasklet_struct *t)
 Schedule dedicated tasklet.
void tasklet_hi_schedule (struct tasklet_struct *t)
 Schedule dedicated high-priority tasklet.

Old-style Bottom Halves and Task Queues

This is from kernel/softirq.c

All bottom halves run as one tasklet so no two bottom halves can run simultaneously.

Todo:
Implement this if any useful driver needs it.
Todo:
encapsulate tqueue_lock like tasklet_vec providing proper interface


spinlock_t tqueue_lock = SPIN_LOCK_UNLOCKED
 protects tqueue list operation (from kernel/timer.c)
void __run_task_queue (task_queue *list)
 Task Queue Execution

Runs _all_ tasks currently in task queue list.


Functions

static void dde_softirq_thread (int num)
 Linux DDE Softirq Thread(s).
int l4dde_softirq_init ()
 Initalize Softirq Thread(s).
Softirqs
This is from include/linux/interrupt.h

Softirqs are multithreaded, not serialized BH-like activities. Several softirqs may run on several CPUs simultaneously - no matter if they are of the same type.

Properties:

  • If raise_softirq() is called, then softirq is guarenteed to be executed on this CPU.
  • On schedule() do_softirq() is called if any softirq is active on this CPU.
  • Softirqs are not serialized in any way.

Linux (2.4.20) has only 4 softirqs:

  • HI_SOFTIRQ
  • NET_TX_SOFTIRQ and NET_RX_SOFTIRQ
  • TASKLET_SOFTIRQ

Relevant for Linux DDE are for now only the first and the latter - NET_* softirqs allow transparent mutli-threading in Linux' network code. HI_SOFTIRQ is for high priority bottom halves as old-style BHs and sound related drivers. It triggers execution of tasklet_hi_action(). TASKLET_SOFTIRQ runs lower priority bottom halves (e.g. in the console subsystem). It triggers execution of tasklet_action().

Todo:
only the implementation of tasklets is done in Linux DDE


void __cpu_raise_softirq (unsigned cpu, int nr)
 Raise softirq for dedicated CPU / handler thread.
void raise_softirq (int nr)
 Raise Softirq.

Variables

Module variables
Test:
krishna: We want to support more than one softirq thread (SOFTIRQ_THREADS), but there's only one semaphore softirq_sema. This'll be fixed when we really support multiple threads.
Todo:
Redesign for more than one thread.


static l4thread_t softirq_tid [SOFTIRQ_THREADS]
 softirq thread ids
static l4semaphore_t softirq_sema = L4SEMAPHORE_LOCKED
 softirq semaphore


Detailed Description

Deferred Activities (BHs, Tasklets, real softirqs).

Date:
08/28/2003
Author:
Christian Helmuth <ch12@os.inf.tu-dresden.de>

Definition in file softirq.c.


Function Documentation

void __cpu_raise_softirq ( unsigned  cpu,
int  nr 
)

Raise softirq for dedicated CPU / handler thread.

Must hold global lock when calling this.

Definition at line 109 of file softirq.c.

static void dde_softirq_thread ( int  num  )  [static]

Linux DDE Softirq Thread(s).

Parameters:
num number of softirq thread (for now always 0)
Test:
krishna: call softirq_action functions directly; later open_softirq implementation and call via softirq_vec[]
Todo:
priorities

Definition at line 425 of file softirq.c.

static int tasklet_hi_action ( void   )  [static]

High-Priority Tasklet Execution.

Returns:
0 on empty high-priority tasklet list

Definition at line 220 of file softirq.c.


Linux DDE, written by Christian Helmuth  © 2003 Technische Universitaet Dresden