* Re: [PATCH] "extern inline" to "static inline" allows compile
From: Steffen Persvold @ 2002-12-12 23:44 UTC (permalink / raw)
To: Richard Henderson; +Cc: Matt Reppert, trivial, linux-kernel
In-Reply-To: <20021212152448.A5688@twiddle.net>
On Thu, 12 Dec 2002, Richard Henderson wrote:
> On Thu, Dec 12, 2002 at 05:09:02PM -0600, Matt Reppert wrote:
> > Comments?
>
> Revert the asm/pci.h change instead.
>
Is there a reason for the 'extern inline', to me it seems more natural to
have 'static inline' ?
Regards,
--
Steffen Persvold | Scali AS
mailto:sp@scali.com | http://www.scali.com
Tel: (+47) 2262 8950 | Olaf Helsets vei 6
Fax: (+47) 2262 8951 | N0621 Oslo, NORWAY
^ permalink raw reply
* oops: 2.5.51 lock_get_status
From: Alex Riesen @ 2002-12-12 23:38 UTC (permalink / raw)
To: linux-kernel
2.5.51+bk as of 12 Dec 23:00 CET.
tried to strace(4.4) the d4x with follow-fork mode.
d4x is a multi-threaded app using posix advisory locks.
(http://www.krasu.ru/soft/chuchelo/)
The thing calls fcntl, which fails as if the file were locked:
open("/root/linux-2.5.51.tar.bz2", O_RDWR) = -1 ENOENT (No such file or directory)
open("/root/.linux-2.5.51.tar.bz2", O_RDWR|O_CREAT, 0600) = 8
time(NULL) = 1039734705
lseek(8, 0, SEEK_END) = 2377500
fcntl64(8, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=0, len=1}) = -1 EAGAIN (Resource temporarily unavailable)
i cannot guarantee that file wasn't actually locked by,
for instance, a detached and forgotten process of d4x,
because cat /proc/locks got segfault.
Decided it was interesting enough, and reported.
There was an oops in syslog also:
Dec 13 00:13:51 steel kernel: Unable to handle kernel NULL pointer dereference at virtual address 00000008
Dec 13 00:13:51 steel kernel: printing eip:
Dec 13 00:13:51 steel kernel: c01557b0
Dec 13 00:13:51 steel kernel: *pde = 00000000
Dec 13 00:13:51 steel kernel: Oops: 0000
Dec 13 00:13:51 steel kernel: CPU: 0
Dec 13 00:13:51 steel kernel: EIP: 0060:[<c01557b0>] Not tainted
Dec 13 00:13:51 steel kernel: EFLAGS: 00010282
Dec 13 00:13:51 steel kernel: EIP is at lock_get_status+0x18/0x210
Dec 13 00:13:51 steel kernel: eax: 00000000 ebx: d7b0f000 ecx: 00000001 edx: 00000001
Dec 13 00:13:51 steel kernel: esi: dbd164e0 edi: 00000000 ebp: d781bed8 esp: d781becc
Dec 13 00:13:51 steel kernel: ds: 0068 es: 0068 ss: 0068
Dec 13 00:13:51 steel kernel: Process cat (pid: 406, threadinfo=d781a000 task=d9e8a740)
Dec 13 00:13:51 steel kernel: Stack: d781bf0c dbd164e0 dbd164e4 d781bf14 c0155aaa d7b0f000 dbd164e0 00000001
Dec 13 00:13:51 steel kernel: c024d393 d781a000 00000c00 00000c00 d781bf0c d781bf10 00000c00 00000001
Dec 13 00:13:51 steel kernel: d7b0f000 00000000 d781bf38 c016a1b7 d7b0f000 d781bf74 00000000 00000c00
Dec 13 00:13:51 steel kernel: Call Trace:
Dec 13 00:13:51 steel kernel: [<c0155aaa>] get_locks_status+0x7a/0x148
Dec 13 00:13:51 steel kernel: [<c016a1b7>] locks_read_proc+0x37/0x84
Dec 13 00:13:51 steel kernel: [<c0167f68>] proc_file_read+0xdc/0x17c
Dec 13 00:13:51 steel kernel: [<c0142b44>] vfs_read+0xc8/0x160
Dec 13 00:13:51 steel kernel: [<c0142e16>] sys_read+0x2a/0x40
Dec 13 00:13:51 steel kernel: [<c0108b47>] syscall_call+0x7/0xb
Dec 13 00:13:51 steel kernel:
Dec 13 00:13:51 steel kernel: Code: 8b 78 08 8b 45 14 50 8b 45 10 50 68 ac d2 24 c0 53 e8 32 bb
^ permalink raw reply
* Re: general Debian questions
From: lcollins @ 2002-12-12 23:30 UTC (permalink / raw)
To: linux-newbie
In-Reply-To: <5.1.0.14.1.20021209201020.0209fa60@celine>
James I have installed Debian Woody on my laptop without too much
trouble but am having fits trying to get Woody installed on my desktop.
Could you tell me how you did the install using Knoppix? I may try that
route because I do enjoy the distro, just having a tough time getting it
installed.
Lonnie
> At 09:48 PM 12/9/02 +0100, James Miller wrote:
>
>> I've begun using Debian after having spent most of my Linux "career"
>> (all 18 month of it!) on mostly Mandrake and Red Hat. I've come to
>> really like Debian, especially the apt-get installation and update
>> routine. I'm considering defecting to Debian. True, I was spared the
>> majority of Debian install problems by using the install-to-hard-disk
>> utility that was written for Knoppix. It worked quite well, actually. I
>> think it was the least painful Linux install I've been through - and
>> I've been through more than I can count. At any rate, before devoting
>> full alegiance to Debian, I thought I'd ask onlist some general feedback
>> on the distro, both pro and con. I use my computer strictly as a
>> workstation, though I am considering setting up a tiny home network on
>> the LTSP model - something about the "target system." I guess I'd like
>> to start off on Debian feedback asking some particulars about how and
>> how often packages are updated? I understand Debian tends to "run
>> behind" with respect to the other distros. As I understand it, new
>> releases of the OS itself occur with far less frequency than the distros
>> I'm used to. But the packages (what, under M$ systems, would be called
>> "3rd party apps," as I understand it), surely, must be upgraded with
>> greater frequency, are they not?
>>
>> Thanks in advance for feedback on this issue.
>
-
To unsubscribe from this list: send the line "unsubscribe linux-newbie" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.linux-learn.org/faqs
^ permalink raw reply
* [PATCH] BIN_TO_BCD consolidation
From: Hollis Blanchard @ 2002-12-12 23:32 UTC (permalink / raw)
To: Linux Kernel Mailing List
[-- Attachment #1.1: Type: text/plain, Size: 3263 bytes --]
All I wanted to do was "secal = BIN_TO_BCD(secs % 60)" ...
Has anyone else noticed the number of BCD_TO_BIN / BIN_TO_BCD
definitions?
egrep -lr -e "define (BCD_TO_BIN|BIN_TO_BCD)" linux/
Definitions are all over (in arch C files, arch includes, generic
includes, even a SCSI C file). They're all identical. They're almost all
wrapped with #ifndef to keep from clobbering each other.
My biggest problem is that they make an assignment:
#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
This makes it impossible to write code like
secal = BIN_TO_BCD(secs % 60);
because 'secs % 60' is not an lvalue.
The following patch moves all those definitions into include/linux/bcd.h
and defines BIN2BCD which doesn't make an assignment. I don't care what
it's called if that offends anyone; I just want to be able to do it. I'd
like to see BIN_TO_BCD deprecated, but maybe that's just me.
I tried to catch everything; I apologize if I missed an instance or two.
Obviously I couldn't test it all, but it builds on PPC. Comments?
-Hollis
--
PowerPC Linux
IBM Linux Technology Center
arch/alpha/kernel/time.c | 1 +
arch/arm/kernel/time.c | 8 --------
arch/cris/drivers/ds1302.c | 1 +
arch/cris/kernel/time.c | 1 +
arch/i386/kernel/time.c | 1 +
arch/m68k/atari/time.c | 1 +
arch/m68k/sun3x/time.c | 4 +---
arch/mips/ddb5xxx/common/rtc_ds1386.c | 7 +------
arch/mips/dec/time.c | 1 +
arch/mips/kernel/old-time.c | 1 +
arch/mips64/sgi-ip27/ip27-rtc.c | 1 +
arch/mips64/sgi-ip27/ip27-timer.c | 1 +
arch/ppc/iSeries/mf.c | 1 +
arch/ppc/platforms/chrp_time.c | 1 +
arch/ppc/platforms/gemini_setup.c | 1 +
arch/ppc/platforms/prep_time.c | 1 +
arch/ppc/syslib/todc_time.c | 1 +
arch/ppc64/kernel/mf.c | 1 +
arch/ppc64/kernel/rtc.c | 1 +
arch/sh/kernel/rtc.c | 9 +--------
arch/sparc64/kernel/time.c | 9 +--------
arch/x86_64/kernel/time.c | 1 +
drivers/acorn/char/pcf8583.c | 1 +
drivers/acpi/sleep.c | 1 +
drivers/char/rtc.c | 1 +
drivers/scsi/sr_vendor.c | 3 +--
drivers/sgi/char/ds1286.c | 1 +
include/asm-arm/arch-ebsa285/time.h | 1 +
include/asm-cris/rtc.h | 5 -----
include/asm-generic/rtc.h | 1 +
include/asm-mips/ds1286.h | 11 -----------
include/asm-mips64/ds1286.h | 11 -----------
include/asm-mips64/m48t35.h | 8 --------
include/asm-ppc/m48t35.h | 9 ---------
include/asm-ppc/mk48t59.h | 8 --------
include/asm-ppc/nvram.h | 8 --------
include/asm-ppc/todc.h | 8 --------
include/asm-ppc64/nvram.h | 8 --------
include/linux/bcd.h | 20 ++++++++++++++++++++
include/linux/mc146818rtc.h | 11 -----------
40 files changed, 48 insertions(+), 122 deletions(-)
[-- Attachment #1.2: bcd-consolidate.diff --]
[-- Type: text/plain, Size: 20763 bytes --]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.744 -> 1.745
# include/asm-ppc/m48t35.h 1.5 -> 1.6
# drivers/acpi/sleep.c 1.8 -> 1.9
# arch/ppc/platforms/chrp_time.c 1.7 -> 1.8
# include/asm-cris/rtc.h 1.2 -> 1.3
# include/asm-ppc/mk48t59.h 1.4 -> 1.5
# drivers/sgi/char/ds1286.c 1.6 -> 1.7
# arch/mips64/sgi-ip27/ip27-timer.c 1.3 -> 1.4
# drivers/char/rtc.c 1.18 -> 1.19
# include/asm-ppc64/nvram.h 1.2 -> 1.3
# include/asm-generic/rtc.h 1.1 -> 1.2
# arch/ppc/iSeries/mf.c 1.2 -> 1.3
# arch/mips64/sgi-ip27/ip27-rtc.c 1.5 -> 1.6
# drivers/scsi/sr_vendor.c 1.10 -> 1.11
# arch/i386/kernel/time.c 1.22 -> 1.23
# arch/ppc/platforms/prep_time.c 1.7 -> 1.8
# arch/sparc64/kernel/time.c 1.18 -> 1.19
# include/asm-mips64/m48t35.h 1.1 -> 1.2
# arch/ppc/platforms/gemini_setup.c 1.12 -> 1.13
# arch/alpha/kernel/time.c 1.11 -> 1.12
# arch/cris/kernel/time.c 1.6 -> 1.7
# arch/ppc64/kernel/rtc.c 1.3 -> 1.4
# include/asm-mips/ds1286.h 1.1 -> 1.2
# arch/m68k/sun3x/time.c 1.4 -> 1.5
# include/asm-mips64/ds1286.h 1.2 -> 1.3
# arch/x86_64/kernel/time.c 1.5 -> 1.6
# arch/arm/kernel/time.c 1.11 -> 1.12
# arch/mips/kernel/old-time.c 1.3 -> 1.4
# arch/ppc64/kernel/mf.c 1.3 -> 1.4
# include/asm-ppc/todc.h 1.1 -> 1.2
# arch/ppc/syslib/todc_time.c 1.4 -> 1.5
# arch/m68k/atari/time.c 1.3 -> 1.4
# arch/mips/dec/time.c 1.2 -> 1.3
# arch/mips/ddb5xxx/common/rtc_ds1386.c 1.1 -> 1.2
# include/linux/mc146818rtc.h 1.2 -> 1.3
# arch/sh/kernel/rtc.c 1.5 -> 1.6
# arch/cris/drivers/ds1302.c 1.4 -> 1.5
# drivers/acorn/char/pcf8583.c 1.5 -> 1.6
# include/asm-ppc/nvram.h 1.4 -> 1.5
# include/asm-arm/arch-ebsa285/time.h 1.5 -> 1.6
# (new) -> 1.1 include/linux/bcd.h
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/12/12 hollis@granite.austin.ibm.com 1.745
# consolidate all the BCD_TO_BIN / BIN_TO_BCD definitions into bcd.h
# --------------------------------------------
#
diff -Nru a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
--- a/arch/alpha/kernel/time.c Thu Dec 12 17:29:52 2002
+++ b/arch/alpha/kernel/time.c Thu Dec 12 17:29:52 2002
@@ -37,6 +37,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/init.h>
+#include <linux/bcd.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
--- a/arch/arm/kernel/time.c Thu Dec 12 17:29:52 2002
+++ b/arch/arm/kernel/time.c Thu Dec 12 17:29:52 2002
@@ -47,14 +47,6 @@
/* change this if you have some constant time drift */
#define USECS_PER_JIFFY (1000000/HZ)
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
static int dummy_set_rtc(void)
{
return 0;
diff -Nru a/arch/cris/drivers/ds1302.c b/arch/cris/drivers/ds1302.c
--- a/arch/cris/drivers/ds1302.c Thu Dec 12 17:29:52 2002
+++ b/arch/cris/drivers/ds1302.c Thu Dec 12 17:29:52 2002
@@ -97,6 +97,7 @@
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
+#include <linux/bcd.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff -Nru a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
--- a/arch/cris/kernel/time.c Thu Dec 12 17:29:52 2002
+++ b/arch/cris/kernel/time.c Thu Dec 12 17:29:52 2002
@@ -32,6 +32,7 @@
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/delay.h>
+#include <linux/bcd.h>
#include <asm/segment.h>
#include <asm/io.h>
diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
--- a/arch/i386/kernel/time.c Thu Dec 12 17:29:52 2002
+++ b/arch/i386/kernel/time.c Thu Dec 12 17:29:52 2002
@@ -43,6 +43,7 @@
#include <linux/smp.h>
#include <linux/module.h>
#include <linux/device.h>
+#include <linux/bcd.h>
#include <asm/io.h>
#include <asm/smp.h>
diff -Nru a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
--- a/arch/m68k/atari/time.c Thu Dec 12 17:29:52 2002
+++ b/arch/m68k/atari/time.c Thu Dec 12 17:29:52 2002
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/rtc.h>
+#include <linux/bcd.h>
#include <asm/rtc.h>
diff -Nru a/arch/m68k/sun3x/time.c b/arch/m68k/sun3x/time.c
--- a/arch/m68k/sun3x/time.c Thu Dec 12 17:29:52 2002
+++ b/arch/m68k/sun3x/time.c Thu Dec 12 17:29:52 2002
@@ -11,6 +11,7 @@
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
#include <linux/rtc.h>
+#include <linux/bcd.h>
#include <asm/irq.h>
#include <asm/io.h>
@@ -35,9 +36,6 @@
#define C_READ 0x40
#define C_SIGN 0x20
#define C_CALIB 0x1f
-
-#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
-#define BIN_TO_BCD(val) (((val/10) << 4) | (val % 10))
int sun3x_hwclk(int set, struct rtc_time *t)
{
diff -Nru a/arch/mips/ddb5xxx/common/rtc_ds1386.c b/arch/mips/ddb5xxx/common/rtc_ds1386.c
--- a/arch/mips/ddb5xxx/common/rtc_ds1386.c Thu Dec 12 17:29:52 2002
+++ b/arch/mips/ddb5xxx/common/rtc_ds1386.c Thu Dec 12 17:29:52 2002
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/time.h>
+#include <linux/bcd.h>
#include <asm/time.h>
#include <asm/addrspace.h>
@@ -27,12 +28,6 @@
#include <asm/ddb5xxx/debug.h>
#define EPOCH 2000
-
-#undef BCD_TO_BIN
-#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
-
-#undef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
#define READ_RTC(x) *(volatile unsigned char*)(rtc_base+x)
#define WRITE_RTC(x, y) *(volatile unsigned char*)(rtc_base+x) = y
diff -Nru a/arch/mips/dec/time.c b/arch/mips/dec/time.c
--- a/arch/mips/dec/time.c Thu Dec 12 17:29:52 2002
+++ b/arch/mips/dec/time.c Thu Dec 12 17:29:52 2002
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
+#include <linux/bcd.h>
#include <asm/cpu.h>
#include <asm/bootinfo.h>
diff -Nru a/arch/mips/kernel/old-time.c b/arch/mips/kernel/old-time.c
--- a/arch/mips/kernel/old-time.c Thu Dec 12 17:29:52 2002
+++ b/arch/mips/kernel/old-time.c Thu Dec 12 17:29:52 2002
@@ -16,6 +16,7 @@
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
+#include <linux/bcd.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
diff -Nru a/arch/mips64/sgi-ip27/ip27-rtc.c b/arch/mips64/sgi-ip27/ip27-rtc.c
--- a/arch/mips64/sgi-ip27/ip27-rtc.c Thu Dec 12 17:29:52 2002
+++ b/arch/mips64/sgi-ip27/ip27-rtc.c Thu Dec 12 17:29:52 2002
@@ -35,6 +35,7 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/smp_lock.h>
+#include <linux/bcd.h>
#include <asm/m48t35.h>
#include <asm/sn/ioc3.h>
diff -Nru a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c
--- a/arch/mips64/sgi-ip27/ip27-timer.c Thu Dec 12 17:29:52 2002
+++ b/arch/mips64/sgi-ip27/ip27-timer.c Thu Dec 12 17:29:52 2002
@@ -11,6 +11,7 @@
#include <linux/param.h>
#include <linux/timex.h>
#include <linux/mm.h>
+#include <linux/bcd.h>
#include <asm/pgtable.h>
#include <asm/sgialib.h>
diff -Nru a/arch/ppc/iSeries/mf.c b/arch/ppc/iSeries/mf.c
--- a/arch/ppc/iSeries/mf.c Thu Dec 12 17:29:52 2002
+++ b/arch/ppc/iSeries/mf.c Thu Dec 12 17:29:52 2002
@@ -40,6 +40,7 @@
#include <asm/iSeries/iSeries_proc.h>
#include <asm/uaccess.h>
#include <linux/pci.h>
+#include <linux/bcd.h>
/*
diff -Nru a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
--- a/arch/ppc/platforms/chrp_time.c Thu Dec 12 17:29:52 2002
+++ b/arch/ppc/platforms/chrp_time.c Thu Dec 12 17:29:52 2002
@@ -20,6 +20,7 @@
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <linux/init.h>
+#include <linux/bcd.h>
#include <asm/segment.h>
#include <asm/io.h>
diff -Nru a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c
--- a/arch/ppc/platforms/gemini_setup.c Thu Dec 12 17:29:52 2002
+++ b/arch/ppc/platforms/gemini_setup.c Thu Dec 12 17:29:52 2002
@@ -24,6 +24,7 @@
#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
+#include <linux/bcd.h>
#include <asm/system.h>
#include <asm/pgtable.h>
diff -Nru a/arch/ppc/platforms/prep_time.c b/arch/ppc/platforms/prep_time.c
--- a/arch/ppc/platforms/prep_time.c Thu Dec 12 17:29:52 2002
+++ b/arch/ppc/platforms/prep_time.c Thu Dec 12 17:29:52 2002
@@ -19,6 +19,7 @@
#include <linux/timex.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
+#include <linux/bcd.h>
#include <asm/sections.h>
#include <asm/segment.h>
diff -Nru a/arch/ppc/syslib/todc_time.c b/arch/ppc/syslib/todc_time.c
--- a/arch/ppc/syslib/todc_time.c Thu Dec 12 17:29:52 2002
+++ b/arch/ppc/syslib/todc_time.c Thu Dec 12 17:29:52 2002
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/timex.h>
+#include <linux/bcd.h>
#include <asm/machdep.h>
#include <asm/io.h>
diff -Nru a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c
--- a/arch/ppc64/kernel/mf.c Thu Dec 12 17:29:52 2002
+++ b/arch/ppc64/kernel/mf.c Thu Dec 12 17:29:52 2002
@@ -40,6 +40,7 @@
#include <asm/iSeries/iSeries_proc.h>
#include <asm/uaccess.h>
#include <linux/pci.h>
+#include <linux/bcd.h>
extern struct pci_dev * iSeries_vio_dev;
diff -Nru a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
--- a/arch/ppc64/kernel/rtc.c Thu Dec 12 17:29:52 2002
+++ b/arch/ppc64/kernel/rtc.c Thu Dec 12 17:29:52 2002
@@ -32,6 +32,7 @@
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
+#include <linux/bcd.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff -Nru a/arch/sh/kernel/rtc.c b/arch/sh/kernel/rtc.c
--- a/arch/sh/kernel/rtc.c Thu Dec 12 17:29:52 2002
+++ b/arch/sh/kernel/rtc.c Thu Dec 12 17:29:52 2002
@@ -9,17 +9,10 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
+#include <linux/bcd.h>
#include <asm/io.h>
#include <asm/rtc.h>
-
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
void sh_rtc_gettimeofday(struct timeval *tv)
{
diff -Nru a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c Thu Dec 12 17:29:52 2002
+++ b/arch/sparc64/kernel/time.c Thu Dec 12 17:29:52 2002
@@ -23,6 +23,7 @@
#include <linux/mc146818rtc.h>
#include <linux/delay.h>
#include <linux/profile.h>
+#include <linux/bcd.h>
#include <asm/oplib.h>
#include <asm/mostek.h>
@@ -329,14 +330,6 @@
return (data1 == data2); /* Was the write blocked? */
}
-
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
-#endif
/* Probe for the real time clock chip. */
static void __init set_system_time(void)
diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c Thu Dec 12 17:29:52 2002
+++ b/arch/x86_64/kernel/time.c Thu Dec 12 17:29:52 2002
@@ -21,6 +21,7 @@
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/device.h>
+#include <linux/bcd.h>
#include <asm/vsyscall.h>
#include <asm/timex.h>
diff -Nru a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c
--- a/drivers/acorn/char/pcf8583.c Thu Dec 12 17:29:52 2002
+++ b/drivers/acorn/char/pcf8583.c Thu Dec 12 17:29:52 2002
@@ -14,6 +14,7 @@
#include <linux/string.h>
#include <linux/mc146818rtc.h>
#include <linux/init.h>
+#include <linux/bcd.h>
#include "pcf8583.h"
diff -Nru a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
--- a/drivers/acpi/sleep.c Thu Dec 12 17:29:52 2002
+++ b/drivers/acpi/sleep.c Thu Dec 12 17:29:52 2002
@@ -16,6 +16,7 @@
#include <linux/device.h>
#include <linux/suspend.h>
#include <linux/seq_file.h>
+#include <linux/bcd.h>
#include <asm/uaccess.h>
#include <asm/acpi.h>
diff -Nru a/drivers/char/rtc.c b/drivers/char/rtc.c
--- a/drivers/char/rtc.c Thu Dec 12 17:29:52 2002
+++ b/drivers/char/rtc.c Thu Dec 12 17:29:52 2002
@@ -72,6 +72,7 @@
#include <linux/spinlock.h>
#include <linux/sysctl.h>
#include <linux/wait.h>
+#include <linux/bcd.h>
#include <asm/current.h>
#include <asm/uaccess.h>
diff -Nru a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c
--- a/drivers/scsi/sr_vendor.c Thu Dec 12 17:29:52 2002
+++ b/drivers/scsi/sr_vendor.c Thu Dec 12 17:29:52 2002
@@ -37,6 +37,7 @@
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/bcd.h>
#include <linux/blk.h>
#include "scsi.h"
@@ -150,8 +151,6 @@
/* This function gets called after a media change. Checks if the CD is
multisession, asks for offset etc. */
-
-#define BCD_TO_BIN(x) ((((int)x & 0xf0) >> 4)*10 + ((int)x & 0x0f))
int sr_cd_check(struct cdrom_device_info *cdi)
{
diff -Nru a/drivers/sgi/char/ds1286.c b/drivers/sgi/char/ds1286.c
--- a/drivers/sgi/char/ds1286.c Thu Dec 12 17:29:52 2002
+++ b/drivers/sgi/char/ds1286.c Thu Dec 12 17:29:52 2002
@@ -36,6 +36,7 @@
#include <linux/poll.h>
#include <linux/rtc.h>
#include <linux/spinlock.h>
+#include <linux/bcd.h>
#include <asm/ds1286.h>
#include <asm/io.h>
diff -Nru a/include/asm-arm/arch-ebsa285/time.h b/include/asm-arm/arch-ebsa285/time.h
--- a/include/asm-arm/arch-ebsa285/time.h Thu Dec 12 17:29:52 2002
+++ b/include/asm-arm/arch-ebsa285/time.h Thu Dec 12 17:29:52 2002
@@ -18,6 +18,7 @@
#define RTC_ALWAYS_BCD 0
#include <linux/mc146818rtc.h>
+#include <linux/bcd.h>
#include <asm/hardware/dec21285.h>
#include <asm/leds.h>
diff -Nru a/include/asm-cris/rtc.h b/include/asm-cris/rtc.h
--- a/include/asm-cris/rtc.h Thu Dec 12 17:29:52 2002
+++ b/include/asm-cris/rtc.h Thu Dec 12 17:29:52 2002
@@ -39,11 +39,6 @@
#define RTC_INIT() (-1)
#endif
-/* conversions to and from the stupid RTC internal format */
-
-#define BCD_TO_BIN(x) x = (((x & 0xf0) >> 3) * 5 + (x & 0xf))
-#define BIN_TO_BCD(x) x = (x % 10) | ((x / 10) << 4)
-
/*
* The struct used to pass data via the following ioctl. Similar to the
* struct tm in <time.h>, but it needs to be here so that the kernel
diff -Nru a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h
--- a/include/asm-generic/rtc.h Thu Dec 12 17:29:52 2002
+++ b/include/asm-generic/rtc.h Thu Dec 12 17:29:52 2002
@@ -16,6 +16,7 @@
#include <linux/mc146818rtc.h>
#include <linux/rtc.h>
+#include <linux/bcd.h>
#define RTC_PIE 0x40 /* periodic interrupt enable */
#define RTC_AIE 0x20 /* alarm interrupt enable */
diff -Nru a/include/asm-mips/ds1286.h b/include/asm-mips/ds1286.h
--- a/include/asm-mips/ds1286.h Thu Dec 12 17:29:52 2002
+++ b/include/asm-mips/ds1286.h Thu Dec 12 17:29:52 2002
@@ -57,15 +57,4 @@
#define RTC_IPSW 0x40
#define RTC_TE 0x80
-/*
- * Conversion between binary and BCD.
- */
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
#endif /* _ASM_DS1286_h */
diff -Nru a/include/asm-mips64/ds1286.h b/include/asm-mips64/ds1286.h
--- a/include/asm-mips64/ds1286.h Thu Dec 12 17:29:52 2002
+++ b/include/asm-mips64/ds1286.h Thu Dec 12 17:29:52 2002
@@ -56,15 +56,4 @@
#define RTC_IPSW 0x40
#define RTC_TE 0x80
-/*
- * Conversion between binary and BCD.
- */
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
#endif /* _ASM_DS1286_h */
diff -Nru a/include/asm-mips64/m48t35.h b/include/asm-mips64/m48t35.h
--- a/include/asm-mips64/m48t35.h Thu Dec 12 17:29:52 2002
+++ b/include/asm-mips64/m48t35.h Thu Dec 12 17:29:52 2002
@@ -21,12 +21,4 @@
#define M48T35_RTC_STOPPED 0x80
#define M48T35_RTC_READ 0x40
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(x) ((x)=((x)&15) + ((x)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(x) ((x)=(((x)/10)<<4) + (x)%10)
-#endif
-
#endif
diff -Nru a/include/asm-ppc/m48t35.h b/include/asm-ppc/m48t35.h
--- a/include/asm-ppc/m48t35.h Thu Dec 12 17:29:52 2002
+++ b/include/asm-ppc/m48t35.h Thu Dec 12 17:29:52 2002
@@ -74,13 +74,4 @@
#define M48T35_RTC_READ 0x40
-/* read/write conversions */
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(x) ((x)=((x)&15) + ((x)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(x) ((x)=(((x)/10)<<4) + (x)%10)
-#endif
-
#endif
diff -Nru a/include/asm-ppc/mk48t59.h b/include/asm-ppc/mk48t59.h
--- a/include/asm-ppc/mk48t59.h Thu Dec 12 17:29:52 2002
+++ b/include/asm-ppc/mk48t59.h Thu Dec 12 17:29:52 2002
@@ -24,12 +24,4 @@
#define MK48T59_RTC_CONTROLB 0x1FF9
#define MK48T59_RTC_CB_STOP 0x80
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
#endif /* _PPC_MK48T59_H */
diff -Nru a/include/asm-ppc/nvram.h b/include/asm-ppc/nvram.h
--- a/include/asm-ppc/nvram.h Thu Dec 12 17:29:52 2002
+++ b/include/asm-ppc/nvram.h Thu Dec 12 17:29:52 2002
@@ -23,14 +23,6 @@
#define MOTO_RTC_CONTROLA 0x1FF8
#define MOTO_RTC_CONTROLB 0x1FF9
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
/* PowerMac specific nvram stuffs */
enum {
diff -Nru a/include/asm-ppc/todc.h b/include/asm-ppc/todc.h
--- a/include/asm-ppc/todc.h Thu Dec 12 17:29:52 2002
+++ b/include/asm-ppc/todc.h Thu Dec 12 17:29:52 2002
@@ -355,14 +355,6 @@
todc_info->flags = clock_type ##_FLAGS; \
}
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
extern todc_info_t *todc_info;
unsigned char todc_direct_read_val(int addr);
diff -Nru a/include/asm-ppc64/nvram.h b/include/asm-ppc64/nvram.h
--- a/include/asm-ppc64/nvram.h Thu Dec 12 17:29:52 2002
+++ b/include/asm-ppc64/nvram.h Thu Dec 12 17:29:52 2002
@@ -28,12 +28,4 @@
#define MOTO_RTC_CONTROLA 0x1FF8
#define MOTO_RTC_CONTROLB 0x1FF9
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
#endif /* _PPC64_NVRAM_H */
diff -Nru a/include/linux/bcd.h b/include/linux/bcd.h
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/include/linux/bcd.h Thu Dec 12 17:29:52 2002
@@ -0,0 +1,20 @@
+/* Permission is hereby granted to copy, modify and redistribute this code
+ * in terms of the GNU Library General Public License, Version 2 or later,
+ * at your option.
+ */
+
+/* macros to translate to/from binary and binary-coded decimal (frequently
+ * found in RTC chips).
+ */
+
+#ifndef _BCD_H
+#define _BCD_H
+
+#define BCD2BIN(val) (((val) & 0x0f) + ((val)>>4)*10)
+#define BIN2BCD(val) ((((val)/10)<<4) + (val)%10)
+
+/* backwards compat */
+#define BCD_TO_BIN(val) ((val)=BCD2BIN(val))
+#define BIN_TO_BCD(val) ((val)=BIN2BCD(val))
+
+#endif /* _BCD_H */
diff -Nru a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h
--- a/include/linux/mc146818rtc.h Thu Dec 12 17:29:52 2002
+++ b/include/linux/mc146818rtc.h Thu Dec 12 17:29:52 2002
@@ -87,15 +87,4 @@
# define RTC_VRT 0x80 /* valid RAM and time */
/**********************************************************************/
-/* example: !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
- * determines if the following two #defines are needed
- */
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
#endif /* _MC146818RTC_H */
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH] "extern inline" to "static inline" allows compile
From: Richard Henderson @ 2002-12-12 23:24 UTC (permalink / raw)
To: Matt Reppert; +Cc: trivial, linux-kernel
In-Reply-To: <20021212170902.34e344b1.arashi@arashi.yi.org>
On Thu, Dec 12, 2002 at 05:09:02PM -0600, Matt Reppert wrote:
> Comments?
Revert the asm/pci.h change instead.
r~
^ permalink raw reply
* Re: Move 405LP RTC support from beech.c into ibm405lp.c
From: David Gibson @ 2002-12-12 23:13 UTC (permalink / raw)
To: Hollis Blanchard; +Cc: embedded list
In-Reply-To: <1039709875.3537.20.camel@granite.austin.ibm.com>
On Thu, Dec 12, 2002 at 10:17:44AM -0600, Hollis Blanchard wrote:
> On Wed, 2002-12-11 at 21:54, David Gibson wrote:
> >
> > The RTC support (written by Todd Poynor) for the Beech is actually in
> > the 405LP chip itself, not just on the Beech board.
> <snip>
>
> As a separate patch (either before or after your move), I'd like to see
> the following patch committed. The current "reset" code doesn't follow
> the sequence described in the manual, and doesn't really reset the chip.
> Until I added this code, the RTC usually would simply not advance. I've
> tested this thoroughly on Beech (405LP 1.1).
Well, I've committed my patch (and I also moved the 405LP's
PPC4xx_ONB_IO_PADDR definition into ibm405lp.h). Could you redo your
patch against the current tree?
> Also, the comment makes me curious - why rely on the BIOS to set the
> right input frequency? It's just one more line of code here (and a
> #define or two for the various boards).
Well, I'd be in favour of setting it here (under my philosphy of
"never trust the firmware not to be crap").
--
David Gibson | For every complex problem there is a
david@gibson.dropbear.id.au | solution which is simple, neat and
| wrong.
http://www.ozlabs.org/people/dgibson
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply
* Re: [PATCH] sys_epoll for 2.4
From: Davide Libenzi @ 2002-12-12 23:22 UTC (permalink / raw)
To: Janet Morgan; +Cc: linux-kernel
In-Reply-To: <200212122303.gBCN3O721003@eng2.beaverton.ibm.com>
[...]
Thank you very much Janet ! The patch looks good and I'm hosting it here :
http://www.xmailserver.org/linux-patches/nio-improve.html#patches
- Davide
^ permalink raw reply
* Re: 2.5.51: sleep broken
From: P. Christeas @ 2002-12-12 23:11 UTC (permalink / raw)
To: Grover, Andrew, acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <EDC461A30AC4D511ADE10002A5072CAD04C7A591-OU+JdkIUtvd9zuciVAfUoVDQ4js95KgL@public.gmane.org>
> > From: P. Christeas [mailto:p_christ-U04EIuiosng@public.gmane.org]
> >
> > > However, /proc/acpi/sleep has all S0 S1 S2 S3 S4 S5
> > > When I 'echo 1 >/proc/acpi/sleep', nothing happens.
> > > ... It's a procfs bug.
>
> Look for a msg on 11/30 by Pavel Machek. Apparently the proc code got
> broken by the seq_file stuff... supposedly they were going to fix it, but
> maybe it would be easier if we all did.
>
> - entry->write_proc = acpi_system_write_sleep;
> + entry->proc_fops->write = acpi_system_write_sleep;
>
> Regards -- Andy
Sorry, I was quite lazy debugging that. Seems though that 20021205 doesn't
have that. I'll let you know if it should be pushed into 2.5.52..
-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
^ permalink raw reply
* Re: [PATCH] s390 (8/8): export sys_wait4.
From: Pete Zaitcev @ 2002-12-12 23:17 UTC (permalink / raw)
To: Roberto Nibali; +Cc: Pete Zaitcev, linux-kernel
In-Reply-To: <3DF8FD59.9030100@drugphish.ch>
> Date: Thu, 12 Dec 2002 22:19:21 +0100
> From: Roberto Nibali <ratz@drugphish.ch>
> >>+EXPORT_SYMBOL(sys_wait4);
> >
> > Martin, hold on just a second. Last I checked, sys_wait4 was
> > used ONLY by a moronic code in ipvs, _and_ there was a comment
> > by the author above it "we are too lazy to do it properly".
> > Do you have a better reason to export it?
>
> Guess I'm the malefactor this time since I've sent this patch to Martin
> after some email exchanges with a guy that wanted LVS to work on a s390.
> I reckon I will fix the said moronic code to use a syscall wrapper for
> sys_wait4() so we don't step on anyone's toes.
I should not have called it moronic. Everyone has schedule
constraints. I am wondering though, if the LVS and ipvs
module are maintained actively. Perhaps I owe them a patch.
-- Pete
^ permalink raw reply
* [LARTC] my qos-cbq didn't work
From: James Ma @ 2002-12-12 23:09 UTC (permalink / raw)
To: lartc
[-- Attachment #1: Type: text/plain, Size: 1591 bytes --]
Hi, All,
I implemented the following qos scripts in my Linux gateway (redhat7.3, kernel 2.4.18), put ftp server (10.10.3.49) on one side (eth0 nic) and ftp client (10.10.5.3) on the other side (eth1 nic). I tried to up load a file (211kbytes) from client to ftp server. I wanted to see a 22kbps transmission rate. Quite surprise, the ftp client showed transmission rate as 6.8e+02 kbytes/s (211k transmitted in 0.3 seconds). It was the same as it without qos implementation. So the conclusion is the QoS was not working at all.
Could anybody tell me what's wrong with the setting?
Thanks,
James
#!/bin/sh
OPTION="allot 1514 maxburst 20 avpkt 500"
tc qdisc del dev eth0 root
tc qdisc add dev eth0 root handle 10: cbq bandwidth 10mbit avpkt 500
tc class add dev eth0 parent 10:0 classid 10:2 cbq bandwidth 10mbit rate 22kbps $OPTION prio 3 bounded
tc qdisc add dev eth0 parent 10:2 handle 20: cbq bandwidth 10mbit allot 1514 avpkt 500
tc class add dev eth0 parent 20: classid 20:10 cbq bandwidth 10mbit rate 11kbps $OPTION prio 3 bounded
tc class add dev eth0 parent 20: classid 20:20 cbq bandwidth 10mbit rate 11kbps $OPTION prio3 bounded
tc filter add dev eth0 parent 10: protocol ip prio 3 u32 match ip tos 0xa0 0xff flowid 10:2
tc filter add dev eth0 parent 10: protocol ip prio 3 u32 match ip src 10.10.5.3/24 flowid 10:2
tc filter add dev eth0 parent 20: protocol ip prio 3 u32 match ip tos 0xa0 0xff flowid 20:10
tc filter add dev eth0 parent 20: protocol ip prio 3 u32 match ip src 10.10.5.3/24 flowid 20:20
[-- Attachment #2: Type: text/html, Size: 2189 bytes --]
^ permalink raw reply
* Re: using 2 TB in real life
From: Andries.Brouwer @ 2002-12-12 23:15 UTC (permalink / raw)
To: anders.henke, linux-kernel; +Cc: marcelo
> SCSI device sdb: -320126976 512-byte hdwr sectors (-163904 MB)
Yes, the code in 2.4.20 works up to 30 bits.
A slight modification works up to 31 bits.
[This is cosmetic only.]
Andries
--- /linux/2.4/linux-2.4.20/linux/drivers/scsi/sd.c Sat Aug 3 02:39:44 2002
+++ ./sd.c Fri Dec 13 00:12:00 2002
@@ -1001,7 +1001,7 @@
*/
int m;
int hard_sector = sector_size;
- int sz = rscsi_disks[i].capacity * (hard_sector/256);
+ unsigned int sz = (rscsi_disks[i].capacity/2) * (hard_sector/256);
/* There are 16 minors allocated for each major device */
for (m = i << 4; m < ((i + 1) << 4); m++) {
@@ -1009,9 +1009,9 @@
}
printk("SCSI device %s: "
- "%d %d-byte hdwr sectors (%d MB)\n",
+ "%u %d-byte hdwr sectors (%d MB)\n",
nbuff, rscsi_disks[i].capacity,
- hard_sector, (sz/2 - sz/1250 + 974)/1950);
+ hard_sector, (sz - sz/625 + 974)/1950);
}
/* Rescale capacity to 512-byte units */
^ permalink raw reply
* Re: [LARTC] VRRPD (rfc2338)
From: sabat @ 2002-12-12 23:05 UTC (permalink / raw)
To: lartc
In-Reply-To: <marc-lartc-103950635007394@msgid-missing>
[-- Attachment #1: Type: text/plain, Size: 3055 bytes --]
Dmitry Golubev wrote:
>But as far as I know, there is no VRRP implementations that fully comply
>with rfc2338 as it requires multiple MAC addresses for the one poor linux
>box's interface. Maybe, someone can suggest a working solution of this
>problem?
>
Yes, there is a way -- the VLAN code in the linux kernel supports
setting the MAC address of virtual interfaces (eth0.5, for instance).
AFAIC, this is much superior (in concept) to multicast MACs, given the
Cisco problem.
>
>I have seen one idea, but haven't tested it yet (hope someone can try it out):
>
>To bridge the physical iface with TAP on which the vrrpd (or keepalived) is
>running. In that case we could make the VRRP-router that fully comply with RFC.
>
>For more info see: http://www.math.leidenuniv.nl/pipermail/bridge/2002-June/002021.html
>
>BR, Dmitry
>
>======= At 2002-12-11, 03:56:00 you wrote: =======
>
>
>
>>The daemon at http://www.keepalived.org/ is the VRRPd implementation
>>that's supposed to be the best. It's actually part of the Linux Virtual
>>Server project (layer 4 load balancer), but the author claims you should
>>be able to use it as a pure VRRP daemon -- although when I've read the
>>doc, I couldn't figure out how. (But don't be discouraged by my
>>impatience. :) It's supposed to be the most mature and ready-for-production.
>>
>>There's also Jerome Etienne's reference implementation (don't have a
>>URL, but it's easy to Google). However, I've heard from more than place
>>that this is too proof-of-concept and perhaps not production-worthy.
>>Here's a link to a paper about running VRRPd as the hotspare protocol
>>for linux firewalls (uses Jerome Etienne's implementation):
>>http://www.gnusec.com/resource/security/docs/HAFirewallLinux-VRRP.pdf.
>>
>>BTW, keep in mind that if you intend to use VRRP in an environment with
>>Cisco routers, you'll need to do some work on them too. Cisco routers do
>>not accept multicast MAC addresses as legit ARP replies by default.
>>Unfortunately, the VRRP RFC and all implementations use multicast MACs.
>>What that means is that you'll need to either 1) turn the switch on the
>>Cisco routers that makes them accept multicast MAC ARP replies (good),
>>or 2) put a static ARP entry in the Cisco routers for the VRRP multicast
>>MACs (better).
>>
>>Hope that helps.
>>
>>-S
>>
>>
>>Anton Tinchev wrote:
>>
>>
>>
>>>Can someone point me for good VRRPD (rfc2338) implementation on linux.
>>>Some stable and live project
>>>Thanks
>>>
>>>_______________________________________________
>>>LARTC mailing list / LARTC@mailman.ds9a.nl
>>>http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/
>>>
>>>
>>>
>>>
>>_______________________________________________
>>LARTC mailing list / LARTC@mailman.ds9a.nl
>>http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/
>>
>>
>
>
>
>
>
>_______________________________________________
>LARTC mailing list / LARTC@mailman.ds9a.nl
>http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/
>
>
[-- Attachment #2: Type: text/html, Size: 4442 bytes --]
^ permalink raw reply
* sym53c810a gives CACHE TEST FAILED
From: Michel Wilson @ 2002-12-12 23:03 UTC (permalink / raw)
To: linux-scsi
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello,
I recently blew the dust off my old Digital Alpha XL300, but I couldn't get
2.4.20 to boot on it. It didn't like my onboard sym53c810a for some reason.
It says:
CACHE TEST FAILED: DMA error (dstat=0xa0).
CACHE INCORRECTLY CONFIGURED.
with the sym-driver, or with the ncr-driver:
CACHE TEST FAILED: script execution failed.
start-886b3414, pc=886b3414, end=886b3440
CACHE INCORRECTLY CONFIGURED
I remember trying the sym53c8xx-2 driver, but it gave the same message.
Didn't make a screenshot of that one though, so I don't know the exact
message.
I did some searching on it, I came across a few people with the same, or
similar problems, but there weren't any answers...
Does anyone know what I should try next, or how I can get more debugging
info on this? It must be a driver problem, the card works fine onder
2.2.7...
Regards,
Michel Wilson.
- --
Eagles may soar, but weasels don't get sucked into jet engines.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)
iD8DBQE9+RXRL2ru+9LLS34RAowvAKDBuHb6updCPHEDOjNLZA3SXBtiKQCcC6TB
lfo3qSdFw46h3zkR1L0AYTs=
=UO0M
-----END PGP SIGNATURE-----
^ permalink raw reply
* Re: pci-skeleton duplex check
From: Ben Greear @ 2002-12-12 23:08 UTC (permalink / raw)
To: Donald Becker
Cc: Jeff Garzik, Roger Luethi, netdev, Linux Kernel Mailing List
In-Reply-To: <Pine.LNX.4.44.0212121539110.10674-100000@beohost.scyld.com>
Donald Becker wrote:
> I've been actively developing Linux drivers for over a decade, and run
> about two dozen mailing lists for specific drivers. I write diagnostic
> routines for every released driver. I thoroughly test and frequently
> update the driver set I maintain. And since about 2000, my patches were
> ignored while the first notice I've have gotten to changes in my drivers
> is the bug reports. And the response: "submit a patch to fix those
> newly introduced bugs". I've even had patches ignore in favor of people
> that wrote "I don't have the NIC, but here is a change".
>
> A good example is the tulip driver. You repeatedly restructured my
> driver in the kernel, splitting into different files. It was still 90+%
> my code, but the changes made it impossible to track the modification
> history. The kernel driver was long-broken with 21143-SYM cards, but no
> one took the responsibility for fixing it.
For what it's worth, I have yet to find a tulip driver that works with
all of my 4-port NICs. Becker's fails with the Phobos 4-port NIC,
a very recent kernel driver fails to negotiate correctly (sometimes)
with the DFE-570tx NIC. Both of them failed a while back when I tried
to put 3 DFE-570tx's into a single machine.
On average, I've had better luck with the kernel driver than with
Becker's, and since it is quite a pain to compile and test it, I
have been ignoring it more and more.
Mr Becker: Perhaps you could rename your tulip driver becker_tulip and have
it separately buildable and configurable in the kernel config options? If
it was back into the kernel proper it would be much easier to experiment with.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com> <Ben_Greear AT excite.com>
President of Candela Technologies Inc http://www.candelatech.com
ScryMUD: http://scry.wanfear.com http://scry.wanfear.com/~greear
^ permalink raw reply
* Re: 2.5.50 Up and running but
From: Rusty Russell @ 2002-12-12 22:20 UTC (permalink / raw)
To: Matt Reppert; +Cc: linux-kernel, wz6b
In-Reply-To: <20021212012101.238ae459.arashi@arashi.yi.org>
In message <20021212012101.238ae459.arashi@arashi.yi.org> you write:
> On Wed, 11 Dec 2002 22:59:10 -0800
> Matt Young <wz6b@arrl.net> wrote:
>
> > Boot couldn't find the module dependency file, even though I did make modul
es
> > and make modules_install
>
> Yeah, the make rule for depmod got removed in one of the module merges. This
> will put it back. (Untested, my init scripts run depmod so it's not a big dea
l
> for me.) Rusty, am I being stupid or is this okay now that depmod
> works?
Yep, that's fine: the original modprobe replacement didn't need
modules.dep, but Adam Richter has 1300 modules and he complained about
the speed (and provided the patch to modprobe to use modules.dep, so
what could I say?)
Hopefully when Linus comes back he'll take my patches,
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
^ permalink raw reply
* [PATCH] "extern inline" to "static inline" allows compile
From: Matt Reppert @ 2002-12-12 23:09 UTC (permalink / raw)
To: rth; +Cc: trivial, linux-kernel
Hi,
I can't compile 2.5.51 on an EV56 without this. Tested, boots.
There are a bunch of symbols in core_cia.h that break the build if they're
extern inline because they're only defined in the header now. Make them
static inline instead. (Important, since they're #defined to things like
inb)
Comments?
Matt
diff -Nru a/include/asm-alpha/core_cia.h b/include/asm-alpha/core_cia.h
--- a/include/asm-alpha/core_cia.h Thu Dec 12 16:59:06 2002
+++ b/include/asm-alpha/core_cia.h Thu Dec 12 16:59:06 2002
@@ -293,7 +293,7 @@
#ifdef __KERNEL__
#ifndef __EXTERN_INLINE
-#define __EXTERN_INLINE extern inline
+#define __EXTERN_INLINE static inline
#define __IO_EXTERN_INLINE
#endif
^ permalink raw reply
* [ANNOUNCE] procps 3.1.3
From: Albert D. Cahalan @ 2002-12-12 23:04 UTC (permalink / raw)
To: linux-kernel; +Cc: acahalan
This release includes user selection in top, the sysctl -e
option needed to support the Red Hat 8.0 boot scripts, and
the use of /proc/*/wchan on recent 2.5.xx kernels.
For those of you still upgrading from procps 2.0.xx releases,
you can expect:
* top can sort by any column (old sort keys available too)
* top can select a single user to display
* top can be put in multi-window mode and/or color mode
* vmstat has the -s option, as found on UNIX and BSD systems
* vmstat has the -f option, as found on UNIX and BSD systems
* watch doesn't eat the first blank line by mistake
* vmstat uses a fast O(1) algorithm on 2.5.xx kernels
* pmap command is SunOS-compatible
* vmstat shows IO-wait time
* pgrep and pkill can find the oldest matching process
* sysctl handles the Linux 2.5.xx VLAN interfaces
* top shows IO-wait time if-and-only-if your kernel computes it
* most programs 30% to 300% faster (tested on a 450 MHz MPC7400)
* ps has a new "-F" format (very nice, like DYNIX/ptx has)
* ps with proper BSD process selection
* better handling of very long uptimes
There's a procps-feedback@lists.sf.net mailing list you can
use for feature requests, bug reports, and so on. Use it!
Feedback makes things happen.
http://procps.sf.net/
http://procps.sf.net/procps-3.1.3.tar.gz
------------- recent changes -------------
procps-3.1.2 --> procps-3.1.3
uses /proc/*/wchan files when available
top: user selection
sysctl: add -e for Red Hat 8.0 boot scripts
sysctl: the obvious --help, -V, and --version
sysctl: some command line error checking
w: stdout, not stderr -- thanks to Sander van Malssen
procps-3.1.1 --> procps-3.1.2
better RPM generation
use C99 features
some seLinux fixes
now count Inact_laundry as needed #172163
ps: fewer globals
ps: hardware-enforced buffer protection
ps: 1 kB smaller
top: B command added (for bold on/off)
top: handle old (and future) config files
top: man page tweak
top: old sort keys #167249
top: out-of-bounds RT as "RT"
top: several times faster
top: t command fixed
vmstat: -f
vmstat: -s
w: much faster
watch: don't drop empty lines #171005
watch: re-indented
procps-3.1.0 --> procps-3.1.1
vmstat faster on 2.5.xx kernels
vmstat header fixed
vmstat -a re-fixed
^ permalink raw reply
* crash when calling madvise( MADV_WILLNEED )
From: John S. J. Anderson @ 2002-12-12 23:03 UTC (permalink / raw)
To: linux-kernel
[-- Attachment #1: Type: TEXT/PLAIN, Size: 816 bytes --]
A developer that I support has discovered that the attached code is
capable of crashing many late series 2.4.x kernels, including
2.4.20. The easiest way to reproduce this crash is to compile the
attached code, and call it via 'madvise_test 3 FILE', where FILE is
a data file of at least 1.5 GB. The contents of FILE don't seem to
matter. The crash may happen more quickly if multiple copies of the
program are started. Sometimes the process locks up the terminal it
is running in; sometimes the kernel throws an OPPS and the whole
machine goes down. There doesn't seem to be a pattern as to which
event happens when.
This has been observed on both a Dell 8450 (8 CPU, 8 gig RAM) and a
Dell 1650 (2 CPU, 2 gig RAM). I've also included an oops that we
captured.
Thanks for any help.
[-- Attachment #2: ~/tmp/madvise_test.c --]
[-- Type: message/external-body, Size: 111 bytes --]
[-- Attachment #3: ~/tmp/opps --]
[-- Type: message/external-body, Size: 110 bytes --]
[-- Attachment #4: Type: TEXT/PLAIN, Size: 256 bytes --]
john.
--
"[L]iberty of the press is the right of the lonely pamphleteer who
uses carbon paper or a mimeograph just as much as of the large
metropolitan publisher who utilizes the latest photocomposition
methods."- judge's decision in Branzburg v. Hayes
^ permalink raw reply
* [PATCH] sys_epoll for 2.4
From: Janet Morgan @ 2002-12-12 23:03 UTC (permalink / raw)
To: linux-kernel
(I'm re-sending this since it appears to have gotten lost along the way....
apologies if it shows up twice.)
The attached patch is a port of Davide's sys_epoll from 2.5.51 to 2.4.20.
The port entailed the obvious gathering up of all sys_epoll-related code
plus adding support for wait queue function callbacks (from Ben's 2.5.22
patch) and defining a file_system_type read_super method for epoll in the
absence of the get_sb_pseudo helper routine.
The patch was tested using dphttpd and pipetest. It performs at least
as well as 2.5.51.
The following is an annotated diffstat for the patch:
arch/i386/kernel/entry.S | 4 add epoll syscalls
arch/sparc64/solaris/timod.c | 5 support new poll_wqueues structure
fs/Makefile | 2 add eventpoll.o
fs/eventpoll.c |1624 +++++++++++++++++++++++++++++++++++++++++++
fs/file_table.c | 8 call eventpoll_init_file() and
eventpoll_release()
fs/select.c | 28 add poll_initwait() and
support for new poll_wqueues structure
include/asm-i386/unistd.h | 4 add epoll syscalls
include/asm-ppc/unistd.h | 3 add epoll syscalls
include/linux/eventpoll.h | 49 +
include/linux/fs.h | 2 add file.f_ep_links and file.f_ep_lock
include/linux/hash.h | 58 + for hash_ptr()
include/linux/kernel.h | 12 add container_of macro
include/linux/poll.h | 31 poll_table_struct and poll_wait() changes
include/linux/sched.h | 2 add typedef for task_t
include/linux/sys.h | 2 increase syscall entry points to 260
include/linux/wait.h | 30 add wait queue function callbacks
kernel/ksyms.c | 2 export poll_initwait not __pollwait
kernel/sched.c | 14 support wait queue function callbacks
18 files changed, 1853 insertions(+), 27 deletions(-)
--- linux-2.4.20/arch/i386/kernel/entry.S Thu Nov 28 15:53:09 2002
+++ sys_epoll/arch/i386/kernel/entry.S Wed Dec 11 11:29:53 2002
@@ -657,6 +657,10 @@
.long SYMBOL_NAME(sys_ni_syscall) /* 250 sys_alloc_hugepages */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_free_hugepages */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_exit_group */
+ .long SYMBOL_NAME(sys_ni_syscall) /* reserved for sys_lookup_dcookie */
+ .long SYMBOL_NAME(sys_epoll_create)
+ .long SYMBOL_NAME(sys_epoll_ctl) /* 255 sys_epoll_ctl */
+ .long SYMBOL_NAME(sys_epoll_wait)
.rept NR_syscalls-(.-sys_call_table)/4
.long SYMBOL_NAME(sys_ni_syscall)
--- linux-2.4.20/arch/sparc64/solaris/timod.c Fri Aug 2 17:39:43 2002
+++ sys_epoll/arch/sparc64/solaris/timod.c Mon Dec 9 16:22:52 2002
@@ -652,9 +652,10 @@
}
if (!(filp->f_flags & O_NONBLOCK)) {
poll_table wait_table, *wait;
-
+ struct poll_wqueues wait_table;
+ poll_table *wait;
poll_initwait(&wait_table);
- wait = &wait_table;
+ wait = &wait_table.pt;
for(;;) {
SOLD("loop");
set_current_state(TASK_INTERRUPTIBLE);
--- linux-2.4.20/fs/Makefile Thu Nov 28 15:53:15 2002
+++ sys_epoll/fs/Makefile Mon Dec 9 16:43:14 2002
@@ -14,7 +14,7 @@
super.o block_dev.o char_dev.o stat.o exec.o pipe.o namei.o \
fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \
dcache.o inode.o attr.o bad_inode.o file.o iobuf.o dnotify.o \
- filesystems.o namespace.o seq_file.o xattr.o
+ filesystems.o namespace.o seq_file.o xattr.o eventpoll.o
ifeq ($(CONFIG_QUOTA),y)
obj-y += dquot.o
--- linux-2.4.20/fs/eventpoll.c Wed Dec 31 16:00:00 1969
+++ sys_epoll/fs/eventpoll.c Wed Dec 11 12:00:43 2002
@@ -0,0 +1,1624 @@
+/*
+ * fs/eventpoll.c ( Efficent event polling implementation )
+ * Copyright (C) 2001,...,2002 Davide Libenzi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ * 11 December 2002
+ * Ported from 2.5.51 - janetinc@us.ibm.com
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/smp_lock.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <linux/hash.h>
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+#include <linux/wait.h>
+#include <linux/eventpoll.h>
+#include <linux/mount.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/mman.h>
+#include <asm/atomic.h>
+
+
+
+#define EVENTPOLLFS_MAGIC 0x03111965 /* My birthday should work for this :) */
+
+#define DEBUG_EPOLL 0
+
+#if DEBUG_EPOLL > 0
+#define DPRINTK(x) printk x
+#define DNPRINTK(n, x) do { if ((n) <= DEBUG_EPOLL) printk x; } while (0)
+#else /* #if DEBUG_EPOLL > 0 */
+#define DPRINTK(x) (void) 0
+#define DNPRINTK(n, x) (void) 0
+#endif /* #if DEBUG_EPOLL > 0 */
+
+#define DEBUG_EPI 0
+
+#if DEBUG_EPI != 0
+#define EPI_SLAB_DEBUG (SLAB_DEBUG_FREE | SLAB_RED_ZONE /* | SLAB_POISON */)
+#else /* #if DEBUG_EPI != 0 */
+#define EPI_SLAB_DEBUG 0
+#endif /* #if DEBUG_EPI != 0 */
+
+
+/* Maximum number of poll wake up nests we are allowing */
+#define EP_MAX_POLLWAKE_NESTS 4
+
+/* Maximum size of the hash in bits ( 2^N ) */
+#define EP_MAX_HASH_BITS 17
+
+/* Minimum size of the hash in bits ( 2^N ) */
+#define EP_MIN_HASH_BITS 9
+
+/* Number of hash entries ( "struct list_head" ) inside a page */
+#define EP_HENTRY_X_PAGE (PAGE_SIZE / sizeof(struct list_head))
+
+/* Maximum size of the hash in pages */
+#define EP_MAX_HPAGES ((1 << EP_MAX_HASH_BITS) / EP_HENTRY_X_PAGE + 1)
+
+/* Number of pages allocated for an "hbits" sized hash table */
+#define EP_HASH_PAGES(hbits) ((int) ((1 << (hbits)) / EP_HENTRY_X_PAGE + \
+ ((1 << (hbits)) % EP_HENTRY_X_PAGE ? 1: 0)))
+
+/* Macro to allocate a "struct epitem" from the slab cache */
+#define EPI_MEM_ALLOC() (struct epitem *) kmem_cache_alloc(epi_cache, SLAB_KERNEL)
+
+/* Macro to free a "struct epitem" to the slab cache */
+#define EPI_MEM_FREE(p) kmem_cache_free(epi_cache, p)
+
+/* Macro to allocate a "struct eppoll_entry" from the slab cache */
+#define PWQ_MEM_ALLOC() (struct eppoll_entry *) kmem_cache_alloc(pwq_cache, SLAB_KERNEL)
+
+/* Macro to free a "struct eppoll_entry" to the slab cache */
+#define PWQ_MEM_FREE(p) kmem_cache_free(pwq_cache, p)
+
+/* Fast test to see if the file is an evenpoll file */
+#define IS_FILE_EPOLL(f) ((f)->f_op == &eventpoll_fops)
+
+/*
+ * Remove the item from the list and perform its initialization.
+ * This is usefull for us because we can test if the item is linked
+ * using "EP_IS_LINKED(p)".
+ */
+#define EP_LIST_DEL(p) do { list_del(p); INIT_LIST_HEAD(p); } while (0)
+
+/* Tells us if the item is currently linked */
+#define EP_IS_LINKED(p) (!list_empty(p))
+
+/* Get the "struct epitem" from a wait queue pointer */
+#define EP_ITEM_FROM_WAIT(p) ((struct epitem *) container_of(p, struct eppoll_entry, wait)->base)
+
+/* Get the "struct epitem" from an epoll queue wrapper */
+#define EP_ITEM_FROM_EPQUEUE(p) (container_of(p, struct ep_pqueue, pt)->epi)
+
+/*
+ * This is used to optimize the event transfer to userspace. Since this
+ * is kept on stack, it should be pretty small.
+ */
+#define EP_MAX_BUF_EVENTS 32
+
+/*
+ * Used to optimize ready items collection by reducing the irqlock/irqunlock
+ * switching rate. This is kept in stack too, so do not go wild with this number.
+ */
+#define EP_MAX_COLLECT_ITEMS 64
+
+
+/*
+ * Node that is linked into the "wake_task_list" member of the "struct poll_safewake".
+ * It is used to keep track on all tasks that are currently inside the wake_up() code
+ * to 1) short-circuit the one coming from the same task and same wait queue head
+ * ( loop ) 2) allow a maximum number of epoll descriptors inclusion nesting
+ * 3) let go the ones coming from other tasks.
+ */
+struct wake_task_node {
+ struct list_head llink;
+ task_t *task;
+ wait_queue_head_t *wq;
+};
+
+/*
+ * This is used to implement the safe poll wake up avoiding to reenter
+ * the poll callback from inside wake_up().
+ */
+struct poll_safewake {
+ struct list_head wake_task_list;
+ spinlock_t lock;
+};
+
+/*
+ * This structure is stored inside the "private_data" member of the file
+ * structure and rapresent the main data sructure for the eventpoll
+ * interface.
+ */
+struct eventpoll {
+ /* Protect the this structure access */
+ rwlock_t lock;
+
+ /* Wait queue used by sys_epoll_wait() */
+ wait_queue_head_t wq;
+
+ /* Wait queue used by file->poll() */
+ wait_queue_head_t poll_wait;
+
+ /* List of ready file descriptors */
+ struct list_head rdllist;
+
+ /* Size of the hash */
+ unsigned int hashbits;
+
+ /* Pages for the "struct epitem" hash */
+ char *hpages[EP_MAX_HPAGES];
+};
+
+/* Wait structure used by the poll hooks */
+struct eppoll_entry {
+ /* List header used to link this structure to the "struct epitem" */
+ struct list_head llink;
+
+ /* The "base" pointer is set to the container "struct epitem" */
+ void *base;
+
+ /*
+ * Wait queue item that will be linked to the target file wait
+ * queue head.
+ */
+ wait_queue_t wait;
+
+ /* The wait queue head that linked the "wait" wait queue item */
+ wait_queue_head_t *whead;
+};
+
+/*
+ * Each file descriptor added to the eventpoll interface will
+ * have an entry of this type linked to the hash.
+ */
+struct epitem {
+ /* List header used to link this structure to the eventpoll hash */
+ struct list_head llink;
+
+ /* List header used to link this structure to the eventpoll ready list */
+ struct list_head rdllink;
+
+ /* Number of active wait queue attached to poll operations */
+ int nwait;
+
+ /* List containing poll wait queues */
+ struct list_head pwqlist;
+
+ /* The "container" of this item */
+ struct eventpoll *ep;
+
+ /* The file this item refers to */
+ struct file *file;
+
+ /* The structure that describe the interested events and the source fd */
+ struct epoll_event event;
+
+ /*
+ * Used to keep track of the usage count of the structure. This avoids
+ * that the structure will desappear from underneath our processing.
+ */
+ atomic_t usecnt;
+
+ /* List header used to link this item to the "struct file" items list */
+ struct list_head fllink;
+};
+
+/* Wrapper struct used by poll queueing */
+struct ep_pqueue {
+ poll_table pt;
+ struct epitem *epi;
+};
+
+
+
+static void ep_poll_safewake_init(struct poll_safewake *psw);
+static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
+static unsigned int ep_get_hash_bits(unsigned int hintsize);
+static int ep_getfd(int *efd, struct inode **einode, struct file **efile);
+static int ep_alloc_pages(char **pages, int numpages);
+static int ep_free_pages(char **pages, int numpages);
+static int ep_file_init(struct file *file, unsigned int hashbits);
+static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file);
+static struct list_head *ep_hash_entry(struct eventpoll *ep, unsigned int index);
+static int ep_init(struct eventpoll *ep, unsigned int hashbits);
+static void ep_free(struct eventpoll *ep);
+static struct epitem *ep_find(struct eventpoll *ep, struct file *file);
+static void ep_use_epitem(struct epitem *epi);
+static void ep_release_epitem(struct epitem *epi);
+static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, poll_table *pt);
+static int ep_insert(struct eventpoll *ep, struct epoll_event *event, struct file *tfile);
+static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event);
+static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi);
+static int ep_unlink(struct eventpoll *ep, struct epitem *epi);
+static int ep_remove(struct eventpoll *ep, struct epitem *epi);
+static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync);
+static int ep_eventpoll_close(struct inode *inode, struct file *file);
+static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait);
+static int ep_collect_ready_items(struct eventpoll *ep, struct epitem **aepi, int maxepi);
+static int ep_send_events(struct eventpoll *ep, struct epitem **aepi, int nepi,
+ struct epoll_event *events);
+static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents);
+static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
+ int timeout);
+static int eventpollfs_delete_dentry(struct dentry *dentry);
+static struct inode *ep_eventpoll_inode(void);
+
+
+/* Safe wake up implementation */
+static struct poll_safewake psw;
+
+/*
+ * This semaphore is used to ensure that files are not removed
+ * while epoll is using them. Namely the f_op->poll(), since
+ * it has to be called from outside the lock, must be protected.
+ * This is read-held during the event transfer loop to userspace
+ * and it is write-held during the file cleanup path and the epoll
+ * file exit code.
+ */
+static struct rw_semaphore epsem;
+
+/* Slab cache used to allocate "struct epitem" */
+static kmem_cache_t *epi_cache;
+
+/* Slab cache used to allocate "struct eppoll_entry" */
+static kmem_cache_t *pwq_cache;
+
+/* Virtual fs used to allocate inodes for eventpoll files */
+static struct vfsmount *eventpoll_mnt;
+
+/* File callbacks that implement the eventpoll file behaviour */
+static struct file_operations eventpoll_fops = {
+ .release = ep_eventpoll_close,
+ .poll = ep_eventpoll_poll
+};
+
+static int eventpollfs_statfs(struct super_block *sb, struct statfs *buf)
+{
+ buf->f_type = EVENTPOLLFS_MAGIC;
+ buf->f_bsize = 1024;
+ buf->f_namelen = 255;
+ return 0;
+}
+
+static struct super_operations eventpollfs_ops = {
+ statfs: eventpollfs_statfs,
+};
+
+static struct super_block * eventpollfs_read_super(struct super_block *sb, void *data, int silent)
+{
+ struct inode *root = new_inode(sb);
+ if (!root)
+ return NULL;
+ root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
+ root->i_uid = root->i_gid = 0;
+ root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
+ sb->s_blocksize = 1024;
+ sb->s_blocksize_bits = 10;
+ sb->s_magic = EVENTPOLLFS_MAGIC;
+ sb->s_op = &eventpollfs_ops;
+ sb->s_root = d_alloc(NULL, &(const struct qstr) {"eventpoll:", 10, 0 });
+ if (!sb->s_root) {
+ iput(root);
+ return NULL;
+ }
+ sb->s_root->d_sb = sb;
+ sb->s_root->d_parent = sb->s_root;
+ d_instantiate(sb->s_root, root);
+ return sb;
+}
+
+static DECLARE_FSTYPE(eventpoll_fs_type, "eventpollfs", eventpollfs_read_super, FS_NOMOUNT);
+
+
+/* Very basic directory entry operations for the eventpoll virtual file system */
+static struct dentry_operations eventpollfs_dentry_operations = {
+ .d_delete = eventpollfs_delete_dentry,
+};
+
+
+
+/* Initialize the poll safe wake up structure */
+static void ep_poll_safewake_init(struct poll_safewake *psw)
+{
+
+ INIT_LIST_HEAD(&psw->wake_task_list);
+ spin_lock_init(&psw->lock);
+}
+
+
+/*
+ * Perform a safe wake up of the poll wait list. The problem is that
+ * with the new callback'd wake up system, it is possible that the
+ * poll callback is reentered from inside the call to wake_up() done
+ * on the poll wait queue head. The rule is that we cannot reenter the
+ * wake up code from the same task more than EP_MAX_POLLWAKE_NESTS times,
+ * and we cannot reenter the same wait queue head at all. This will
+ * enable to have a hierarchy of epoll file descriptor of no more than
+ * EP_MAX_POLLWAKE_NESTS deep. We need the irq version of the spin lock
+ * because this one gets called by the poll callback, that in turn is called
+ * from inside a wake_up(), that might be called from irq context.
+ */
+static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
+{
+ int wake_nests = 0;
+ unsigned long flags;
+ task_t *this_task = current;
+ struct list_head *lsthead = &psw->wake_task_list, *lnk;
+ struct wake_task_node tnode;
+
+ spin_lock_irqsave(&psw->lock, flags);
+
+ /* Try to see if the current task is already inside this wakeup call */
+ list_for_each(lnk, lsthead) {
+ struct wake_task_node *tncur = list_entry(lnk, struct wake_task_node, llink);
+
+ if (tncur->task == this_task) {
+ if (tncur->wq == wq || ++wake_nests > EP_MAX_POLLWAKE_NESTS) {
+ /*
+ * Ops ... loop detected or maximum nest level reached.
+ * We abort this wake by breaking the cycle itself.
+ */
+ spin_unlock_irqrestore(&psw->lock, flags);
+ return;
+ }
+ }
+ }
+
+ /* Add the current task to the list */
+ tnode.task = this_task;
+ tnode.wq = wq;
+ list_add(&tnode.llink, lsthead);
+
+ spin_unlock_irqrestore(&psw->lock, flags);
+
+ /* Do really wake up now */
+ wake_up(wq);
+
+ /* Remove the current task from the list */
+ spin_lock_irqsave(&psw->lock, flags);
+ list_del(&tnode.llink);
+ spin_unlock_irqrestore(&psw->lock, flags);
+}
+
+
+/*
+ * Calculate the size of the hash in bits. The returned size will be
+ * bounded between EP_MIN_HASH_BITS and EP_MAX_HASH_BITS.
+ */
+static unsigned int ep_get_hash_bits(unsigned int hintsize)
+{
+ unsigned int i, val;
+
+ for (i = 0, val = 1; val < hintsize && i < EP_MAX_HASH_BITS; i++, val <<= 1);
+ return i < EP_MIN_HASH_BITS ? EP_MIN_HASH_BITS: i;
+}
+
+
+/* Used to initialize the epoll bits inside the "struct file" */
+void eventpoll_init_file(struct file *file)
+{
+
+ INIT_LIST_HEAD(&file->f_ep_links);
+ spin_lock_init(&file->f_ep_lock);
+}
+
+
+/*
+ * This is called from inside fs/file_table.c:__fput() to unlink files
+ * from the eventpoll interface. We need to have this facility to cleanup
+ * correctly files that are closed without being removed from the eventpoll
+ * interface.
+ */
+void eventpoll_release(struct file *file)
+{
+ struct list_head *lsthead = &file->f_ep_links;
+ struct epitem *epi;
+
+ /*
+ * Fast check to avoid the get/release of the semaphore. Since
+ * we're doing this outside the semaphore lock, it might return
+ * false negatives, but we don't care. It'll help in 99.99% of cases
+ * to avoid the semaphore lock. False positives simply cannot happen
+ * because the file in on the way to be removed and nobody ( but
+ * eventpoll ) has still a reference to this file.
+ */
+ if (list_empty(lsthead))
+ return;
+
+ /*
+ * We don't want to get "file->f_ep_lock" because it is not
+ * necessary. It is not necessary because we're in the "struct file"
+ * cleanup path, and this means that noone is using this file anymore.
+ * The only hit might come from ep_free() but by holding the semaphore
+ * will correctly serialize the operation.
+ */
+ down_write(&epsem);
+ while (!list_empty(lsthead)) {
+ epi = list_entry(lsthead->next, struct epitem, fllink);
+
+ EP_LIST_DEL(&epi->fllink);
+ ep_remove(epi->ep, epi);
+ }
+ up_write(&epsem);
+}
+
+
+/*
+ * It opens an eventpoll file descriptor by suggesting a storage of "size"
+ * file descriptors. The size parameter is just an hint about how to size
+ * data structures. It won't prevent the user to store more than "size"
+ * file descriptors inside the epoll interface. It is the kernel part of
+ * the userspace epoll_create(2).
+ */
+asmlinkage int sys_epoll_create(int size)
+{
+ int error, fd;
+ unsigned int hashbits;
+ struct inode *inode;
+ struct file *file;
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
+ current, size));
+
+ /* Correctly size the hash */
+ hashbits = ep_get_hash_bits((unsigned int) size);
+
+ /*
+ * Creates all the items needed to setup an eventpoll file. That is,
+ * a file structure, and inode and a free file descriptor.
+ */
+ error = ep_getfd(&fd, &inode, &file);
+ if (error)
+ goto eexit_1;
+
+ /* Setup the file internal data structure ( "struct eventpoll" ) */
+ error = ep_file_init(file, hashbits);
+ if (error)
+ goto eexit_2;
+
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
+ current, size, fd));
+
+ return fd;
+
+eexit_2:
+ sys_close(fd);
+eexit_1:
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
+ current, size, error));
+ return error;
+}
+
+
+/*
+ * The following function implement the controller interface for the eventpoll
+ * file that enable the insertion/removal/change of file descriptors inside
+ * the interest set. It rapresents the kernel part of the user spcae epoll_ctl(2).
+ */
+asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
+{
+ int error;
+ struct file *file, *tfile;
+ struct eventpoll *ep;
+ struct epitem *epi;
+ struct epoll_event epds;
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u)\n",
+ current, epfd, op, fd, event->events));
+
+ error = -EFAULT;
+ if (copy_from_user(&epds, event, sizeof(struct epoll_event)))
+ goto eexit_1;
+
+ /* Get the "struct file *" for the eventpoll file */
+ error = -EBADF;
+ file = fget(epfd);
+ if (!file)
+ goto eexit_1;
+
+ /* Get the "struct file *" for the target file */
+ tfile = fget(fd);
+ if (!tfile)
+ goto eexit_2;
+
+ /* The target file descriptor must support poll */
+ error = -EPERM;
+ if (!tfile->f_op || !tfile->f_op->poll)
+ goto eexit_3;
+
+ /*
+ * We have to check that the file structure underneath the file descriptor
+ * the user passed to us _is_ an eventpoll file. And also we do not permit
+ * adding an epoll file descriptor inside itself.
+ */
+ error = -EINVAL;
+ if (file == tfile || !IS_FILE_EPOLL(file))
+ goto eexit_3;
+
+ /*
+ * At this point it is safe to assume that the "private_data" contains
+ * our own data structure.
+ */
+ ep = file->private_data;
+
+ /*
+ * Try to lookup the file inside our hash table. When an item is found
+ * ep_find() increases the usage count of the item so that it won't
+ * desappear underneath us. The only thing that might happen, if someone
+ * tries very hard, is a double insertion of the same file descriptor.
+ * This does not rapresent a problem though and we don't really want
+ * to put an extra syncronization object to deal with this harmless condition.
+ */
+ epi = ep_find(ep, tfile);
+
+ error = -EINVAL;
+ switch (op) {
+ case EPOLL_CTL_ADD:
+ if (!epi) {
+ epds.events |= POLLERR | POLLHUP;
+
+ error = ep_insert(ep, &epds, tfile);
+ } else
+ error = -EEXIST;
+ break;
+ case EPOLL_CTL_DEL:
+ if (epi)
+ error = ep_remove(ep, epi);
+ else
+ error = -ENOENT;
+ break;
+ case EPOLL_CTL_MOD:
+ if (epi) {
+ epds.events |= POLLERR | POLLHUP;
+ error = ep_modify(ep, epi, &epds);
+ } else
+ error = -ENOENT;
+ break;
+ }
+
+ /*
+ * The function ep_find() increments the usage count of the structure
+ * so, if this is not NULL, we need to release it.
+ */
+ if (epi)
+ ep_release_epitem(epi);
+
+eexit_3:
+ fput(tfile);
+eexit_2:
+ fput(file);
+eexit_1:
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u) = %d\n",
+ current, epfd, op, fd, event->events, error));
+
+ return error;
+}
+
+
+/*
+ * Implement the event wait interface for the eventpoll file. It is the kernel
+ * part of the user space epoll_wait(2).
+ */
+asmlinkage int sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
+ int timeout)
+{
+ int error;
+ struct file *file;
+ struct eventpoll *ep;
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d)\n",
+ current, epfd, events, maxevents, timeout));
+
+ /* The maximum number of event must be greater than zero */
+ if (maxevents <= 0)
+ return -EINVAL;
+
+ /* Verify that the area passed by the user is writeable */
+ if ((error = verify_area(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))))
+ goto eexit_1;
+
+ /* Get the "struct file *" for the eventpoll file */
+ error = -EBADF;
+ file = fget(epfd);
+ if (!file)
+ goto eexit_1;
+
+ /*
+ * We have to check that the file structure underneath the file descriptor
+ * the user passed to us _is_ an eventpoll file.
+ */
+ error = -EINVAL;
+ if (!IS_FILE_EPOLL(file))
+ goto eexit_2;
+
+ /*
+ * At this point it is safe to assume that the "private_data" contains
+ * our own data structure.
+ */
+ ep = file->private_data;
+
+ /* Time to fish for events ... */
+ error = ep_poll(ep, events, maxevents, timeout);
+
+eexit_2:
+ fput(file);
+eexit_1:
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d) = %d\n",
+ current, epfd, events, maxevents, timeout, error));
+
+ return error;
+}
+
+
+/*
+ * Creates the file descriptor to be used by the epoll interface.
+ */
+static int ep_getfd(int *efd, struct inode **einode, struct file **efile)
+{
+ struct qstr this;
+ char name[32];
+ struct dentry *dentry;
+ struct inode *inode;
+ struct file *file;
+ int error, fd;
+
+ /* Get an ready to use file */
+ error = -ENFILE;
+ file = get_empty_filp();
+ if (!file)
+ goto eexit_1;
+
+ /* Allocates an inode from the eventpoll file system */
+ inode = ep_eventpoll_inode();
+ error = PTR_ERR(inode);
+ if (IS_ERR(inode))
+ goto eexit_2;
+
+ /* Allocates a free descriptor to plug the file onto */
+ error = get_unused_fd();
+ if (error < 0)
+ goto eexit_3;
+ fd = error;
+
+ /*
+ * Link the inode to a directory entry by creating a unique name
+ * using the inode number.
+ */
+ error = -ENOMEM;
+ sprintf(name, "[%lu]", inode->i_ino);
+ this.name = name;
+ this.len = strlen(name);
+ this.hash = inode->i_ino;
+ dentry = d_alloc(eventpoll_mnt->mnt_sb->s_root, &this);
+ if (!dentry)
+ goto eexit_4;
+ dentry->d_op = &eventpollfs_dentry_operations;
+ d_add(dentry, inode);
+ file->f_vfsmnt = mntget(eventpoll_mnt);
+ file->f_dentry = dget(dentry);
+
+ /*
+ * Initialize the file as read/write because it could be used
+ * with write() to add/remove/change interest sets.
+ */
+ file->f_pos = 0;
+ file->f_flags = O_RDONLY;
+ file->f_op = &eventpoll_fops;
+ file->f_mode = FMODE_READ;
+ file->f_version = 0;
+ file->private_data = NULL;
+
+ /* Install the new setup file into the allocated fd. */
+ fd_install(fd, file);
+
+ *efd = fd;
+ *einode = inode;
+ *efile = file;
+ return 0;
+
+eexit_4:
+ put_unused_fd(fd);
+eexit_3:
+ iput(inode);
+eexit_2:
+ put_filp(file);
+eexit_1:
+ return error;
+}
+
+
+static int ep_alloc_pages(char **pages, int numpages)
+{
+ int i;
+
+ for (i = 0; i < numpages; i++) {
+ pages[i] = (char *) __get_free_pages(GFP_KERNEL, 0);
+ if (!pages[i]) {
+ for (--i; i >= 0; i--) {
+ ClearPageReserved(virt_to_page(pages[i]));
+ free_pages((unsigned long) pages[i], 0);
+ }
+ return -ENOMEM;
+ }
+ SetPageReserved(virt_to_page(pages[i]));
+ }
+ return 0;
+}
+
+
+static int ep_free_pages(char **pages, int numpages)
+{
+ int i;
+
+ for (i = 0; i < numpages; i++) {
+ ClearPageReserved(virt_to_page(pages[i]));
+ free_pages((unsigned long) pages[i], 0);
+ }
+ return 0;
+}
+
+
+static int ep_file_init(struct file *file, unsigned int hashbits)
+{
+ int error;
+ struct eventpoll *ep;
+
+ if (!(ep = kmalloc(sizeof(struct eventpoll), GFP_KERNEL)))
+ return -ENOMEM;
+
+ memset(ep, 0, sizeof(*ep));
+
+ error = ep_init(ep, hashbits);
+ if (error) {
+ kfree(ep);
+ return error;
+ }
+
+ file->private_data = ep;
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_file_init() ep=%p\n",
+ current, ep));
+ return 0;
+}
+
+
+/*
+ * Calculate the index of the hash relative to "file".
+ */
+static unsigned int ep_hash_index(struct eventpoll *ep, struct file *file)
+{
+
+ return (unsigned int) hash_ptr(file, ep->hashbits);
+}
+
+
+/*
+ * Returns the hash entry ( struct list_head * ) of the passed index.
+ */
+static struct list_head *ep_hash_entry(struct eventpoll *ep, unsigned int index)
+{
+
+ return (struct list_head *) (ep->hpages[index / EP_HENTRY_X_PAGE] +
+ (index % EP_HENTRY_X_PAGE) * sizeof(struct list_head));
+}
+
+
+static int ep_init(struct eventpoll *ep, unsigned int hashbits)
+{
+ int error;
+ unsigned int i, hsize;
+
+ rwlock_init(&ep->lock);
+ init_waitqueue_head(&ep->wq);
+ init_waitqueue_head(&ep->poll_wait);
+ INIT_LIST_HEAD(&ep->rdllist);
+
+ /* Hash allocation and setup */
+ ep->hashbits = hashbits;
+ error = ep_alloc_pages(ep->hpages, EP_HASH_PAGES(ep->hashbits));
+ if (error)
+ goto eexit_1;
+
+ /* Initialize hash buckets */
+ for (i = 0, hsize = 1 << hashbits; i < hsize; i++)
+ INIT_LIST_HEAD(ep_hash_entry(ep, i));
+
+ return 0;
+eexit_1:
+ return error;
+}
+
+
+static void ep_free(struct eventpoll *ep)
+{
+ unsigned int i, hsize;
+ struct list_head *lsthead, *lnk;
+
+ /*
+ * We need to lock this because we could be hit by
+ * eventpoll_release() while we're freeing the "struct eventpoll".
+ */
+ down_write(&epsem);
+
+ /*
+ * Walks through the whole hash by unregistering poll callbacks.
+ */
+ for (i = 0, hsize = 1 << ep->hashbits; i < hsize; i++) {
+ lsthead = ep_hash_entry(ep, i);
+
+ list_for_each(lnk, lsthead) {
+ struct epitem *epi = list_entry(lnk, struct epitem, llink);
+
+ ep_unregister_pollwait(ep, epi);
+ }
+ }
+
+ /*
+ * Walks through the whole hash by freeing each "struct epitem". At this
+ * point we are sure no poll callbacks will be lingering around, and also by
+ * write-holding "epsem" we can be sure that no file cleanup code will hit
+ * us during this operation. So we can avoid the lock on "ep->lock".
+ */
+ for (i = 0, hsize = 1 << ep->hashbits; i < hsize; i++) {
+ lsthead = ep_hash_entry(ep, i);
+
+ while (!list_empty(lsthead)) {
+ struct epitem *epi = list_entry(lsthead->next, struct epitem, llink);
+
+ ep_remove(ep, epi);
+ }
+ }
+
+ up_write(&epsem);
+
+ /* Free hash pages */
+ ep_free_pages(ep->hpages, EP_HASH_PAGES(ep->hashbits));
+}
+
+
+/*
+ * Search the file inside the eventpoll hash. It add usage count to
+ * the returned item, so the caller must call ep_release_epitem()
+ * after finished using the "struct epitem".
+ */
+static struct epitem *ep_find(struct eventpoll *ep, struct file *file)
+{
+ unsigned long flags;
+ struct list_head *lsthead, *lnk;
+ struct epitem *epi = NULL;
+
+ read_lock_irqsave(&ep->lock, flags);
+
+ lsthead = ep_hash_entry(ep, ep_hash_index(ep, file));
+ list_for_each(lnk, lsthead) {
+ epi = list_entry(lnk, struct epitem, llink);
+
+ if (epi->file == file) {
+ ep_use_epitem(epi);
+ break;
+ }
+ epi = NULL;
+ }
+
+ read_unlock_irqrestore(&ep->lock, flags);
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_find(%p) -> %p\n",
+ current, file, epi));
+
+ return epi;
+}
+
+
+/*
+ * Increment the usage count of the "struct epitem" making it sure
+ * that the user will have a valid pointer to reference.
+ */
+static void ep_use_epitem(struct epitem *epi)
+{
+
+ atomic_inc(&epi->usecnt);
+}
+
+
+/*
+ * Decrement ( release ) the usage count by signaling that the user
+ * has finished using the structure. It might lead to freeing the
+ * structure itself if the count goes to zero.
+ */
+static void ep_release_epitem(struct epitem *epi)
+{
+
+ if (atomic_dec_and_test(&epi->usecnt))
+ EPI_MEM_FREE(epi);
+}
+
+
+/*
+ * This is the callback that is used to add our wait queue to the
+ * target file wakeup lists.
+ */
+static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, poll_table *pt)
+{
+ struct epitem *epi = EP_ITEM_FROM_EPQUEUE(pt);
+ struct eppoll_entry *pwq;
+
+ if (epi->nwait >= 0 && (pwq = PWQ_MEM_ALLOC()))
+ {
+ init_waitqueue_func_entry(&pwq->wait, ep_poll_callback);
+ pwq->whead = whead;
+ pwq->base = epi;
+ add_wait_queue(whead, &pwq->wait);
+ list_add_tail(&pwq->llink, &epi->pwqlist);
+ epi->nwait++;
+ }
+ else
+ {
+ /* We have to signal that an error occured */
+ epi->nwait = -1;
+ }
+}
+
+
+static int ep_insert(struct eventpoll *ep, struct epoll_event *event, struct file *tfile)
+{
+ int error, revents, pwake = 0;
+ unsigned long flags;
+ struct epitem *epi;
+ struct ep_pqueue epq;
+
+ error = -ENOMEM;
+ if (!(epi = EPI_MEM_ALLOC()))
+ goto eexit_1;
+
+ /* Item initialization follow here ... */
+ INIT_LIST_HEAD(&epi->llink);
+ INIT_LIST_HEAD(&epi->rdllink);
+ INIT_LIST_HEAD(&epi->fllink);
+ INIT_LIST_HEAD(&epi->pwqlist);
+ epi->ep = ep;
+ epi->file = tfile;
+ epi->event = *event;
+ atomic_set(&epi->usecnt, 1);
+ epi->nwait = 0;
+
+ /* Initialize the poll table using the queue callback */
+ epq.epi = epi;
+ init_poll_funcptr(&epq.pt, ep_ptable_queue_proc);
+
+ /*
+ * Attach the item to the poll hooks and get current event bits.
+ * We can safely use the file* here because its usage count has
+ * been increased by the caller of this function.
+ */
+ revents = tfile->f_op->poll(tfile, &epq.pt);
+
+ /*
+ * We have to check if something went wrong during the poll wait queue
+ * install process. Namely an allocation for a wait queue failed due
+ * high memory pressure.
+ */
+ if (epi->nwait < 0)
+ goto eexit_2;
+
+ /* Add the current item to the list of active epoll hook for this file */
+ spin_lock(&tfile->f_ep_lock);
+ list_add_tail(&epi->fllink, &tfile->f_ep_links);
+ spin_unlock(&tfile->f_ep_lock);
+
+ /* We have to drop the new item inside our item list to keep track of it */
+ write_lock_irqsave(&ep->lock, flags);
+
+ /* Add the current item to the hash table */
+ list_add(&epi->llink, ep_hash_entry(ep, ep_hash_index(ep, tfile)));
+
+ /* If the file is already "ready" we drop it inside the ready list */
+ if ((revents & event->events) && !EP_IS_LINKED(&epi->rdllink)) {
+ list_add_tail(&epi->rdllink, &ep->rdllist);
+
+ /* Notify waiting tasks that events are available */
+ if (waitqueue_active(&ep->wq))
+ wake_up(&ep->wq);
+ if (waitqueue_active(&ep->poll_wait))
+ pwake++;
+ }
+
+ write_unlock_irqrestore(&ep->lock, flags);
+
+ /* We have to call this outside the lock */
+ if (pwake)
+ ep_poll_safewake(&psw, &ep->poll_wait);
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_insert(%p, %p)\n",
+ current, ep, tfile));
+
+ return 0;
+
+eexit_2:
+ ep_unregister_pollwait(ep, epi);
+
+ /*
+ * We need to do this because an event could have been arrived on some
+ * allocated wait queue.
+ */
+ write_lock_irqsave(&ep->lock, flags);
+ if (EP_IS_LINKED(&epi->rdllink))
+ EP_LIST_DEL(&epi->rdllink);
+ write_unlock_irqrestore(&ep->lock, flags);
+
+ EPI_MEM_FREE(epi);
+eexit_1:
+ return error;
+}
+
+
+/*
+ * Modify the interest event mask by dropping an event if the new mask
+ * has a match in the current file status.
+ */
+static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_event *event)
+{
+ int pwake = 0;
+ unsigned int revents;
+ unsigned long flags;
+
+ /*
+ * Set the new event interest mask before calling f_op->poll(), otherwise
+ * a potential race might occur. In fact if we do this operation inside
+ * the lock, an event might happen between the f_op->poll() call and the
+ * new event set registering.
+ */
+ epi->event.events = event->events;
+
+ /*
+ * Get current event bits. We can safely use the file* here because
+ * its usage count has been increased by the caller of this function.
+ */
+ revents = epi->file->f_op->poll(epi->file, NULL);
+
+ write_lock_irqsave(&ep->lock, flags);
+
+ /* Copy the data member from inside the lock */
+ epi->event.data = event->data;
+
+ /* If the file is already "ready" we drop it inside the ready list */
+ if ((revents & event->events) && EP_IS_LINKED(&epi->llink) &&
+ !EP_IS_LINKED(&epi->rdllink)) {
+ list_add_tail(&epi->rdllink, &ep->rdllist);
+
+ /* Notify waiting tasks that events are available */
+ if (waitqueue_active(&ep->wq))
+ wake_up(&ep->wq);
+ if (waitqueue_active(&ep->poll_wait))
+ pwake++;
+ }
+
+ write_unlock_irqrestore(&ep->lock, flags);
+
+ /* We have to call this outside the lock */
+ if (pwake)
+ ep_poll_safewake(&psw, &ep->poll_wait);
+
+ return 0;
+}
+
+
+/*
+ * This function unregister poll callbacks from the associated file descriptor.
+ * Since this must be called without holding "ep->lock" the atomic exchange trick
+ * will protect us from multiple unregister.
+ */
+static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
+{
+ int nwait;
+ struct list_head *lsthead = &epi->pwqlist;
+ struct eppoll_entry *pwq;
+
+ /* This is called without locks, so we need the atomic exchange */
+ nwait = xchg(&epi->nwait, 0);
+
+ if (nwait)
+ {
+ while (!list_empty(lsthead)) {
+ pwq = list_entry(lsthead->next, struct eppoll_entry, llink);
+
+ EP_LIST_DEL(&pwq->llink);
+ remove_wait_queue(pwq->whead, &pwq->wait);
+ PWQ_MEM_FREE(pwq);
+ }
+ }
+}
+
+
+/*
+ * Unlink the "struct epitem" from all places it might have been hooked up.
+ * This function must be called with write IRQ lock on "ep->lock".
+ */
+static int ep_unlink(struct eventpoll *ep, struct epitem *epi)
+{
+ int error;
+
+ /*
+ * It can happen that this one is called for an item already unlinked.
+ * The check protect us from doing a double unlink ( crash ).
+ */
+ error = -ENOENT;
+ if (!EP_IS_LINKED(&epi->llink))
+ goto eexit_1;
+
+ /*
+ * At this point is safe to do the job, unlink the item from our list.
+ * This operation togheter with the above check closes the door to
+ * double unlinks.
+ */
+ EP_LIST_DEL(&epi->llink);
+
+ /*
+ * If the item we are going to remove is inside the ready file descriptors
+ * we want to remove it from this list to avoid stale events.
+ */
+ if (EP_IS_LINKED(&epi->rdllink))
+ EP_LIST_DEL(&epi->rdllink);
+
+ error = 0;
+eexit_1:
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_unlink(%p, %p) = %d\n",
+ current, ep, epi->file, error));
+
+ return error;
+}
+
+
+/*
+ * Removes a "struct epitem" from the eventpoll hash and deallocates
+ * all the associated resources.
+ */
+static int ep_remove(struct eventpoll *ep, struct epitem *epi)
+{
+ int error;
+ unsigned long flags;
+
+ /*
+ * Removes poll wait queue hooks. We _have_ to do this without holding
+ * the "ep->lock" otherwise a deadlock might occur. This because of the
+ * sequence of the lock acquisition. Here we do "ep->lock" then the wait
+ * queue head lock when unregistering the wait queue. The wakeup callback
+ * will run by holding the wait queue head lock and will call our callback
+ * that will try to get "ep->lock".
+ */
+ ep_unregister_pollwait(ep, epi);
+
+ /* Remove the current item from the list of epoll hooks */
+ spin_lock(&epi->file->f_ep_lock);
+ if (EP_IS_LINKED(&epi->fllink))
+ EP_LIST_DEL(&epi->fllink);
+ spin_unlock(&epi->file->f_ep_lock);
+
+ /* We need to acquire the write IRQ lock before calling ep_unlink() */
+ write_lock_irqsave(&ep->lock, flags);
+
+ /* Really unlink the item from the hash */
+ error = ep_unlink(ep, epi);
+
+ write_unlock_irqrestore(&ep->lock, flags);
+
+ if (error)
+ goto eexit_1;
+
+ /* At this point it is safe to free the eventpoll item */
+ ep_release_epitem(epi);
+
+ error = 0;
+eexit_1:
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %p) = %d\n",
+ current, ep, epi->file, error));
+
+ return error;
+}
+
+
+/*
+ * This is the callback that is passed to the wait queue wakeup
+ * machanism. It is called by the stored file descriptors when they
+ * have events to report.
+ */
+static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync)
+{
+ int pwake = 0;
+ unsigned long flags;
+ struct epitem *epi = EP_ITEM_FROM_WAIT(wait);
+ struct eventpoll *ep = epi->ep;
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n",
+ current, epi->file, epi, ep));
+
+ write_lock_irqsave(&ep->lock, flags);
+
+ /* If this file is already in the ready list we exit soon */
+ if (EP_IS_LINKED(&epi->rdllink))
+ goto is_linked;
+
+ list_add_tail(&epi->rdllink, &ep->rdllist);
+
+is_linked:
+ /*
+ * Wake up ( if active ) both the eventpoll wait list and the ->poll()
+ * wait list.
+ */
+ if (waitqueue_active(&ep->wq))
+ wake_up(&ep->wq);
+ if (waitqueue_active(&ep->poll_wait))
+ pwake++;
+
+ write_unlock_irqrestore(&ep->lock, flags);
+
+ /* We have to call this outside the lock */
+ if (pwake)
+ ep_poll_safewake(&psw, &ep->poll_wait);
+
+ return 1;
+}
+
+
+static int ep_eventpoll_close(struct inode *inode, struct file *file)
+{
+ struct eventpoll *ep = file->private_data;
+
+ if (ep) {
+ ep_free(ep);
+ kfree(ep);
+ }
+
+ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: close() ep=%p\n", current, ep));
+ return 0;
+}
+
+
+static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait)
+{
+ unsigned int pollflags = 0;
+ unsigned long flags;
+ struct eventpoll *ep = file->private_data;
+
+ /* Insert inside our poll wait queue */
+ poll_wait(file, &ep->poll_wait, wait);
+
+ /* Check our condition */
+ read_lock_irqsave(&ep->lock, flags);
+ if (!list_empty(&ep->rdllist))
+ pollflags = POLLIN | POLLRDNORM;
+ read_unlock_irqrestore(&ep->lock, flags);
+
+ return pollflags;
+}
+
+
+/*
+ * Since we have to release the lock during the __copy_to_user() operation and
+ * during the f_op->poll() call, we try to collect the maximum number of items
+ * by reducing the irqlock/irqunlock switching rate.
+ */
+static int ep_collect_ready_items(struct eventpoll *ep, struct epitem **aepi, int maxepi)
+{
+ int nepi;
+ unsigned long flags;
+ struct list_head *lsthead = &ep->rdllist;
+
+ write_lock_irqsave(&ep->lock, flags);
+
+ for (nepi = 0; nepi < maxepi && !list_empty(lsthead);) {
+ struct epitem *epi = list_entry(lsthead->next, struct epitem, rdllink);
+
+ /* Remove the item from the ready list */
+ EP_LIST_DEL(&epi->rdllink);
+
+ /*
+ * We need to increase the usage count of the "struct epitem" because
+ * another thread might call EPOLL_CTL_DEL on this target and make the
+ * object to vanish underneath our nose.
+ */
+ ep_use_epitem(epi);
+
+ aepi[nepi++] = epi;
+ }
+
+ write_unlock_irqrestore(&ep->lock, flags);
+
+ return nepi;
+}
+
+
+/*
+ * This function is called without holding the "ep->lock" since the call to
+ * __copy_to_user() might sleep, and also f_op->poll() might reenable the IRQ
+ * because of the way poll() is traditionally implemented in Linux.
+ */
+static int ep_send_events(struct eventpoll *ep, struct epitem **aepi, int nepi,
+ struct epoll_event *events)
+{
+ int i, eventcnt, eventbuf, revents;
+ struct epitem *epi;
+ struct epoll_event event[EP_MAX_BUF_EVENTS];
+
+ for (i = 0, eventcnt = 0, eventbuf = 0; i < nepi; i++, aepi++) {
+ epi = *aepi;
+
+ /* Get the ready file event set */
+ revents = epi->file->f_op->poll(epi->file, NULL);
+
+ if (revents & epi->event.events) {
+ event[eventbuf] = epi->event;
+ event[eventbuf].events &= revents;
+ eventbuf++;
+ if (eventbuf == EP_MAX_BUF_EVENTS) {
+ if (__copy_to_user(&events[eventcnt], event,
+ eventbuf * sizeof(struct epoll_event))) {
+ for (; i < nepi; i++, aepi++)
+ ep_release_epitem(*aepi);
+ return -EFAULT;
+ }
+ eventcnt += eventbuf;
+ eventbuf = 0;
+ }
+ }
+
+ ep_release_epitem(epi);
+ }
+
+ if (eventbuf) {
+ if (__copy_to_user(&events[eventcnt], event,
+ eventbuf * sizeof(struct epoll_event)))
+ return -EFAULT;
+ eventcnt += eventbuf;
+ }
+
+ return eventcnt;
+}
+
+
+/*
+ * Perform the transfer of events to user space.
+ */
+static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents)
+{
+ int eventcnt, nepi, sepi, maxepi;
+ struct epitem *aepi[EP_MAX_COLLECT_ITEMS];
+
+ /*
+ * We need to lock this because we could be hit by
+ * eventpoll_release() while we're transfering
+ * events to userspace. Read-holding "epsem" will lock
+ * out eventpoll_release() during the whole
+ * transfer loop and this will garantie us that the
+ * file will not vanish underneath our nose when
+ * we will call f_op->poll() from ep_send_events().
+ */
+ down_read(&epsem);
+
+ for (eventcnt = 0; eventcnt < maxevents;) {
+ /* Maximum items we can extract this time */
+ maxepi = min(EP_MAX_COLLECT_ITEMS, maxevents - eventcnt);
+
+ /* Collect/extract ready items */
+ nepi = ep_collect_ready_items(ep, aepi, maxepi);
+
+ if (nepi) {
+ /* Send events to userspace */
+ sepi = ep_send_events(ep, aepi, nepi, &events[eventcnt]);
+ if (sepi < 0) {
+ up_read(&epsem);
+ return sepi;
+ }
+ eventcnt += sepi;
+ }
+
+ if (nepi < maxepi)
+ break;
+ }
+
+ up_read(&epsem);
+
+ return eventcnt;
+}
+
+
+static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
+ int timeout)
+{
+ int res, eavail;
+ unsigned long flags;
+ long jtimeout;
+ wait_queue_t wait;
+
+ /*
+ * Calculate the timeout by checking for the "infinite" value ( -1 ).
+ * The passed timeout is in milliseconds, that why (t * HZ) / 1000.
+ */
+ jtimeout = timeout == -1 ? MAX_SCHEDULE_TIMEOUT: (timeout * HZ) / 1000;
+
+retry:
+ write_lock_irqsave(&ep->lock, flags);
+
+ res = 0;
+ if (list_empty(&ep->rdllist)) {
+ /*
+ * We don't have any available event to return to the caller.
+ * We need to sleep here, and we will be wake up by
+ * ep_poll_callback() when events will become available.
+ */
+ init_waitqueue_entry(&wait, current);
+ add_wait_queue(&ep->wq, &wait);
+
+ for (;;) {
+ /*
+ * We don't want to sleep if the ep_poll_callback() sends us
+ * a wakeup in between. That's why we set the task state
+ * to TASK_INTERRUPTIBLE before doing the checks.
+ */
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (!list_empty(&ep->rdllist) || !jtimeout)
+ break;
+ if (signal_pending(current)) {
+ res = -EINTR;
+ break;
+ }
+
+ write_unlock_irqrestore(&ep->lock, flags);
+ jtimeout = schedule_timeout(jtimeout);
+ write_lock_irqsave(&ep->lock, flags);
+ }
+ remove_wait_queue(&ep->wq, &wait);
+
+ set_current_state(TASK_RUNNING);
+ }
+
+ /* Is it worth to try to dig for events ? */
+ eavail = !list_empty(&ep->rdllist);
+
+ write_unlock_irqrestore(&ep->lock, flags);
+
+ /*
+ * Try to transfer events to user space. In case we get 0 events and
+ * there's still timeout left over, we go trying again in search of
+ * more luck.
+ */
+ if (!res && eavail &&
+ !(res = ep_events_transfer(ep, events, maxevents)) && jtimeout)
+ goto retry;
+
+ return res;
+}
+
+
+static int eventpollfs_delete_dentry(struct dentry *dentry)
+{
+
+ return 1;
+}
+
+
+static struct inode *ep_eventpoll_inode(void)
+{
+ int error = -ENOMEM;
+ struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
+
+ if (!inode)
+ goto eexit_1;
+
+ inode->i_fop = &eventpoll_fops;
+
+ /*
+ * Mark the inode dirty from the very beginning,
+ * that way it will never be moved to the dirty
+ * list because mark_inode_dirty() will think
+ * that it already _is_ on the dirty list.
+ */
+ inode->i_state = I_DIRTY;
+ inode->i_mode = S_IRUSR | S_IWUSR;
+ inode->i_uid = current->fsuid;
+ inode->i_gid = current->fsgid;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ inode->i_blksize = PAGE_SIZE;
+ return inode;
+
+eexit_1:
+ return ERR_PTR(error);
+}
+
+
+static int __init eventpoll_init(void)
+{
+ int error;
+
+ /* Initialize the semaphore used to syncronize the file cleanup code */
+ init_rwsem(&epsem);
+
+ /* Initialize the structure used to perform safe poll wait head wake ups */
+ ep_poll_safewake_init(&psw);
+
+ /* Allocates slab cache used to allocate "struct epitem" items */
+ error = -ENOMEM;
+ epi_cache = kmem_cache_create("eventpoll epi",
+ sizeof(struct epitem),
+ 0,
+ SLAB_HWCACHE_ALIGN | EPI_SLAB_DEBUG, NULL, NULL);
+ if (!epi_cache)
+ goto eexit_1;
+
+ /* Allocates slab cache used to allocate "struct eppoll_entry" */
+ error = -ENOMEM;
+ pwq_cache = kmem_cache_create("eventpoll pwq",
+ sizeof(struct eppoll_entry),
+ 0,
+ EPI_SLAB_DEBUG, NULL, NULL);
+ if (!pwq_cache)
+ goto eexit_2;
+
+ /*
+ * Register the virtual file system that will be the source of inodes
+ * for the eventpoll files
+ */
+ error = register_filesystem(&eventpoll_fs_type);
+ if (error)
+ goto eexit_3;
+
+ /* Mount the above commented virtual file system */
+ eventpoll_mnt = kern_mount(&eventpoll_fs_type);
+ error = PTR_ERR(eventpoll_mnt);
+ if (IS_ERR(eventpoll_mnt))
+ goto eexit_4;
+
+ return 0;
+
+eexit_4:
+ unregister_filesystem(&eventpoll_fs_type);
+eexit_3:
+ kmem_cache_destroy(pwq_cache);
+eexit_2:
+ kmem_cache_destroy(epi_cache);
+eexit_1:
+
+ return error;
+}
+
+
+static void __exit eventpoll_exit(void)
+{
+ /* Undo all operations done inside eventpoll_init() */
+ unregister_filesystem(&eventpoll_fs_type);
+ mntput(eventpoll_mnt);
+ kmem_cache_destroy(pwq_cache);
+ kmem_cache_destroy(epi_cache);
+}
+
+module_init(eventpoll_init);
+module_exit(eventpoll_exit);
+
+MODULE_LICENSE("GPL");
+
--- linux-2.4.20/fs/file_table.c Thu Nov 28 15:53:15 2002
+++ sys_epoll/fs/file_table.c Mon Dec 9 16:22:52 2002
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/smp_lock.h>
#include <linux/iobuf.h>
+#include <linux/eventpoll.h>
/* sysctl tunables... */
struct files_stat_struct files_stat = {0, 0, NR_FILE};
@@ -42,6 +43,7 @@
files_stat.nr_free_files--;
new_one:
memset(f, 0, sizeof(*f));
+ eventpoll_init_file(f);
atomic_set(&f->f_count,1);
f->f_version = ++event;
f->f_uid = current->fsuid;
@@ -85,6 +87,7 @@
int init_private_file(struct file *filp, struct dentry *dentry, int mode)
{
memset(filp, 0, sizeof(*filp));
+ eventpoll_init_file(filp);
filp->f_mode = mode;
atomic_set(&filp->f_count, 1);
filp->f_dentry = dentry;
@@ -104,6 +107,11 @@
struct inode * inode = dentry->d_inode;
if (atomic_dec_and_test(&file->f_count)) {
+ /*
+ * The function eventpoll_release() should be the
+ * first called in the file cleanup chain.
+ */
+ eventpoll_release(file);
locks_remove_flock(file);
if (file->f_iobuf)
--- linux-2.4.20/fs/select.c Mon Sep 10 13:04:33 2001
+++ sys_epoll/fs/select.c Mon Dec 9 16:22:52 2002
@@ -19,6 +19,7 @@
#include <linux/poll.h>
#include <linux/personality.h> /* for STICKY_TIMEOUTS */
#include <linux/file.h>
+#include <linux/fs.h>
#include <asm/uaccess.h>
@@ -52,10 +53,18 @@
* as all select/poll functions have to call it to add an entry to the
* poll table.
*/
+void __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p);
-void poll_freewait(poll_table* pt)
+void poll_initwait(struct poll_wqueues *pwq)
{
- struct poll_table_page * p = pt->table;
+ init_poll_funcptr(&pwq->pt, __pollwait);
+ pwq->error = 0;
+ pwq->table = NULL;
+}
+
+void poll_freewait(struct poll_wqueues *pwq)
+{
+ struct poll_table_page * p = pwq->table;
while (p) {
struct poll_table_entry * entry;
struct poll_table_page *old;
@@ -72,8 +81,9 @@
}
}
-void __pollwait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
+void __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *_p)
{
+ struct poll_wqueues *p = container_of(_p, struct poll_wqueues, pt);
struct poll_table_page *table = p->table;
if (!table || POLL_TABLE_FULL(table)) {
@@ -103,6 +113,7 @@
}
}
+
#define __IN(fds, n) (fds->in + n)
#define __OUT(fds, n) (fds->out + n)
#define __EX(fds, n) (fds->ex + n)
@@ -163,7 +174,8 @@
int do_select(int n, fd_set_bits *fds, long *timeout)
{
- poll_table table, *wait;
+ struct poll_wqueues table;
+ poll_table *wait;
int retval, i, off;
long __timeout = *timeout;
@@ -176,7 +188,7 @@
n = retval;
poll_initwait(&table);
- wait = &table;
+ wait = &table.pt;
if (!__timeout)
wait = NULL;
retval = 0;
@@ -383,10 +395,10 @@
}
static int do_poll(unsigned int nfds, unsigned int nchunks, unsigned int nleft,
- struct pollfd *fds[], poll_table *wait, long timeout)
+ struct pollfd *fds[], struct poll_wqueues *wait, long timeout)
{
int count;
- poll_table* pt = wait;
+ poll_table* pt = &wait->pt;
for (;;) {
unsigned int i;
@@ -413,7 +425,7 @@
{
int i, j, fdcount, err;
struct pollfd **fds;
- poll_table table, *wait;
+ struct poll_wqueues table, *wait;
int nchunks, nleft;
/* Do a sanity check on nfds ... */
--- linux-2.4.20/include/asm-i386/unistd.h Thu Nov 28 15:53:15 2002
+++ sys_epoll/include/asm-i386/unistd.h Mon Dec 9 18:33:37 2002
@@ -257,6 +257,10 @@
#define __NR_alloc_hugepages 250
#define __NR_free_hugepages 251
#define __NR_exit_group 252
+#define __NR_epoll_create 254
+#define __NR_epoll_ctl 255
+#define __NR_epoll_wait 256
+
/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
--- linux-2.4.20/include/asm-ppc/unistd.h Thu Nov 28 15:53:15 2002
+++ sys_epoll/include/asm-ppc/unistd.h Mon Dec 9 18:33:59 2002
@@ -241,6 +241,9 @@
#define __NR_io_submit 230
#define __NR_io_cancel 231
#endif
+#define __NR_epoll_create 254
+#define __NR_epoll_ctl 255
+#define __NR_epoll_wait 256
#define __NR(n) #n
--- linux-2.4.20/include/linux/eventpoll.h Wed Dec 31 16:00:00 1969
+++ sys_epoll/include/linux/eventpoll.h Mon Dec 9 16:22:53 2002
@@ -0,0 +1,49 @@
+/*
+ * include/linux/eventpoll.h ( Efficent event polling implementation )
+ * Copyright (C) 2001,...,2002 Davide Libenzi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#ifndef _LINUX_EVENTPOLL_H
+#define _LINUX_EVENTPOLL_H
+
+
+/* Valid opcodes to issue to sys_epoll_ctl() */
+#define EPOLL_CTL_ADD 1
+#define EPOLL_CTL_DEL 2
+#define EPOLL_CTL_MOD 3
+
+struct epoll_event {
+ __u32 events;
+ __u64 data;
+};
+
+#ifdef __KERNEL__
+
+/* Forward declarations to avoid compiler errors */
+struct file;
+
+
+/* Kernel space functions implementing the user space "epoll" API */
+asmlinkage int sys_epoll_create(int size);
+asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
+asmlinkage int sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
+ int timeout);
+
+/* Used to initialize the epoll bits inside the "struct file" */
+void eventpoll_init_file(struct file *file);
+
+/* Used in fs/file_table.c:__fput() to unlink files from the eventpoll interface */
+void eventpoll_release(struct file *file);
+
+#endif /* #ifdef __KERNEL__ */
+
+#endif /* #ifndef _LINUX_EVENTPOLL_H */
+
--- linux-2.4.20/include/linux/fs.h Thu Nov 28 15:53:15 2002
+++ sys_epoll/include/linux/fs.h Mon Dec 9 16:49:09 2002
@@ -542,6 +542,8 @@
/* preallocated helper kiobuf to speedup O_DIRECT */
struct kiobuf *f_iobuf;
long f_iobuf_lock;
+ struct list_head f_ep_links;
+ spinlock_t f_ep_lock;
};
extern spinlock_t files_lock;
#define file_list_lock() spin_lock(&files_lock);
--- linux-2.4.20/include/linux/hash.h Wed Dec 31 16:00:00 1969
+++ sys_epoll/include/linux/hash.h Mon Dec 9 16:22:52 2002
@@ -0,0 +1,58 @@
+#ifndef _LINUX_HASH_H
+#define _LINUX_HASH_H
+/* Fast hashing routine for a long.
+ (C) 2002 William Lee Irwin III, IBM */
+
+/*
+ * Knuth recommends primes in approximately golden ratio to the maximum
+ * integer representable by a machine word for multiplicative hashing.
+ * Chuck Lever verified the effectiveness of this technique:
+ * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
+ *
+ * These primes are chosen to be bit-sparse, that is operations on
+ * them can use shifts and additions instead of multiplications for
+ * machines where multiplications are slow.
+ */
+#if BITS_PER_LONG == 32
+/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e370001UL
+#elif BITS_PER_LONG == 64
+/* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL
+#else
+#error Define GOLDEN_RATIO_PRIME for your wordsize.
+#endif
+
+static inline unsigned long hash_long(unsigned long val, unsigned int bits)
+{
+ unsigned long hash = val;
+
+#if BITS_PER_LONG == 64
+ /* Sigh, gcc can't optimise this alone like it does for 32 bits. */
+ unsigned long n = hash;
+ n <<= 18;
+ hash -= n;
+ n <<= 33;
+ hash -= n;
+ n <<= 3;
+ hash += n;
+ n <<= 3;
+ hash -= n;
+ n <<= 4;
+ hash += n;
+ n <<= 2;
+ hash += n;
+#else
+ /* On some cpus multiply is faster, on others gcc will do shifts */
+ hash *= GOLDEN_RATIO_PRIME;
+#endif
+
+ /* High bits are more random, so use them. */
+ return hash >> (BITS_PER_LONG - bits);
+}
+
+static inline unsigned long hash_ptr(void *ptr, unsigned int bits)
+{
+ return hash_long((unsigned long)ptr, bits);
+}
+#endif /* _LINUX_HASH_H */
--- linux-2.4.20/include/linux/kernel.h Thu Nov 28 15:53:15 2002
+++ sys_epoll/include/linux/kernel.h Mon Dec 9 16:49:09 2002
@@ -174,6 +174,18 @@
extern void __out_of_line_bug(int line) ATTRIB_NORET;
#define out_of_line_bug() __out_of_line_bug(__LINE__)
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
#endif /* __KERNEL__ */
#define SI_LOAD_SHIFT 16
--- linux-2.4.20/include/linux/poll.h Thu Nov 22 11:46:26 2001
+++ sys_epoll/include/linux/poll.h Mon Dec 9 16:49:11 2002
@@ -10,28 +10,39 @@
#include <linux/mm.h>
#include <asm/uaccess.h>
-struct poll_table_page;
+struct poll_table_struct;
+
+/*
+ * structures and helpers for f_op->poll implementations
+ */
+typedef void (*poll_queue_proc)(struct file *, wait_queue_head_t *, struct poll_table_struct *);
typedef struct poll_table_struct {
- int error;
- struct poll_table_page * table;
+ poll_queue_proc qproc;
} poll_table;
-extern void __pollwait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p);
-
static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
{
if (p && wait_address)
- __pollwait(filp, wait_address, p);
+ p->qproc(filp, wait_address, p);
}
-static inline void poll_initwait(poll_table* pt)
+static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc)
{
- pt->error = 0;
- pt->table = NULL;
+ pt->qproc = qproc;
}
-extern void poll_freewait(poll_table* pt);
+/*
+ * Structures and helpers for sys_poll/sys_poll
+ */
+struct poll_wqueues {
+ poll_table pt;
+ struct poll_table_page * table;
+ int error;
+};
+
+extern void poll_initwait(struct poll_wqueues *pwq);
+extern void poll_freewait(struct poll_wqueues *pwq);
/*
* Scaleable version of the fd_set.
--- linux-2.4.20/include/linux/sched.h Thu Nov 28 15:53:15 2002
+++ sys_epoll/include/linux/sched.h Mon Dec 9 16:49:09 2002
@@ -145,6 +145,8 @@
extern spinlock_t runqueue_lock;
extern spinlock_t mmlist_lock;
+typedef struct task_struct task_t;
+
extern void sched_init(void);
extern void init_idle(void);
extern void show_state(void);
--- linux-2.4.20/include/linux/sys.h Sun Dec 10 20:56:37 1995
+++ sys_epoll/include/linux/sys.h Mon Dec 9 16:22:52 2002
@@ -4,7 +4,7 @@
/*
* system call entry points ... but not all are defined
*/
-#define NR_syscalls 256
+#define NR_syscalls 260
/*
* These are system calls that will be removed at some time
--- linux-2.4.20/include/linux/wait.h Thu Nov 22 11:46:19 2001
+++ sys_epoll/include/linux/wait.h Mon Dec 9 16:49:09 2002
@@ -19,6 +19,9 @@
#include <asm/page.h>
#include <asm/processor.h>
+typedef struct __wait_queue wait_queue_t;
+typedef void (*wait_queue_func_t)(wait_queue_t *wait);
+
/*
* Debug control. Slow but useful.
*/
@@ -32,13 +35,13 @@
unsigned int flags;
#define WQ_FLAG_EXCLUSIVE 0x01
struct task_struct * task;
+ wait_queue_func_t func;
struct list_head task_list;
#if WAITQUEUE_DEBUG
long __magic;
long __waker;
#endif
};
-typedef struct __wait_queue wait_queue_t;
/*
* 'dual' spinlock architecture. Can be switched between spinlock_t and
@@ -138,6 +141,7 @@
#define __WAITQUEUE_INITIALIZER(name, tsk) { \
task: tsk, \
+ func: NULL, \
task_list: { NULL, NULL }, \
__WAITQUEUE_DEBUG_INIT(name)}
@@ -174,10 +178,18 @@
#endif
q->flags = 0;
q->task = p;
+ q->func = NULL;
#if WAITQUEUE_DEBUG
q->__magic = (long)&q->__magic;
#endif
}
+static inline void init_waitqueue_func_entry(wait_queue_t *q,
+ wait_queue_func_t func)
+{
+ q->flags = 0;
+ q->task = NULL;
+ q->func = func;
+}
static inline int waitqueue_active(wait_queue_head_t *q)
{
@@ -189,6 +201,22 @@
return !list_empty(&q->task_list);
}
+#define add_wait_queue_cond(q, wait, cond) \
+ ({ \
+ unsigned long flags; \
+ int _raced = 0; \
+ wq_write_lock_irqsave(&(q)->lock, flags); \
+ (wait)->flags = 0; \
+ __add_wait_queue((q), (wait)); \
+ rmb(); \
+ if (!(cond)) { \
+ _raced = 1; \
+ __remove_wait_queue((q), (wait)); \
+ } \
+ wq_write_unlock_irqrestore(&(q)->lock, flags); \
+ _raced; \
+ })
+
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
{
--- linux-2.4.20/kernel/ksyms.c Thu Nov 28 15:53:15 2002
+++ sys_epoll/kernel/ksyms.c Mon Dec 9 16:22:53 2002
@@ -257,7 +257,7 @@
EXPORT_SYMBOL(generic_read_dir);
EXPORT_SYMBOL(generic_file_llseek);
EXPORT_SYMBOL(no_llseek);
-EXPORT_SYMBOL(__pollwait);
+EXPORT_SYMBOL(poll_initwait);
EXPORT_SYMBOL(poll_freewait);
EXPORT_SYMBOL(ROOT_DEV);
EXPORT_SYMBOL(__find_get_page);
--- linux-2.4.20/kernel/sched.c Thu Nov 28 15:53:15 2002
+++ sys_epoll/kernel/sched.c Mon Dec 9 16:22:53 2002
@@ -714,16 +714,24 @@
static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode,
int nr_exclusive, const int sync)
{
- struct list_head *tmp;
+ struct list_head *tmp, *next;
struct task_struct *p;
CHECK_MAGIC_WQHEAD(q);
WQ_CHECK_LIST_HEAD(&q->task_list);
- list_for_each(tmp,&q->task_list) {
+ list_for_each_safe(tmp, next, &q->task_list) {
unsigned int state;
+ wait_queue_func_t func;
wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list);
-
+ func = curr->func;
+ if (func) {
+ unsigned flags = curr->flags;
+ func(curr);
+ if ((flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
+ break;
+ continue;
+ }
CHECK_MAGIC(curr->__magic);
p = curr->task;
state = p->state;
^ permalink raw reply
* RE: 2.5.51: sleep broken
From: Grover, Andrew @ 2002-12-12 22:42 UTC (permalink / raw)
To: 'P. Christeas',
acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
> From: P. Christeas [mailto:p_christ-U04EIuiosng@public.gmane.org]
> > However, /proc/acpi/sleep has all S0 S1 S2 S3 S4 S5
> > When I 'echo 1 >/proc/acpi/sleep', nothing happens.
> > I'll let you know if I have more details..
> I noticed I had some extra dbg code to indicate what's
> happening in the procfs
> level.
> Now, it seems that "1" doesn't get written to the acpi/sleep
> entry. It's a
> procfs bug.
Look for a msg on 11/30 by Pavel Machek. Apparently the proc code got broken
by the seq_file stuff... supposedly they were going to fix it, but maybe it
would be easier if we all did.
- entry->write_proc = acpi_system_write_sleep;
+ entry->proc_fops->write = acpi_system_write_sleep;
Regards -- Andy
-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
^ permalink raw reply
* Re: [PATCH] 2.5.51 SCSI_IOCTL_GET_IDLUN + _GET_BUS_NUMBER
From: Douglas Gilbert @ 2002-12-12 22:40 UTC (permalink / raw)
To: Jens Axboe; +Cc: James Bottomley, linux-scsi
In-Reply-To: <20021212174241.GB6481@suse.de>
Jens Axboe wrote:
> On Thu, Dec 12 2002, James Bottomley wrote:
>
>>dougg@torque.net said:
>>
>>>For disks both the SCSI_IOCTL_GET_IDLUN and SCSI_IOCTL_GET_BUS_NUMBER
>>>ioctls return the value 0 (type: int) in all cases. The attachment
>>>removes the dummy definitions of these ioctls in driver/block/
>>>scsi_ioctl.c so they fall through to the scsi mid level which
>>>correctly implements them (at least in terms of lk 2.4).
>>
>>I'm not sure this is the correct thing to do. These ioctls may be there
>>because cdrecord is using them. In the new scheme, you can record a CD
>>without ever troubling the scsi mid-layer, so if cdrecord wants them, they
>>have to be provided in some fashion without relying on a fall through.
>>
>>I've copied Jens on this mail, since he's the one that knows this stuff and
>>should be able to confirm or deny this suspicion. Jens?
>
>
> Hmm, I _may_ be wrong but I think the main reason for GET_IDLUN and
> GET_BUS_NUMBER in the generic block layer is to stop them from failing
> in libscg and thus fooling it into believing we are scsi. You would need
> to check libscg/scsi-linux-sg.c to be sure.
One reason libscg/scsi-linux-sg.c (cdrecord) would use
them is to differentiate between multiple "pseudo" scsi
devices when it is doing a scd to sg mapping. [This is the area
where I saw my sg_utils break.]
So defining them and always yielding 0 is going to confuse
it when there are two or more devices (e.g. 2 cd writers).
cdrecord uses the <host, target_id, lun> triple to enumerate
cd writers (rather than linux's <host, channel, target_id, lun>).
It is not clear to me how trying to define a correct
SCSI_IOCTL_GET_IDLUN ioctl in the block level can cope with
the strange combination of one scsi cdwriter and one atapi
cdrwiter in the same box. [That is, will they have distinct
host numbers?]
There are also applications like cdparanoia to consider.
> For one thing, we need to maintain the behaviour we have now of _not_
> failing them for ata devices. If you want to pass them down to SCSI as
> well and get the right id/lun and bus, fine, but don't break the ata
> one.
There is also the meaning of these ioctls in lk 2.4
to consider.
How to define these ioctls properly for scsi block devices
and return "0" for other types of block devices??
Well sd and sr could be patched to route these two ioctls
to the scsi mid level and let other ioctls be diverted
through drivers/block/scsi_ioctl.c . Is that ugly enough :-)
BTW SCSI_IOCTL_GET_IDLUN ioctl in lk 2.4 and earlier yields
2 integer values (not 1).
Doug Gilbert
^ permalink raw reply
* Re: 2.5.5[01]]: Xircom Cardbus broken (PCI resource collisions)
From: Valdis.Kletnieks @ 2002-12-12 22:47 UTC (permalink / raw)
To: Alessandro Suardi; +Cc: linux-kernel
[-- Attachment #1.1: Type: text/plain, Size: 214 bytes --]
> PCI: Device 02:00.0 not available because of resource collisions
> PCI: Device 02:00.1 not available because of resource collisions
Been there. Done that. Does the attached patch help? It did for me.
/Valdis
[-- Attachment #1.2: pcmcia.patch --]
[-- Type: text/plain , Size: 492 bytes --]
--- drivers/pcmcia/cardbus.c.dist 2002-12-03 01:49:29.000000000 -0500
+++ drivers/pcmcia/cardbus.c 2002-12-03 01:50:23.000000000 -0500
@@ -283,8 +283,6 @@
dev->hdr_type = hdr & 0x7f;
pci_setup_device(dev);
- if (pci_enable_device(dev))
- continue;
strcpy(dev->dev.bus_id, dev->slot_name);
@@ -302,6 +300,8 @@
pci_writeb(dev, PCI_INTERRUPT_LINE, irq);
}
+ if (pci_enable_device(dev))
+ continue;
device_register(&dev->dev);
pci_insert_device(dev, bus);
}
[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]
^ permalink raw reply
* Re: playback in multiple period_size?
From: Guilhem Tardy @ 2002-12-12 22:34 UTC (permalink / raw)
To: Jaroslav Kysela; +Cc: alsa-devel
In-Reply-To: <Pine.LNX.4.33.0212122255220.3487-100000@pnote.perex-int.cz>
> > Is the application supposed to always add silence at the end to ensure that
> > a multiple of period_size has been written?
>
> It looks like a bug. Could you send me a little C code which triggers this
> problem?
Sure, the code is below. Everything is alright until the I drain() before
close(). As it happens, drain() only returns seconds later, with an error.
Thanks,
Guilhem.
#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
#include
"/usr/src/download/alsa-driver-0.9.0rc6/alsa-kernel/pci/pci2103/pci2103-ioctls.h"
#define BUFBYTES 512
#define SIMULBYTES 160000
void About(void)
{
fprintf (stderr, "Syntax: test_write [-8|-16|-U|-A] [device] [file.raw]\n");
exit (-1);
}
void writei_func(snd_pcm_t *handle, char *data, snd_pcm_uframes_t count)
{
int ret;
while (count > 0) {
ret = snd_pcm_writei (handle, data, count);
if (ret < 0) {
fprintf(stderr, "write to audio interface failed (%s)",
snd_strerror (ret));
exit (-1);
}
if (ret > 0) {
count -= ret;
data += snd_pcm_samples_to_bytes(handle, ret);
}
}
}
main (int argc, char *argv[])
{
int i;
int err;
int card, dev;
char card_id[32];
char dev_id[32];
const char *str_result;
snd_ctl_t *ctl_handle;
snd_ctl_card_info_t *card_info;
snd_hwdep_info_t *hwdep_info;
snd_hwdep_iface_t iface;
snd_hwdep_t *hwdep;
snd_pcm_format_t format;
snd_pcm_t *playback_handle;
snd_pcm_hw_params_t *hw_params;
snd_pcm_uframes_t min_align;
snd_pcm_sw_params_t *sw_params;
char buf[BUFBYTES];
int fd, bytes, samples, size, isPCI2103 = 0;
printf("argc=%d [\"%s\", \"%s\", \"%s\"]\n", argc, argv[1], argv[2], argv[3]);
if (argc < 3) {
fprintf (stderr, "Not enough arguments!!!\n");
About();
}
if (argc > 4) {
fprintf (stderr, "Too many arguments!!!\n");
About();
}
if (!strcmp(argv[1],"-8"))
format = SND_PCM_FORMAT_S8;
else if (!strcmp(argv[1],"-16"))
format = SND_PCM_FORMAT_S16_LE;
else if (!strcmp(argv[1],"-U"))
format = SND_PCM_FORMAT_MU_LAW;
else if (!strcmp(argv[1],"-A"))
format = SND_PCM_FORMAT_G726_16KBPS;
else {
fprintf (stderr, "Unknown format!!!\n");
About();
}
card = atoi(argv[2]+3);
if (card < 0 || card > 31) {
fprintf (stderr, "Wrong argument '%d' in '%s'\n", card, argv[2]);
exit (-1);
}
////////////////////////////////////////////
// Open the CTL device
// Get control handle for selected card
sprintf(card_id, "hw:%i", card);
if ((err = snd_ctl_open(&ctl_handle, card_id, 0)) < 0) {
fprintf (stderr, "control open (%s): %s\n", card_id, snd_strerror(err));
exit (-1);
}
if ((err = snd_ctl_card_info_malloc(&card_info)) < 0) {
fprintf (stderr, "cannot allocate card info structure (%s)\n",
snd_strerror (err));
exit (-1);
}
// Read control info from card
if ((err = snd_ctl_card_info(ctl_handle, card_info)) < 0) {
fprintf (stderr, "control hardware info (%s): %s\n", card_id,
snd_strerror(err));
exit (-1);
}
// We would prefer a PCI2103 card!!!
str_result = snd_ctl_card_info_get_driver(card_info);
if (strcmp(str_result, "PCI2103")) {
fprintf (stderr, "driver (%s): not a PCI2103 type card\n", str_result);
}
else
isPCI2103 = 1;
snd_ctl_card_info_free(card_info);
// Find hardware dependant device
dev = -1;
while (1) {
if ((err = snd_ctl_hwdep_next_device(ctl_handle, &dev)) < 0) {
fprintf (stderr, "hwdep next device (%s): %s\n", card_id,
snd_strerror(err));
break;
}
if (dev < 0) // no more device
break;
sprintf(dev_id, "hw:%i,%i", card, dev);
if (strcmp(dev_id, argv[2])) // wrong device
continue;
if ((err = snd_hwdep_info_malloc(&hwdep_info)) < 0) {
fprintf (stderr, "cannot allocate hwdep info structure (%s)\n",
snd_strerror (err));
exit (-1);
}
snd_hwdep_info_set_device(hwdep_info, dev);
if ((err = snd_ctl_hwdep_info(ctl_handle, hwdep_info)) < 0) {
if (err != -ENOENT) {
fprintf (stderr, "control hwdep info (%s): %s\n", card_id,
snd_strerror(err));
exit (-1);
}
continue;
}
iface = snd_hwdep_info_get_iface(hwdep_info);
snd_hwdep_info_free(hwdep_info);
if (iface == SND_HWDEP_IFACE_PCI2103) {
////////////////////////////////////////////////////////
// Open the HWDEP device, and test special APIs
if ((err = snd_hwdep_open(&hwdep, dev_id, SND_HWDEP_OPEN_DUPLEX)) < 0) {
fprintf (stderr, "cannot open hwdep '%s' (%s)\n",
dev_id, snd_strerror (err));
exit (-1);
}
if ((err = snd_hwdep_ioctl(hwdep, PCI2103_SNDIOC_AES_ENABLE, (void *) 1)) <
0) {
fprintf (stderr, "cannot enable AES (%s)\n",
snd_strerror (err));
exit (-1);
}
if ((err = snd_hwdep_ioctl(hwdep, PCI2103_SNDIOC_AES_ENABLE, (void *) 0)) <
0) {
fprintf (stderr, "cannot disable AES (%s)\n",
snd_strerror (err));
exit (-1);
}
if ((err = snd_hwdep_close(hwdep)) < 0) {
fprintf (stderr, "cannot close hwdep (%s)\n",
snd_strerror (err));
exit (-1);
}
}
}
snd_ctl_close(ctl_handle);
////////////////////////////////////////////
// Open the PCM device
if ((err = snd_pcm_open (&playback_handle, argv[2], SND_PCM_STREAM_PLAYBACK,
0)) < 0) {
fprintf (stderr, "cannot open audio device %s (%s)\n",
argv[2],
snd_strerror (err));
exit (-1);
}
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
snd_strerror (err));
exit (-1);
}
if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
snd_strerror (err));
exit (-1);
}
if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params,
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
fprintf (stderr, "cannot set access type (%s)\n",
snd_strerror (err));
exit (-1);
}
if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, format))
< 0) {
fprintf (stderr, "cannot set sample format (%s)\n",
snd_strerror (err));
exit (-1);
}
if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, 8000,
0)) < 0) {
fprintf (stderr, "cannot set sample rate (%s)\n",
snd_strerror (err));
exit (-1);
}
if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 1)) <
0) {
fprintf (stderr, "cannot set channel count (%s)\n",
snd_strerror (err));
exit (-1);
}
if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
fprintf (stderr, "cannot set parameters (%s)\n",
snd_strerror (err));
exit (-1);
}
if ((err = snd_pcm_hw_params_get_min_align (hw_params, &min_align)) < 0) {
fprintf (stderr, "cannot get minimum transfer align value (%s)\n",
snd_strerror (err));
exit (-1);
}
snd_pcm_hw_params_free (hw_params);
if ((err = snd_pcm_sw_params_malloc (&sw_params)) < 0) {
fprintf (stderr, "cannot allocate software parameter structure (%s)\n",
snd_strerror (err));
exit (-1);
}
snd_pcm_sw_params_current(playback_handle, sw_params);
if ((err = snd_pcm_sw_params_set_xfer_align(playback_handle, sw_params,
min_align)) < 0) {
fprintf (stderr, "cannot set xfer_align (%s)\n",
snd_strerror (err));
exit (-1);
}
if ((err = snd_pcm_sw_params(playback_handle, sw_params)) < 0) {
fprintf (stderr, "unable to install sw params (%s)\n",
snd_strerror (err));
exit (-1);
}
snd_pcm_sw_params_free (sw_params);
////////////////////////////////////////////
// Play some tune
samples = snd_pcm_bytes_to_samples(playback_handle, BUFBYTES);
samples -= samples % min_align;
bytes = snd_pcm_samples_to_bytes(playback_handle, samples);
if (argc == 4) {
fd = open(argv[3], 0);
if (fd >= 0) {
i = 0;
printf("Now playing from a file in chunks of %d samples (%d bytes)\n",
samples, bytes);
while ((size = read(fd, buf, bytes)) > 0) {
fprintf(stderr, ".");
fflush(stderr);
samples = snd_pcm_bytes_to_samples(playback_handle, size);
samples -= samples % min_align;
writei_func(playback_handle, buf, samples);
}
fprintf(stderr, "\n");
fflush(stderr);
close(fd);
}
}
else {
for ( i = 0; i < bytes; ++i )
buf[i] = 0xFF;
printf("Now playing a simulated sound in chunks of %d samples (%d
bytes)...\n", samples, bytes);
for (i = 0; i < SIMULBYTES; i+=bytes)
writei_func(playback_handle, buf, samples);
}
snd_pcm_drain (playback_handle);
printf( "Playing is now finished.\n" );
snd_pcm_close (playback_handle);
exit (0);
}
__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com
-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
^ permalink raw reply
* Re: Kernel bug handling TCP_RTO_MAX?
From: Matti Aarnio @ 2002-12-12 22:38 UTC (permalink / raw)
To: Andreani Stefano; +Cc: linux-kernel, linux-net
In-Reply-To: <047ACC5B9A00D741927A4A32E7D01B73D66176@RMEXC01.h3g.it>
On Thu, Dec 12, 2002 at 08:15:42PM +0100, Andreani Stefano wrote:
> Problem: I need to change the max value of the TCP retransmission timeout.
...
> #define TCP_RTO_MAX ((unsigned)(6*HZ)) //It was: ((unsigned)(120*HZ))
>
> Then I recompiled the kernel, rebooted the machine and tested the
> solution. The result I obtained was the same I had before this
> modification.
Oh, you want to cap the retransmit time to 6 seconds so that
TCP works (at least somehow) in a terribly lossy network ?
Having that _low_ value at it isn't advisable in the general
internet, but these modern mobile networks with paketized data
are pain with dramatically varying latencies. TCP works
badly in such environments. X.25 works better - to a degree..
Changeing the value, and doing "make clean; make bzImage"
should give you a kernel with it in.
..
> Could it be a bug on the RTO calculation algorithm, or there is
> something I mistook?
Possibly omitting "make clean" -- short-cutting it can be done
by: "rm net/ipv4/*.o" I think..
> This is the first time I get into the linux kernel, so please be
> patient!
>
> Thanks,
> Stefano.
> -------------------------------
> Stefano Andreani
> Freelance ICT Consultant
> H3G IOT Team - Italy
> tel. +39 347 8215965
> stefano.andreani.ap@h3g.it
/Matti Aarnio
^ permalink raw reply
* Re: "bio too big" error
From: Kevin Corry @ 2002-12-12 21:51 UTC (permalink / raw)
To: Joe Thornber, Wil Reichert; +Cc: Greg KH, kernel list, lvm-devel
In-Reply-To: <20021212091209.GA1299@reti>
On Thursday 12 December 2002 03:12, Joe Thornber wrote:
> On Wed, Dec 11, 2002 at 04:15:42PM -0800, Wil Reichert wrote:
> > Ok, 2.5.51 plus dm patches result in the following:
> >
> > Initializing LVM: device-mapper: device
> > /dev/ide/host2/bus1/target0/lun0/disc too small for target
> > device-mapper: internal error adding target to table
> > device-mapper: destroying table
> > device-mapper ioctl cmd 2 failed: Invalid argument
> > Couldn't load device 'cheese_vg-blah'.
> > 0 logical volume(s) in volume group "cheese_vg" now active
> > lvm2.
> >
> > Was fine (minus of course the entire bio thing) in 50, did something
> > break in 51 or is it just my box?
>
> I've had a couple of reports of this problem. The offending patch is:
>
> http://people.sistina.com/~thornber/patches/2.5-stable/2.5.51/2.5.51-dm-1/0
>0005.patch
>
> back it out if necc.
>
> All it does is:
>
> --- diff/drivers/md/dm-table.c 2002-12-11 11:59:51.000000000 +0000
> +++ source/drivers/md/dm-table.c 2002-12-11 12:00:00.000000000 +0000
> @@ -388,7 +388,7 @@
> static int check_device_area(struct dm_dev *dd, sector_t start, sector_t
> len) {
> sector_t dev_size;
> - dev_size = dd->bdev->bd_inode->i_size;
> + dev_size = dd->bdev->bd_inode->i_size >> SECTOR_SHIFT;
> return ((start < dev_size) && (len <= (dev_size - start)));
> }
Actually, this 00005.patch *is* necessary. dd->bdev->bd_inode->i_size *is* in
bytes, and does need to be shifted to do the above comparison.
I believe we have tracked the problem down to the call to dm_get_device() in
dm-linear.c. It is passing in an incorrect value, which winds up being the
"start" parameter to the check_device_area() function. I've included a patch
at the end of this email which I believe should fix the problem. I have also
checked dm-stripe.c, and it appears to make the call to dm_get_device()
correctly, so no worries there.
--
Kevin Corry
corryk@us.ibm.com
http://evms.sourceforge.net/
--- linux-2.5.51a/drivers/md/dm-linear.c 2002/11/20 20:09:22 1.1
+++ linux-2.5.51b/drivers/md/dm-linear.c 2002/12/12 21:38:32
@@ -43,7 +43,7 @@
goto bad;
}
- if (dm_get_device(ti, argv[0], ti->begin, ti->len,
+ if (dm_get_device(ti, argv[0], lc->start, ti->len,
dm_table_get_mode(ti->table), &lc->dev)) {
ti->error = "dm-linear: Device lookup failed";
goto bad;
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.