public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Esben Nielsen <nielsen.esben@googlemail.com>
To: linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@elte.hu>
Subject: [patch 2/5] [PREEMPT_RT] Changing interrupt handlers from running in thread to hardirq and back runtime.
Date: Fri, 2 Jun 2006 23:23:15 +0100 (BST)	[thread overview]
Message-ID: <Pine.LNX.4.64.0606022321440.9307@localhost> (raw)
In-Reply-To: 20060602165336.147812000@localhost

This patch makes it possible to change which context the interrupt handlers
for each interrupt run in, hard-irq or threaded if CONFIG_PREEMPT_HARDIRQS is 
set.

The interface is the file
  /proc/irq/<irq number>/threaded
You can read it to see what the context is now or write one of

  irq
  fifo <rt priority>
  rr <rt priority>
  normal <nice value>
  batch <nice value>

where one of the latter makes the interrupt handler threaded.

A replacement for request_irq(), called request_irq2(), is added. When a driver
uses this to install it's irq-handler it can also give a change_irq_context
call-back. This call-back is called whenever the irq-context is changed or 
going to be changed. The call-back must be of the form

int driver_change_context(int irq, void *dev_id, enum change_context_cmd cmd)

where

enum change_context_cmd {
 	IRQ_TO_HARDIRQ,
 	IRQ_CAN_THREAD,
 	IRQ_TO_THREADED
};

The call-back is supposed to do the following on
  IRQ_TO_HARDIRQ: make sure everything in the interrupt handler is non-blocking
                  or return a non-zero error code.
  IRQ_CAN_THREAD: Return 0 if it is ok for the interrupt handler to be run in
                  thread context. Return a non-zero error code otherwise.
  IRQ_TO_THREAD: Now the interrupt handler does run in thread context. The
                 driver can now change it's locks to being mutexes. The return
                 value is ignored as the driver already got a chance to protest
                 above.

Index: linux-2.6.16-rt23.spin_mutex/include/linux/interrupt.h
===================================================================
--- linux-2.6.16-rt23.spin_mutex.orig/include/linux/interrupt.h
+++ linux-2.6.16-rt23.spin_mutex/include/linux/interrupt.h
@@ -34,21 +34,38 @@ typedef int irqreturn_t;
  #define IRQ_HANDLED	(1)
  #define IRQ_RETVAL(x)	((x) != 0)

+enum change_context_cmd {
+	IRQ_TO_HARDIRQ,
+	IRQ_CAN_THREAD,
+	IRQ_TO_THREADED
+};
+
  struct irqaction {
  	irqreturn_t (*handler)(int, void *, struct pt_regs *);
  	unsigned long flags;
  	cpumask_t mask;
  	const char *name;
  	void *dev_id;
+#ifdef CONFIG_CHANGE_IRQ_CONTEXT
+	int (*change_context)(int, void *,
+			      enum change_context_cmd);
+#endif
  	struct irqaction *next;
  	int irq;
-	struct proc_dir_entry *dir, *threaded;
+	struct proc_dir_entry *dir;
+	struct rcu_head rcu;
  };

  extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs);
  extern int request_irq(unsigned int,
  		       irqreturn_t (*handler)(int, void *, struct pt_regs *),
  		       unsigned long, const char *, void *);
+extern int request_irq2(unsigned int irq,
+			irqreturn_t (*handler)(int, void *, struct pt_regs *),
+			unsigned long irqflags, const char * devname,
+			void *dev_id,
+			int (*change_context)(int, void *,
+					      enum change_context_cmd));
  extern void free_irq(unsigned int, void *);


Index: linux-2.6.16-rt23.spin_mutex/include/linux/irq.h
===================================================================
--- linux-2.6.16-rt23.spin_mutex.orig/include/linux/irq.h
+++ linux-2.6.16-rt23.spin_mutex/include/linux/irq.h
@@ -47,6 +47,18 @@
  # define SA_NODELAY 0x01000000
  #endif

+#ifndef SA_MUST_THREAD
+# define SA_MUST_THREAD 0x02000000
+#endif
+
+/* Set this flag if the irq handler must thread under preempt-rt otherwise not
+ */
+#ifdef CONFIG_PREEMPT_RT
+# define SA_MUST_THREAD_RT SA_MUST_THREAD
+#else
+# define SA_MUST_THREAD_RT 0
+#endif
+
  /*
   * IRQ types
   */
@@ -147,12 +159,13 @@ struct irq_type {
   * @chip:		low level hardware access functions - comes from type
   * @action:		the irq action chain
   * @status:		status information
+ *                      (protected by the spinlock )
   * @depth:		disable-depth, for nested irq_disable() calls
   * @irq_count:		stats field to detect stalled irqs
   * @irqs_unhandled:	stats field for spurious unhandled interrupts
   * @thread:		Thread pointer for threaded preemptible irq handling
   * @wait_for_handler:	Waitqueue to wait for a running preemptible handler
- * @lock:		locking for SMP
+ * @lock:		lock around the action list
   * @move_irq:		Flag need to re-target interrupt destination
   *
   * Pad this out to 32 bytes for cache and indexing reasons.
Index: linux-2.6.16-rt23.spin_mutex/kernel/Kconfig.preempt
===================================================================
--- linux-2.6.16-rt23.spin_mutex.orig/kernel/Kconfig.preempt
+++ linux-2.6.16-rt23.spin_mutex/kernel/Kconfig.preempt
@@ -119,6 +119,17 @@ config PREEMPT_HARDIRQS

  	  Say N if you are unsure.

+config CHANGE_IRQ_CONTEXT
+	bool "Change the irq context runtime"
+	depends on PREEMPT_HARDIRQS && (PREEMPT_RCU || !SPIN_MUTEXES)
+	help
+	  You can change wether the IRQ handler(s) for each IRQ number is
+          running in hardirq context or as threaded by writing to
+          /proc/irq/<number>/threaded
+          If PREEMPT_RT is selected the drivers involved must be ready for it,
+          though, or the write will fail. Remember to switch on SPIN_MUTEXES as
+          well in that case as the drivers which are ready uses spin-mutexes.
+
  config SPINLOCK_BKL
  	bool "Old-Style Big Kernel Lock"
  	depends on (PREEMPT || SMP) && !PREEMPT_RT
Index: linux-2.6.16-rt23.spin_mutex/kernel/irq/internals.h
===================================================================
--- linux-2.6.16-rt23.spin_mutex.orig/kernel/irq/internals.h
+++ linux-2.6.16-rt23.spin_mutex/kernel/irq/internals.h
@@ -22,6 +22,10 @@ static inline void end_irq(irq_desc_t *d
  }

  #ifdef CONFIG_PROC_FS
+#ifdef CONFIG_CHANGE_IRQ_CONTEXT
+extern int make_irq_nodelay(int irq, struct irq_desc *desc);
+extern int make_irq_threaded(int irq, struct irq_desc *desc);
+#endif
  extern void register_irq_proc(unsigned int irq);
  extern void register_handler_proc(unsigned int irq, struct irqaction *action);
  extern void unregister_handler_proc(unsigned int irq, struct irqaction *action);
Index: linux-2.6.16-rt23.spin_mutex/kernel/irq/manage.c
===================================================================
--- linux-2.6.16-rt23.spin_mutex.orig/kernel/irq/manage.c
+++ linux-2.6.16-rt23.spin_mutex/kernel/irq/manage.c
@@ -206,6 +206,153 @@ int can_request_irq(unsigned int irq, un
  	return !action;
  }

+
+#ifdef CONFIG_CHANGE_IRQ_CONTEXT
+int make_action_nodelay(int irq, struct irqaction *act)
+{
+	unsigned long flags;
+
+	if(!(act->flags & SA_MUST_THREAD)) {
+		return 0;
+	}
+
+	if( act->change_context ) {
+		int ret =
+			act->change_context(irq, act->dev_id, IRQ_TO_HARDIRQ);
+		if(ret) {
+			printk(KERN_ERR "Failed to change irq handler "
+			       "for dev %s on IRQ%d to hardirq "
+			       "context (ret: %d)\n", act->name, irq, ret);
+			return ret;
+		}
+		spin_lock_irqsave(&irq_desc[irq].lock, flags);
+		act->flags &=~SA_MUST_THREAD;
+		act->flags |= SA_NODELAY;
+		spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+		return 0;
+	}
+	else {
+		printk(KERN_ERR "Irq handler "
+		       "for dev %s on IRQ%d can not be changed"
+		       " to hardirq context\n", act->name, irq);
+		return -ENOSYS;
+	}
+
+}
+
+
+static int __make_irq_threaded(int irq, struct irq_desc *desc);
+
+int make_irq_nodelay(int irq, struct irq_desc *desc)
+{
+	int ret = 0;
+	struct irqaction *act;
+	unsigned long flags;
+
+	rcu_read_lock();
+	for(act = desc->action; act; act = act->next) {
+		WARN_ON(((~act->flags) & (SA_MUST_THREAD|SA_NODELAY)) == 0);
+		if(act->flags & SA_MUST_THREAD) {
+			ret = make_action_nodelay(irq, act);
+			if(ret) {
+				printk(KERN_ERR "Could not make irq %d "
+				       "nodelay (errno %d)\n",
+				       irq, ret);
+				goto failed;
+			}
+		}
+	}
+	spin_lock_irqsave(&desc->lock, flags);
+	desc->status |= IRQ_NODELAY;
+	spin_unlock_irqrestore(&desc->lock, flags);
+	rcu_read_unlock();
+
+	return 0;
+ failed:
+	__make_irq_threaded(irq, desc);
+	rcu_read_unlock();
+	return ret;
+}
+
+int action_may_thread(int irq, struct irqaction *act)
+{
+	if(!act->change_context)
+		return !(act->flags & SA_NODELAY);
+
+	return act->change_context(irq, act->dev_id, IRQ_CAN_THREAD) == 0;
+}
+
+
+static int __make_irq_threaded(int irq, struct irq_desc *desc)
+{
+	struct irqaction *act;
+
+	for(act = desc->action; act; act = act->next) {
+		WARN_ON(((~act->flags) & (SA_MUST_THREAD|SA_NODELAY)) == 0);
+		if(!action_may_thread(irq, act)) {
+			return -EINVAL;
+		}
+	}
+
+	if (start_irq_thread(irq, desc))
+		return -ENOMEM;
+
+	spin_lock_irq(&desc->lock);
+	desc->status &= ~IRQ_NODELAY;
+	spin_unlock_irq(&desc->lock);
+
+	/* We can't make irq handlers change their context before we
+	   are sure no CPU is running them in hard irq context */
+	synchronize_irq(irq);
+
+	for(act = desc->action; act; act = act->next) {
+		WARN_ON(((~act->flags) & (SA_MUST_THREAD|SA_NODELAY)) == 0);
+		if(act->change_context) {
+			/* This callback can't fail */
+			act->change_context(irq, act->dev_id, IRQ_TO_THREADED);
+			spin_lock_irq(&desc->lock);
+			act->flags &=~SA_NODELAY;
+			act->flags |= SA_MUST_THREAD;
+			spin_unlock_irq(&desc->lock);
+		}
+	}
+
+	return 0;
+}
+
+int make_irq_threaded(int irq, struct irq_desc *desc)
+{
+	int ret;
+	rcu_read_lock();
+	ret = __make_irq_threaded(irq, desc);
+	rcu_read_unlock();
+	return ret;
+}
+#else /* CONFIG_CHANGE_IRQ_CONTEXT */
+int make_action_nodelay(int irq, struct irqaction *act)
+{
+	return -EINVAL;
+}
+int make_irq_nodelay(int irq, struct irq_desc *desc)
+{
+	unsigned long flags;
+	struct irqaction *act;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	for(act = desc->action; act; act = act->next) {
+		WARN_ON((~act->flags) & (SA_MUST_THREAD|SA_NODELAY) == 0);
+		if(act->flags & SA_MUST_THREAD)
+			return -EINVAL;
+	}
+
+	desc->status |= IRQ_NODELAY;
+	spin_unlock_irqrestore(&desc->lock, flags);
+
+	return 0;
+}
+
+#endif /* !CONFIG_CHANGE_IRQ_CONTEXT */
+
  /*
   * Internal function to register an irqaction - typically used to
   * allocate special interrupts that are part of the architecture.
@@ -239,11 +386,28 @@ int setup_irq(unsigned int irq, struct i
  		rand_initialize_irq(irq);
  	}

+	WARN_ON(((~new->flags) & (SA_MUST_THREAD|SA_NODELAY)) == 0);
  	if (!(new->flags & SA_NODELAY))
  		if (start_irq_thread(irq, desc))
  			return -ENOMEM;
+
+	if( (desc->status & IRQ_NODELAY) && (new->flags & SA_MUST_THREAD) ) {
+		int ret = make_action_nodelay(irq, new);
+		if(ret)
+			return ret;
+	}
+
+
+	if( (new->flags & SA_NODELAY) && !(desc->status & IRQ_NODELAY) ) {
+		int ret = make_irq_nodelay(irq, desc);
+		if(ret)
+			return ret;
+	}
+
+
  	/*
-	 * The following block of code has to be executed atomically
+	 * The following block of code has to be executed atomically due
+	 * to the hard irq context
  	 */
  	spin_lock_irqsave(&desc->lock, flags);
  	p = &desc->action;
@@ -262,7 +426,7 @@ int setup_irq(unsigned int irq, struct i
  		shared = 1;
  	}

-	*p = new;
+	rcu_assign_pointer(*p, new);

  	/*
  	 * Propagate any possible SA_NODELAY flag into IRQ_NODELAY:
@@ -282,13 +446,25 @@ int setup_irq(unsigned int irq, struct i

  	new->irq = irq;
  	register_irq_proc(irq);
-	new->dir = new->threaded = NULL;
+	new->dir = NULL;
  	register_handler_proc(irq, new);

  	return 0;
  }

  /**
+ *      free_irqaction_rcu - free the actual memory block of a struct irqaction
+ *      @rcu: Pointer to the struct rcu_head
+ *
+ *      Is called after RCU syncronization
+ */
+static void free_irqaction_rcu(struct rcu_head *rcu)
+{
+	struct irqaction *p = container_of(rcu, struct irqaction, rcu);
+	kfree(p);
+}
+
+/**
   *	free_irq - free an interrupt
   *	@irq: Interrupt line to free
   *	@dev_id: Device identity to free
@@ -312,6 +488,7 @@ void free_irq(unsigned int irq, void *de
  		return;

  	desc = irq_desc + irq;
+
  	spin_lock_irqsave(&desc->lock, flags);
  	p = &desc->action;
  	for (;;) {
@@ -325,7 +502,7 @@ void free_irq(unsigned int irq, void *de
  				continue;

  			/* Found it - now remove it from the list of entries */
-			*pp = action->next;
+			rcu_assign_pointer(*pp, action->next);

  			/* Currently used only by UML, might disappear one day.*/
  #ifdef CONFIG_IRQ_RELEASE_METHOD
@@ -344,9 +521,8 @@ void free_irq(unsigned int irq, void *de
  			spin_unlock_irqrestore(&desc->lock, flags);
  			unregister_handler_proc(irq, action);

-			/* Make sure it's not being used on another CPU */
  			synchronize_irq(irq);
-			kfree(action);
+			call_rcu(&action->rcu, free_irqaction_rcu);
  			return;
  		}
  		printk(KERN_ERR "Trying to free free IRQ%d\n", irq);
@@ -358,12 +534,14 @@ void free_irq(unsigned int irq, void *de
  EXPORT_SYMBOL(free_irq);

  /**
- *	request_irq - allocate an interrupt line
+ *	request_irq2 - allocate an interrupt line
   *	@irq: Interrupt line to allocate
   *	@handler: Function to be called when the IRQ occurs
   *	@irqflags: Interrupt type flags
   *	@devname: An ascii name for the claiming device
   *	@dev_id: A cookie passed back to the handler function
+ *      @change_context: call back for requesting a change of context
+ *       (threaded vs hardirq)
   *
   *	This call allocates interrupt resources and enables the
   *	interrupt line and IRQ handling. From the point this
@@ -381,18 +559,23 @@ EXPORT_SYMBOL(free_irq);
   *
   *	Flags:
   *
- *	SA_SHIRQ		Interrupt is shared
+ *	SA_SHIRQ		Interrupt can be shared
   *	SA_INTERRUPT		Disable local interrupts while processing
   *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
+ *      SA_NODELAY              The handler must run in hardirq context
+ *      SA_MUSTTHREAD           The handler can not run in hardirq context
   *
   */
-int request_irq(unsigned int irq,
-		irqreturn_t (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, const char * devname, void *dev_id)
+int request_irq2(unsigned int irq,
+		 irqreturn_t (*handler)(int, void *, struct pt_regs *),
+		 unsigned long irqflags, const char * devname, void *dev_id,
+		 int (*change_context)(int, void *,
+				       enum change_context_cmd))
  {
  	struct irqaction * action;
  	int retval;

+
  	/*
  	 * Sanity-check: shared interrupts must pass in a real dev-ID,
  	 * otherwise we'll have trouble later trying to figure out
@@ -416,8 +599,11 @@ int request_irq(unsigned int irq,
  	action->flags = irqflags;
  	cpus_clear(action->mask);
  	action->name = devname;
-	action->next = NULL;
  	action->dev_id = dev_id;
+#ifdef CONFIG_CHANGE_IRQ_CONTEXT
+	action->change_context = change_context;
+#endif
+	action->next = NULL;

  	select_smp_affinity(irq);

@@ -427,7 +613,17 @@ int request_irq(unsigned int irq,

  	return retval;
  }
+EXPORT_SYMBOL(request_irq2);

+int request_irq(unsigned int irq,
+		irqreturn_t (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, const char * devname, void *dev_id)
+{
+	if( !(irqflags & SA_NODELAY) )
+		irqflags |= SA_MUST_THREAD_RT;
+
+	return request_irq2(irq, handler, irqflags, devname, dev_id, NULL);
+}
  EXPORT_SYMBOL(request_irq);

  /**
Index: linux-2.6.16-rt23.spin_mutex/kernel/irq/proc.c
===================================================================
--- linux-2.6.16-rt23.spin_mutex.orig/kernel/irq/proc.c
+++ linux-2.6.16-rt23.spin_mutex/kernel/irq/proc.c
@@ -11,6 +11,7 @@
  #include <linux/profile.h>
  #include <linux/proc_fs.h>
  #include <linux/interrupt.h>
+#include <linux/ctype.h>

  #include "internals.h"

@@ -83,6 +84,138 @@ static int irq_affinity_write_proc(struc

  #endif

+
+#ifdef CONFIG_CHANGE_IRQ_CONTEXT
+/*
+ * The /proc/irq/<irq>/threaded values:
+ */
+static struct proc_dir_entry *irq_threaded_entry[NR_IRQS];
+
+static const char *sched_policies[] = {
+	"normal",
+	"fifo",
+	"rr",
+	"batch"
+};
+
+static int irq_threaded_read_proc(char *page, char **start, off_t off,
+				  int count, int *eof, void *data)
+{
+	unsigned int irq = (int)(long)data;
+	task_t *t;
+
+	if ( (irq_desc[irq].status & IRQ_NODELAY)
+	    || !irq_desc[irq].thread ) {
+		return scnprintf(page, count, "IRQ\n");
+	}
+
+	t = irq_desc[irq].thread;
+	if (t->policy==SCHED_NORMAL &&  t->policy == SCHED_BATCH )
+		return scnprintf(page, count, "%s %d\n",
+				 sched_policies[t->policy],
+				 task_prio(t));
+	else
+		return scnprintf(page, count, "%s %lu\n",
+				 sched_policies[t->policy],
+				 t->rt_priority);
+}
+
+
+static int set_rt_prio(int irq, int policy, char *arg)
+{
+	char *tmp;
+	struct sched_param prm;
+	int ret;
+	task_t *t;
+
+	while(isspace(*arg))
+		arg++;
+
+	if(*arg) {
+		prm.sched_priority = simple_strtol(arg,&tmp,10);
+		if (tmp == arg)
+			return -EINVAL;
+	}
+	else
+	  return -EINVAL;
+
+	ret = make_irq_threaded(irq, &irq_desc[irq]);
+	if(ret)
+		return ret;
+
+	t = irq_desc[irq].thread;
+	return sched_setscheduler(t, policy, &prm);
+}
+
+static int set_nonrt_prio(int irq, int policy, char *arg)
+{
+	char *tmp;
+	long prio;
+	int ret;
+	struct sched_param prm;
+	task_t *t;
+
+	while(isspace(*arg))
+		arg++;
+
+
+	if(*arg) {
+		prio = simple_strtol(arg,&tmp,10);
+		if (tmp == arg || prio < -20 || prio > 19)
+			return -EINVAL;
+	}
+	else
+		prio = 0;
+
+	ret = make_irq_threaded(irq, &irq_desc[irq]);
+	if(ret)
+		return ret;
+
+	t = irq_desc[irq].thread;
+	prm.sched_priority = 0;
+	ret = sched_setscheduler(t, policy, &prm);
+	if(ret)
+		return ret;
+
+	set_user_nice(t, prio);
+	return 0;
+}
+
+static int irq_threaded_write_proc(struct file *file,
+				   const char __user *buffer,
+				   unsigned long count, void *data)
+{
+	unsigned int irq = (int)(long)data;
+	int ret = 0;
+	char buf[20];
+
+	if(copy_from_user( (void*)&buf[0], (void*)buffer,
+			   count>20 ? 20: count ) )
+		return -EFAULT;
+
+	buf[19] = 0;
+
+	if(!strnicmp(buf,"irq",3))
+ 		ret = make_irq_nodelay(irq, &irq_desc[irq]);
+	else if(!strnicmp(buf,"normal",3))
+		ret = set_nonrt_prio(irq, SCHED_NORMAL, buf+6);
+	else if(!strnicmp(buf,"fifo",3))
+		ret = set_rt_prio(irq, SCHED_FIFO, buf+4);
+	else  if(!strnicmp(buf,"rr",2))
+		ret = set_rt_prio(irq, SCHED_RR, buf+2);
+	else  if(!strnicmp(buf,"batch",3))
+		ret = set_nonrt_prio(irq, SCHED_BATCH, buf+5);
+	else
+		ret = -EINVAL;
+
+
+	if(ret)
+		return ret;
+	else
+		return count;
+}
+#endif /* CONFIG_CHANGE_IRQ_CONTEXT */
+
  #define MAX_NAMELEN 10

  void register_irq_proc(unsigned int irq)
@@ -116,58 +249,33 @@ void register_irq_proc(unsigned int irq)
  		smp_affinity_entry[irq] = entry;
  	}
  #endif
+
+#ifdef CONFIG_CHANGE_IRQ_CONTEXT
+	{
+		struct proc_dir_entry *entry;
+
+		/* create /proc/irq/<irq>/threaded */
+		entry = create_proc_entry("threaded", 0600, irq_dir[irq]);
+
+		if (entry) {
+			entry->nlink = 1;
+			entry->data = (void *)(long)irq;
+			entry->read_proc = irq_threaded_read_proc;
+			entry->write_proc = irq_threaded_write_proc;
+		}
+		irq_threaded_entry[irq] = entry;
+	}
+#endif
  }

  #undef MAX_NAMELEN

  void unregister_handler_proc(unsigned int irq, struct irqaction *action)
  {
-	if (action->threaded)
-		remove_proc_entry(action->threaded->name, action->dir);
  	if (action->dir)
  		remove_proc_entry(action->dir->name, irq_dir[irq]);
  }

-#ifndef CONFIG_PREEMPT_RT
-
-#ifndef CONFIG_PREEMPT_RT
-
-static int threaded_read_proc(char *page, char **start, off_t off,
-			      int count, int *eof, void *data)
-{
-	return sprintf(page, "%c\n",
-		((struct irqaction *)data)->flags & SA_NODELAY ? '0' : '1');
-}
-
-static int threaded_write_proc(struct file *file, const char __user *buffer,
-			       unsigned long count, void *data)
-{
-	int c;
-	struct irqaction *action = data;
-	irq_desc_t *desc = irq_desc + action->irq;
-
-	if (get_user(c, buffer))
-		return -EFAULT;
-	if (c != '0' && c != '1')
-		return -EINVAL;
-
-	spin_lock_irq(&desc->lock);
-
-	if (c == '0')
-		action->flags |= SA_NODELAY;
-	if (c == '1')
-		action->flags &= ~SA_NODELAY;
-	recalculate_desc_flags(desc);
-
-	spin_unlock_irq(&desc->lock);
-
-	return 1;
-}
-
-#endif
-
-#endif
-
  #define MAX_NAMELEN 128

  static int name_unique(unsigned int irq, struct irqaction *new_action)
@@ -197,20 +305,6 @@ void register_handler_proc(unsigned int
  	action->dir = proc_mkdir(name, irq_dir[irq]);
  	if (!action->dir)
  		return;
-#ifndef CONFIG_PREEMPT_RT
-	{
-		struct proc_dir_entry *entry;
-		/* create /proc/irq/1234/handler/threaded */
-		entry = create_proc_entry("threaded", 0600, action->dir);
-		if (!entry)
-			return;
-		entry->nlink = 1;
-		entry->data = (void *)action;
-		entry->read_proc = threaded_read_proc;
-		entry->write_proc = threaded_write_proc;
-		action->threaded = entry;
-	}
-#endif
  }

  #undef MAX_NAMELEN

--

  parent reply	other threads:[~2006-06-02 21:23 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20060602165336.147812000@localhost>
2006-06-02 22:23 ` [patch 1/5] [PREEMPT_RT] Changing interrupt handlers from running in thread to hardirq and back runtime Esben Nielsen
2006-06-02 22:23 ` Esben Nielsen [this message]
2006-06-03 20:21   ` [patch 2/5] " Steven Rostedt
2006-06-04 17:33     ` Esben Nielsen
2006-06-02 22:23 ` [patch 3/5] " Esben Nielsen
2006-06-03 20:39   ` Steven Rostedt
2006-06-04 17:34     ` Esben Nielsen
2006-06-02 22:23 ` [patch 4/5] " Esben Nielsen
2006-06-03 21:30   ` Steven Rostedt
2006-06-04 22:50     ` Esben Nielsen
2006-06-02 22:23 ` [patch 5/5] " Esben Nielsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Pine.LNX.4.64.0606022321440.9307@localhost \
    --to=nielsen.esben@googlemail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox