Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Jan 2012 22:50:50 +0600
From:      Max Khon <fjoe@samodelkin.net>
To:        current@freebsd.org
Subject:   FILTER_SCHEDULE_THREAD is not a bit-value
Message-ID:  <CADe0-4kO%2BN0bbBByNcUua6SpG%2BHt7bgEm2kaAoESd=KySwNAHA@mail.gmail.com>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Hello!

sys/bus.h documents the following semantics for FILTER_SCHEDULE_THREAD:

/**
 * @brief Driver interrupt filter return values
 *
 * If a driver provides an interrupt filter routine it must return an
 * integer consisting of oring together zero or more of the following
                                 ^^^^^^^
 * flags:
 *
 *      FILTER_STRAY    - this device did not trigger the interrupt
 *      FILTER_HANDLED  - the interrupt has been fully handled and can be EOId
 *      FILTER_SCHEDULE_THREAD - the threaded interrupt handler should be
 *                        scheduled to execute
 *
 * If the driver does not provide a filter, then the interrupt code will
 * act is if the filter had returned FILTER_SCHEDULE_THREAD.  Note that it
 * is illegal to specify any other flag with FILTER_STRAY and that it is
 * illegal to not specify either of FILTER_HANDLED or FILTER_SCHEDULE_THREAD
 * if FILTER_STRAY is not specified.
 */
#define FILTER_STRAY            0x01
#define FILTER_HANDLED          0x02
#define FILTER_SCHEDULE_THREAD  0x04

But actually FILTER_SCHEDULE_THREAD is not used as a bit-value (see
kern/kern_intr.c):

                if (!thread) {
                        if (ret == FILTER_SCHEDULE_THREAD)
                                thread = 1;
                }

There is at least one in-tree driver that could be broken because of
this (asmc(8), but I found the problem with some other out-of-tree
driver).
This should be "if (ret & FILTER_SCHEDULE_THREAD)" instead. Attached
patch fixes the problem.

What do you think?

Max

[-- Attachment #2 --]
Index: sys/kern/kern_intr.c
===================================================================
--- sys/kern/kern_intr.c	(revision 228491)
+++ sys/kern/kern_intr.c	(working copy)
@@ -1449,7 +1449,7 @@
 		 * their own
 		 */
 		if (!thread) {
-			if (ret == FILTER_SCHEDULE_THREAD)
+			if (ret & FILTER_SCHEDULE_THREAD)
 				thread = 1;
 		}
 	}

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CADe0-4kO%2BN0bbBByNcUua6SpG%2BHt7bgEm2kaAoESd=KySwNAHA>