* Re: converting cap_set_pg() to for_each_task_pid()
From: Greg KH @ 2002-12-18 23:08 UTC (permalink / raw)
To: William Lee Irwin III, chris, linux-kernel
In-Reply-To: <20021218055742.GE12812@holomorphy.com>
On Tue, Dec 17, 2002 at 09:57:42PM -0800, William Lee Irwin III wrote:
> I have a pending patch that converts cap_set_pg() to the
> for_each_task_pid() API. Could you review this, and if it
> pass, include it in your tree?
Applied to my tree, I'll send it to Linus in a bit.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH]: correct format string in dump_tlb
From: Ralf Baechle @ 2002-12-18 22:59 UTC (permalink / raw)
To: Juan Quintela; +Cc: linux mips mailing list
In-Reply-To: <m2wum8p0dy.fsf@demo.mitica>
On Wed, Dec 18, 2002 at 02:43:37AM +0100, Juan Quintela wrote:
> if we cast to unsigned it, print it as a long is a no-no :(
Correct but I didn't like your patch ...
> - printk("page == %08lx\n", (unsigned int) pte_val(page));
> + printk("page == %08x\n", (unsigned int) pte_val(page));
pte_val() returns unsigned long. So I applied a different fix.
Ralf
^ permalink raw reply
* [linux-lvm] PV Resizing
From: Monty Taylor @ 2002-12-18 22:57 UTC (permalink / raw)
To: linux-lvm
Hello.
I've managed to get myself into a rather funny spot -- I use LVM to
provide administrative flexibility, but I didn't account for one
possibility. I'm hoping someone has an idea...
I have a machine with a single hard drive. I have three partitions,
boot, swap, and the lvm partition. I now need to install a windows
partition... (damn CAD program won't run under WINE) Is there _any_ way
to resize the PV from under LVM? (Like with parted or something) so I
can create another partition?
Thanks in advance.
Monty
^ permalink raw reply
* Re: Help in cross-compiler--gcc3.2-7.1 error
From: H. J. Lu @ 2002-12-18 22:52 UTC (permalink / raw)
To: Chien-Lung Wu; +Cc: 'Brad Barrett', linux-mips
In-Reply-To: <A4E787A2467EF849B00585F14C9005590689B5@dprn03.deltartp.com>
On Wed, Dec 18, 2002 at 05:21:39PM -0500, Chien-Lung Wu wrote:
> Hi, Brad:
>
> Thanks for your information.
> I download:
> binutils v2.13.90.0.10 (H.J. Lu)
> GCC v3.2-7.1 (H.J. Lu)
> glibc v2.2.5
> glibc-linuxthreads v2.2.5
>
> and follow your build note to build a big-endian mips cross-compiler.
>
The cross compile toolchain, toolchain-20021126-1.src.rpm, I provided
is based on gcc 2.96. Although I do have one based gcc 3.2:
# /export/tools-3.2-redhat-8/bin/mips-linux-gcc
Reading specs from /export/tools-3.2-redhat-8/lib/gcc-lib/mips-linux/3.2.1/specs
Configured with: /export/linux/src/tools-3.2-redhat-8/tools/configure --disable-multilib --enable-clocale=gnu --with-system-zlib --target=mips-linux --prefix=/export/tools-3.2-redhat-8 --with-local-prefix=/export/tools-3.2-redhat-8 --enable-threads=posix --enable-haifa --enable-shared --disable-checking
Thread model: posix
gcc version 3.2.1 20021125 (Red Hat Linux 8.0 3.2.1-1)
it is the part of my RedHat 8.x port, which hasn't been finished yet.
H.J.
^ permalink raw reply
* [PATCH] update chipsfb.c to new API
From: Paul Mackerras @ 2002-12-18 22:59 UTC (permalink / raw)
To: James Simmons; +Cc: linux-kernel, benh
Here is a patch which updates chipsfb.c to the new 2.5 framebuffer
API. It simplifies the driver quite a bit, partly because the new API
is simpler and partly because the driver really can only handle one
65550 chip, since we access the chip via inb/outb to fixed I/O port
numbers.
I have tested it on a powerbook 3400, which has a C&T 65550 video chip
with 1MB of VRAM, and it seems to work just fine, at least in 8 bit
mode. I guess I still need to add the pseudo_palette stuff for 16 bit
mode. Unfortunately I can't test it under X at the moment because the
X server I have installed on the 3400 is Xpmac, which doesn't work any
more because the VC_GETMODE etc. ioctls have been removed. The 3400
is an old and slow machine with a small hard disk and an old Linux/PPC
installation on it, and I don't really want to compile up XFree86 on
it.
Paul.
--- linux-2.5/drivers/video/chipsfb.c 2002-12-10 15:20:32.000000000 +1100
+++ pmac-2.5/drivers/video/chipsfb.c 2002-12-18 22:05:59.000000000 +1100
@@ -2,7 +2,7 @@
* drivers/video/chipsfb.c -- frame buffer device for
* Chips & Technologies 65550 chip.
*
- * Copyright (C) 1998 Paul Mackerras
+ * Copyright (C) 1998-2002 Paul Mackerras
*
* This file is derived from the Powermac "chips" driver:
* Copyright (C) 1997 Fabio Riccardi.
@@ -39,34 +39,11 @@
#include <linux/pmu.h>
#endif
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/macmodes.h>
-
-struct fb_info_chips {
- struct fb_info info;
- struct fb_fix_screeninfo fix;
- struct fb_var_screeninfo var;
- struct display disp;
- struct {
- __u8 red, green, blue;
- } palette[256];
- struct pci_dev *pdev;
- unsigned long frame_buffer_phys;
- __u8 *frame_buffer;
- unsigned long blitter_regs_phys;
- __u32 *blitter_regs;
- unsigned long blitter_data_phys;
- __u8 *blitter_data;
- struct fb_info_chips *next;
-#ifdef CONFIG_PMAC_PBOOK
- unsigned char *save_framebuffer;
-#endif
-#ifdef FBCON_HAS_CFB16
- u16 fbcon_cfb16_cmap[16];
-#endif
-};
+/*
+ * Since we access the display with inb/outb to fixed port numbers,
+ * we can only handle one 6555x chip. -- paulus
+ */
+static struct fb_info chipsfb_info;
#define write_ind(num, val, ap, dp) do { \
outb((num), (ap)); outb((val), (dp)); \
@@ -98,9 +75,8 @@
inb(0x3da); read_ind(num, var, 0x3c0, 0x3c1); \
} while (0)
-static struct fb_info_chips *all_chips;
-
#ifdef CONFIG_PMAC_PBOOK
+static unsigned char *save_framebuffer;
int chips_sleep_notify(struct pmu_sleep_notifier *self, int when);
static struct pmu_sleep_notifier chips_sleep_notifier = {
chips_sleep_notify, SLEEP_LEVEL_VIDEO,
@@ -112,58 +88,29 @@
*/
int chips_init(void);
-static void chips_pci_init(struct pci_dev *dp);
-static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-static int chips_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int chips_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
+static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *);
+static int chipsfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info);
+static int chipsfb_set_par(struct fb_info *info);
static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
static int chipsfb_blank(int blank, struct fb_info *info);
static struct fb_ops chipsfb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = chips_get_fix,
- .fb_get_var = chips_get_var,
- .fb_set_var = chips_set_var,
- .fb_get_cmap = chips_get_cmap,
- .fb_set_cmap = gen_set_cmap,
- .fb_setcolreg = chipsfb_setcolreg,
- .fb_blank = chipsfb_blank,
-};
-
-static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,
- u_int *blue, u_int *transp, struct fb_info *info);
-static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp);
-
-static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
-{
- struct fb_info_chips *cp = (struct fb_info_chips *) info;
-
- *fix = cp->fix;
- return 0;
-}
-
-static int chips_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct fb_info_chips *cp = (struct fb_info_chips *) info;
-
- *var = cp->var;
- return 0;
-}
+ .owner = THIS_MODULE,
+ .fb_check_var = chipsfb_check_var,
+ .fb_set_par = chipsfb_set_par,
+ .fb_setcolreg = chipsfb_setcolreg,
+ .fb_blank = chipsfb_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_cursor = soft_cursor,
+};
-static int chips_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
+static int chipsfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
- struct fb_info_chips *cp = (struct fb_info_chips *) info;
- struct display *disp = (con >= 0)? &fb_display[con]: &cp->disp;
-
if (var->xres > 800 || var->yres > 600
|| var->xres_virtual > 800 || var->yres_virtual > 600
|| (var->bits_per_pixel != 8 && var->bits_per_pixel != 16)
@@ -171,198 +118,76 @@
|| (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
return -EINVAL;
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW &&
- var->bits_per_pixel != disp->var.bits_per_pixel) {
- chips_set_bitdepth(cp, disp, con, var->bits_per_pixel);
- }
+ var->xres = var->xres_virtual = 800;
+ var->yres = var->yres_virtual = 600;
return 0;
}
-static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
+static int chipsfb_set_par(struct fb_info *info)
{
- if (con == info->currcon) /* current console? */
- return fb_get_cmap(cmap, kspc, chipsfb_getcolreg, info);
- if (fb_display[con].cmap.len) /* non default colormap? */
- fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
- else {
- int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
- fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
+ if (info->var.bits_per_pixel == 16) {
+ write_cr(0x13, 200); // Set line length (doublewords)
+ write_xr(0x81, 0x14); // 15 bit (555) color mode
+ write_xr(0x82, 0x00); // Disable palettes
+ write_xr(0x20, 0x10); // 16 bit blitter mode
+
+ info->fix.line_length = 800*2;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+ info->var.red.offset = 10;
+ info->var.green.offset = 5;
+ info->var.blue.offset = 0;
+ info->var.red.length = info->var.green.length =
+ info->var.blue.length = 5;
+
+ } else {
+ /* p->var.bits_per_pixel == 8 */
+ write_cr(0x13, 100); // Set line length (doublewords)
+ write_xr(0x81, 0x12); // 8 bit color mode
+ write_xr(0x82, 0x08); // Graphics gamma enable
+ write_xr(0x20, 0x00); // 8 bit blitter mode
+
+ info->fix.line_length = 800;
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+ info->var.red.offset = info->var.green.offset =
+ info->var.blue.offset = 0;
+ info->var.red.length = info->var.green.length =
+ info->var.blue.length = 8;
+
}
return 0;
}
-static int chipsfbcon_switch(int con, struct fb_info *info)
-{
- struct fb_info_chips *p = (struct fb_info_chips *) info;
- int new_bpp, old_bpp;
-
- /* Do we have to save the colormap? */
- if (fb_display[info->currcon].cmap.len)
- fb_get_cmap(&fb_display[info->currcon].cmap, 1, chipsfb_getcolreg, info);
-
- new_bpp = fb_display[con].var.bits_per_pixel;
- old_bpp = fb_display[info->currcon].var.bits_per_pixel;
- info->currcon = con;
-
- if (new_bpp != old_bpp)
- chips_set_bitdepth(p, &fb_display[con], con, new_bpp);
-
- do_install_cmap(con, info);
- return 0;
-}
-
-static int chipsfb_updatevar(int con, struct fb_info *info)
-{
- return 0;
-}
-
static int chipsfb_blank(int blank, struct fb_info *info)
{
- struct fb_info_chips *p = (struct fb_info_chips *) info;
- int i;
-
+#ifdef CONFIG_PMAC_BACKLIGHT
// used to disable backlight only for blank > 1, but it seems
// useful at blank = 1 too (saves battery, extends backlight life)
- if (blank) {
-#ifdef CONFIG_PMAC_BACKLIGHT
- set_backlight_enable(0);
-#endif /* CONFIG_PMAC_BACKLIGHT */
- /* get the palette from the chip */
- for (i = 0; i < 256; ++i) {
- outb(i, 0x3c7);
- udelay(1);
- p->palette[i].red = inb(0x3c9);
- p->palette[i].green = inb(0x3c9);
- p->palette[i].blue = inb(0x3c9);
- }
- for (i = 0; i < 256; ++i) {
- outb(i, 0x3c8);
- udelay(1);
- outb(0, 0x3c9);
- outb(0, 0x3c9);
- outb(0, 0x3c9);
- }
- } else {
-#ifdef CONFIG_PMAC_BACKLIGHT
- set_backlight_enable(1);
+ set_backlight_enable(!blank);
#endif /* CONFIG_PMAC_BACKLIGHT */
- for (i = 0; i < 256; ++i) {
- outb(i, 0x3c8);
- udelay(1);
- outb(p->palette[i].red, 0x3c9);
- outb(p->palette[i].green, 0x3c9);
- outb(p->palette[i].blue, 0x3c9);
- }
- }
- return 0;
-}
-
-static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,
- u_int *blue, u_int *transp, struct fb_info *info)
-{
- struct fb_info_chips *p = (struct fb_info_chips *) info;
- if (regno > 255)
- return 1;
- *red = (p->palette[regno].red<<8) | p->palette[regno].red;
- *green = (p->palette[regno].green<<8) | p->palette[regno].green;
- *blue = (p->palette[regno].blue<<8) | p->palette[regno].blue;
- *transp = 0;
- return 0;
+ return 1; /* get fb_blank to set the colormap to all black */
}
static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info)
{
- struct fb_info_chips *p = (struct fb_info_chips *) info;
-
if (regno > 255)
return 1;
red >>= 8;
green >>= 8;
blue >>= 8;
- p->palette[regno].red = red;
- p->palette[regno].green = green;
- p->palette[regno].blue = blue;
outb(regno, 0x3c8);
udelay(1);
outb(red, 0x3c9);
outb(green, 0x3c9);
outb(blue, 0x3c9);
-#ifdef FBCON_HAS_CFB16
- if (regno < 16)
- p->fbcon_cfb16_cmap[regno] = ((red & 0xf8) << 7)
- | ((green & 0xf8) << 2) | ((blue & 0xf8) >> 3);
-#endif
-
return 0;
}
-static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp)
-{
- int err;
- struct fb_fix_screeninfo* fix = &p->fix;
- struct fb_var_screeninfo* var = &p->var;
-
- if (bpp == 16) {
- if (con == p->info.currcon) {
- write_cr(0x13, 200); // Set line length (doublewords)
- write_xr(0x81, 0x14); // 15 bit (555) color mode
- write_xr(0x82, 0x00); // Disable palettes
- write_xr(0x20, 0x10); // 16 bit blitter mode
- }
-
- fix->line_length = 800*2;
- fix->visual = FB_VISUAL_TRUECOLOR;
-
- var->red.offset = 10;
- var->green.offset = 5;
- var->blue.offset = 0;
- var->red.length = var->green.length = var->blue.length = 5;
-
-#ifdef FBCON_HAS_CFB16
- disp->dispsw = &fbcon_cfb16;
- disp->dispsw_data = p->fbcon_cfb16_cmap;
-#else
- disp->dispsw = &fbcon_dummy;
-#endif
- } else if (bpp == 8) {
- if (con == p->info.currcon) {
- write_cr(0x13, 100); // Set line length (doublewords)
- write_xr(0x81, 0x12); // 8 bit color mode
- write_xr(0x82, 0x08); // Graphics gamma enable
- write_xr(0x20, 0x00); // 8 bit blitter mode
- }
-
- fix->line_length = 800;
- fix->visual = FB_VISUAL_PSEUDOCOLOR;
-
- var->red.offset = var->green.offset = var->blue.offset = 0;
- var->red.length = var->green.length = var->blue.length = 8;
-
-#ifdef FBCON_HAS_CFB8
- disp->dispsw = &fbcon_cfb8;
-#else
- disp->dispsw = &fbcon_dummy;
-#endif
- }
-
- var->bits_per_pixel = bpp;
- disp->line_length = p->fix.line_length;
- disp->visual = fix->visual;
- disp->var = *var;
-
- if (p->info.changevar)
- (*p->info.changevar)(con);
-
- if ((err = fb_alloc_cmap(&disp->cmap, 0, 0)))
- return;
- do_install_cmap(con, (struct fb_info *)p);
-}
-
struct chips_init_reg {
unsigned char addr;
unsigned char data;
@@ -473,7 +298,7 @@
{ 0xa8, 0x00 }
};
-static void __init chips_hw_init(struct fb_info_chips *p)
+static void __init chips_hw_init(void)
{
int i;
@@ -492,12 +317,12 @@
write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
}
-static void __init init_chips(struct fb_info_chips *p)
-{
- int i;
-
- strcpy(p->fix.id, "C&T 65550");
- p->fix.smem_start = p->frame_buffer_phys;
+static struct fb_fix_screeninfo chipsfb_fix __initdata = {
+ .id = "C&T 65550",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
+ .accel = FB_ACCEL_NONE,
+ .line_length = 800,
// FIXME: Assumes 1MB frame buffer, but 65550 supports 1MB or 2MB.
// * "3500" PowerBook G3 (the original PB G3) has 2MB.
@@ -506,115 +331,75 @@
// for a second pair of DRAMs. (Thanks, Apple!)
// * 3400 has 1MB (I think). Don't know if it's expandable.
// -- Tim Seufert
- p->fix.smem_len = 0x100000; // 1MB
- p->fix.type = FB_TYPE_PACKED_PIXELS;
- p->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- p->fix.line_length = 800;
-
- p->var.xres = 800;
- p->var.yres = 600;
- p->var.xres_virtual = 800;
- p->var.yres_virtual = 600;
- p->var.bits_per_pixel = 8;
- p->var.red.length = p->var.green.length = p->var.blue.length = 8;
- p->var.height = p->var.width = -1;
- p->var.vmode = FB_VMODE_NONINTERLACED;
- p->var.pixclock = 10000;
- p->var.left_margin = p->var.right_margin = 16;
- p->var.upper_margin = p->var.lower_margin = 16;
- p->var.hsync_len = p->var.vsync_len = 8;
-
- p->disp.var = p->var;
- p->disp.cmap.red = NULL;
- p->disp.cmap.green = NULL;
- p->disp.cmap.blue = NULL;
- p->disp.cmap.transp = NULL;
- p->disp.visual = p->fix.visual;
- p->disp.type = p->fix.type;
- p->disp.type_aux = p->fix.type_aux;
- p->disp.line_length = p->fix.line_length;
- p->disp.can_soft_blank = 1;
- p->disp.dispsw = &fbcon_cfb8;
- p->disp.scrollmode = SCROLL_YREDRAW;
-
- strcpy(p->info.modename, p->fix.id);
- p->info.node = NODEV;
- p->info.fbops = &chipsfb_ops;
- p->info.screen_base = p->frame_buffer;
- p->info.disp = &p->disp;
- p->info.currcon = -1;
- p->info.fontname[0] = 0;
- p->info.changevar = NULL;
- p->info.switch_con = &chipsfbcon_switch;
- p->info.updatevar = &chipsfb_updatevar;
- p->info.flags = FBINFO_FLAG_DEFAULT;
-
- for (i = 0; i < 16; ++i) {
- int j = color_table[i];
- p->palette[i].red = default_red[j];
- p->palette[i].green = default_grn[j];
- p->palette[i].blue = default_blu[j];
- }
+ .smem_len = 0x100000, /* 1MB */
+};
- if (register_framebuffer(&p->info) < 0) {
- kfree(p);
- return;
- }
+static struct fb_var_screeninfo chipsfb_var __initdata = {
+ .xres = 800,
+ .yres = 600,
+ .xres_virtual = 800,
+ .yres_virtual = 600,
+ .bits_per_pixel = 8,
+ .red = { .length = 8 },
+ .green = { .length = 8 },
+ .blue = { .length = 8 },
+ .height = -1,
+ .width = -1,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .pixclock = 10000,
+ .left_margin = 16,
+ .right_margin = 16,
+ .upper_margin = 16,
+ .lower_margin = 16,
+ .hsync_len = 8,
+ .vsync_len = 8,
+};
+
+static void __init init_chips(struct fb_info *p, unsigned long addr)
+{
+ p->fix = chipsfb_fix;
+ p->fix.smem_start = addr;
- printk("fb%d: Chips 65550 frame buffer (%dK RAM detected)\n",
- minor(p->info.node), p->fix.smem_len / 1024);
+ p->var = chipsfb_var;
- chips_hw_init(p);
+ p->node = NODEV;
+ p->fbops = &chipsfb_ops;
+ p->flags = FBINFO_FLAG_DEFAULT;
-#ifdef CONFIG_PMAC_PBOOK
- if (all_chips == NULL)
- pmu_register_sleep_notifier(&chips_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
- p->next = all_chips;
- all_chips = p;
-}
+ fb_alloc_cmap(&p->cmap, 256, 0);
-int __init chips_init(void)
-{
- struct pci_dev *dp = NULL;
+ if (register_framebuffer(p) < 0) {
+ printk(KERN_ERR "C&T 65550 framebuffer failed to register\n");
+ return;
+ }
- while ((dp = pci_find_device(PCI_VENDOR_ID_CT,
- PCI_DEVICE_ID_CT_65550, dp)) != NULL)
- if ((dp->class >> 16) == PCI_BASE_CLASS_DISPLAY)
- chips_pci_init(dp);
- return all_chips? 0: -ENODEV;
+ printk(KERN_INFO "fb%d: Chips 65550 frame buffer (%dK RAM detected)\n",
+ minor(p->node), p->fix.smem_len / 1024);
+
+ chips_hw_init();
}
-static void __init chips_pci_init(struct pci_dev *dp)
+static int __devinit
+chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
{
- struct fb_info_chips *p;
+ struct fb_info *p = &chipsfb_info;
unsigned long addr, size;
unsigned short cmd;
if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
- return;
- addr = dp->resource[0].start;
- size = dp->resource[0].end + 1 - addr;
+ return -ENODEV;
+ addr = pci_resource_start(dp, 0);
+ size = pci_resource_len(dp, 0);
if (addr == 0)
- return;
- p = kmalloc(sizeof(*p), GFP_ATOMIC);
- if (p == 0)
- return;
- memset(p, 0, sizeof(*p));
- if (!request_mem_region(addr, size, "chipsfb")) {
- kfree(p);
- return;
- }
+ return -ENODEV;
+ if (p->screen_base != 0)
+ return -EBUSY;
+ if (!request_mem_region(addr, size, "chipsfb"))
+ return -EBUSY;
+
#ifdef __BIG_ENDIAN
addr += 0x800000; // Use big-endian aperture
#endif
- p->pdev = dp;
- p->frame_buffer_phys = addr;
- p->frame_buffer = __ioremap(addr, 0x200000, _PAGE_NO_CACHE);
- p->blitter_regs_phys = addr + 0x400000;
- p->blitter_regs = ioremap(addr + 0x400000, 0x1000);
- p->blitter_data_phys = addr + 0x410000;
- p->blitter_data = ioremap(addr + 0x410000, 0x10000);
/* we should use pci_enable_device here, but,
the device doesn't declare its I/O ports in its BARs
@@ -623,15 +408,68 @@
cmd |= 3; /* enable memory and IO space */
pci_write_config_word(dp, PCI_COMMAND, cmd);
- /* Clear the entire framebuffer */
- memset(p->frame_buffer, 0, 0x100000);
-
#ifdef CONFIG_PMAC_BACKLIGHT
/* turn on the backlight */
set_backlight_enable(1);
#endif /* CONFIG_PMAC_BACKLIGHT */
- init_chips(p);
+ p->screen_base = __ioremap(addr, 0x200000, _PAGE_NO_CACHE);
+ if (p->screen_base == NULL) {
+ release_mem_region(addr, size);
+ return -ENOMEM;
+ }
+
+ init_chips(p, addr);
+
+#ifdef CONFIG_PMAC_PBOOK
+ pmu_register_sleep_notifier(&chips_sleep_notifier);
+#endif /* CONFIG_PMAC_PBOOK */
+
+ /* Clear the entire framebuffer */
+ memset(p->screen_base, 0, 0x100000);
+
+ pci_set_drvdata(dp, p);
+ return 0;
+}
+
+static void __devexit chipsfb_remove(struct pci_dev *dp)
+{
+ struct fb_info *p = pci_get_drvdata(dp);
+
+ if (p != &chipsfb_info || p->screen_base == NULL)
+ return;
+ unregister_framebuffer(p);
+ iounmap(p->screen_base);
+ p->screen_base = NULL;
+ release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
+
+#ifdef CONFIG_PMAC_PBOOK
+ pmu_unregister_sleep_notifier(&chips_sleep_notifier);
+#endif /* CONFIG_PMAC_PBOOK */
+}
+
+static struct pci_device_id chipsfb_pci_tbl[] __devinitdata = {
+ { PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_65550, PCI_ANY_ID, PCI_ANY_ID },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, chipsfb_pci_tbl);
+
+static struct pci_driver chipsfb_driver = {
+ .name = "chipsfb",
+ .id_table = chipsfb_pci_tbl,
+ .probe = chipsfb_pci_init,
+ .remove = __devexit_p(chipsfb_remove),
+};
+
+int __init chips_init(void)
+{
+ return pci_module_init(&chipsfb_driver);
+}
+
+static void __exit chipsfb_exit(void)
+{
+ pci_unregister_driver(&chipsfb_driver);
}
#ifdef CONFIG_PMAC_PBOOK
@@ -642,40 +480,37 @@
int
chips_sleep_notify(struct pmu_sleep_notifier *self, int when)
{
- struct fb_info_chips *p;
+ struct fb_info *p = &chipsfb_info;
+ int nb = p->var.yres * p->fix.line_length;
- for (p = all_chips; p != NULL; p = p->next) {
- int nb = p->var.yres * p->fix.line_length;
+ if (p->screen_base == NULL)
+ return PBOOK_SLEEP_OK;
- switch (when) {
- case PBOOK_SLEEP_REQUEST:
- p->save_framebuffer = vmalloc(nb);
- if (p->save_framebuffer == NULL)
- return PBOOK_SLEEP_REFUSE;
- break;
- case PBOOK_SLEEP_REJECT:
- if (p->save_framebuffer) {
- vfree(p->save_framebuffer);
- p->save_framebuffer = 0;
- }
- break;
-
- case PBOOK_SLEEP_NOW:
- chipsfb_blank(1, (struct fb_info *)p);
- if (p->save_framebuffer)
- memcpy(p->save_framebuffer,
- p->frame_buffer, nb);
- break;
- case PBOOK_WAKE:
- if (p->save_framebuffer) {
- memcpy(p->frame_buffer,
- p->save_framebuffer, nb);
- vfree(p->save_framebuffer);
- p->save_framebuffer = 0;
- }
- chipsfb_blank(0, (struct fb_info *)p);
- break;
+ switch (when) {
+ case PBOOK_SLEEP_REQUEST:
+ save_framebuffer = vmalloc(nb);
+ if (save_framebuffer == NULL)
+ return PBOOK_SLEEP_REFUSE;
+ break;
+ case PBOOK_SLEEP_REJECT:
+ if (save_framebuffer) {
+ vfree(save_framebuffer);
+ save_framebuffer = 0;
+ }
+ break;
+ case PBOOK_SLEEP_NOW:
+ chipsfb_blank(1, p);
+ if (save_framebuffer)
+ memcpy(save_framebuffer, p->screen_base, nb);
+ break;
+ case PBOOK_WAKE:
+ if (save_framebuffer) {
+ memcpy(p->screen_base, save_framebuffer, nb);
+ vfree(save_framebuffer);
+ save_framebuffer = 0;
}
+ chipsfb_blank(0, p);
+ break;
}
return PBOOK_SLEEP_OK;
}
^ permalink raw reply
* Re: Intel P6 vs P7 system call performance
From: Linus Torvalds @ 2002-12-18 22:57 UTC (permalink / raw)
To: Jamie Lokier
Cc: H. Peter Anvin, Terje Eggestad, Ulrich Drepper, Matti Aarnio,
Hugh Dickins, Dave Jones, Ingo Molnar, linux-kernel
In-Reply-To: <Pine.LNX.4.44.0212181432470.1516-100000@penguin.transmeta.com>
Btw, I'm pushing what looks like the "final" version of sysenter/sysexit
for now. There may be bugs left, but all the known issues are resolved:
- single-stepping over the system call now works. It doesn't actually see
all of the user-mode instructions, since the fast system call interface
does not lend itself well to restoring "TF" in eflags on return, but
the trampoline code saves and restores the flags, so you will be able
to step over the important bits.
(ptrace also doesn't actually allow you to look at the instruction
contents in high memory, so gdb won't see the instructions in the
user-mode fast system call trampoline even when it can single-step
them, and I don't think I'll bother to fix it up).
- NMI at the "wrong" time (just before first instruction in kernel
space) should now be a non-issue. The per-CPU SEP stack looks like a
real (nonpreemptable) process, and follows all the conventions needed
for "current_thread_info()" and friends. This behaviour is also
triggered by the single-step debug trap, so while I've obviously not
tested NMI behaviour, I _have_ tested the very same concept at that
exact point.
- The APM problem was confirmed by Andrew to apparently be just a GDT
that was too small for the new layout.
This is in addition to the six-argument issues and the glibc address query
issues that were resolved yesterday.
Linus
^ permalink raw reply
* Re: [LARTC] PRIO type qdisc
From: Paul C. Diem @ 2002-12-18 22:48 UTC (permalink / raw)
To: lartc
In-Reply-To: <marc-lartc-104010520627418@msgid-missing>
On Wed, 18 Dec 2002, Stef Coene wrote:
> On Tuesday 17 December 2002 07:05, Paul C. Diem wrote:
> > I'm looking for a PRIO type qdisc which will prioritize packets (either
> > based on DS or filters). Unlike PRIO, I need all the classes to flow into
> > a single qdisc (HTB). For example:
> >
> > PRIO
> >
> > +--------+--------+
> >
> > Band0 Band1 Band2
> >
> > +--------+--------+
> >
> > HTB
> >
> > Does such a qdisc exist or is there a way to get all the PRIO classes to
> > flow into a single qdisc?
> There is no such qdisc. And I don't think there is such way.
>
> But why do you want to do this?
Here's what I'm really trying to accomplish: I have several links of
various speeds. Some of the links feed from other links. For example,
+---> B +---> E
| |
A <---< 10Mbps >---+---> C <---< 6Mbps >---+---> F <---< 6Mbps >---> H
|
+---> D <---< 3Mbps >---> G
ie. I have a 10Mbps link from A which feeds B, C and D, a 6Mbps link from
C which feeds E and F, a 6Mbps link from F which feeds H and a 3Mbps link
from D which feeds G. I need to provide multiple levels of service (based
on maximum bandwidth and packet priority) at each node. What I'd like to
do it use htb to cap the bandwidth and some sort of prio qdisc to
prioritize packets. The problem with prio is that I'd need to define the
entire remaining "link tree" for each band at each level. It seems I need
a qdisc which will prioritize packets based on some mark (ie. DS) but only
had one class (instead of as many classes at there are bands like prio).
It looks like gred may do something like this but I can't find any
detailed information on gred. If I'm going about this all wrong, please
let me know.
Paul C. Diem
PCDiem@FoxValley.net
_______________________________________________
LARTC mailing list / LARTC@mailman.ds9a.nl
http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/
^ permalink raw reply
* Re: gettimeofday() moving backwards
From: Dominik Brodowski @ 2002-12-18 22:40 UTC (permalink / raw)
To: Grover, Andrew
Cc: 'Paul Richards',
acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <EDC461A30AC4D511ADE10002A5072CAD04C7A5BB-OU+JdkIUtvd9zuciVAfUoVDQ4js95KgL@public.gmane.org>
On Wed, Dec 18, 2002 at 01:23:57PM -0800, Grover, Andrew wrote:
> > From: Paul Richards [mailto:p.a.richards-Y3tGgqFSo3OFxr2TtlUqVg@public.gmane.org]
> > I am using linux kernel v2.4.20 with ACPI patch dated 2002-12-05.
> >
> > I have noticed that if my processor changes state (800Mhz up
> > to 1200Mhz say)
> > then gettimeofday() behaves weirdly. It runs smoothly but
> > every now and again
> > (on the order of 10 times a second) it makes a correction.
> > If I have gone from
> > 800Mhz to 1200Mhz then the correction is backwards, otherwise
> > it makes a forward
> > jump..
>
> Hmm, can you mention this on the cpufreq mailing list?
> cpufreq-1walMZg8u8rXmaaqVzeoHQ@public.gmane.org .
In kernel 2.5.5x, gettimeofday() should work fine: ACPI uses the cpufreq
infrastructure, which adds -among other things- a hunk in
arch/i386/timer/tsc.c which updates some values on frequency transitions.
(see http://www.brodo.de/cpufreq/ for details on cpufreq).
As cpufreq isn't included in 2.4. kernels, and likely never will, the 2.4.
gettimeofday() call does cause strange results in 2.4.
Dominik
-------------------------------------------------------
This SF.NET email is sponsored by: Order your Holiday Geek Presents Now!
Green Lasers, Hip Geek T-Shirts, Remote Control Tanks, Caffeinated Soap,
MP3 Players, XBox Games, Flying Saucers, WebCams, Smart Putty.
T H I N K G E E K . C O M http://www.thinkgeek.com/sf/
^ permalink raw reply
* RE: Help in cross-compiler--gcc3.2-7.1 error
From: Chien-Lung Wu @ 2002-12-18 22:21 UTC (permalink / raw)
To: 'Brad Barrett', linux-mips; +Cc: Chien-Lung Wu
Hi, Brad:
Thanks for your information.
I download:
binutils v2.13.90.0.10 (H.J. Lu)
GCC v3.2-7.1 (H.J. Lu)
glibc v2.2.5
glibc-linuxthreads v2.2.5
and follow your build note to build a big-endian mips cross-compiler.
As I build the binutil-2.13.90.10, it is o.k.
However, as I build the gcc (1st), I get the error message:
make[1]: Leaving directory `/home/lineo/xcompiler/mips-gcc-3.2.7/libiberty'
make[1]: Entering directory `/home/lineo/xcompiler/mips-gcc-3.2.7/gcc'
gcc -DIN_GCC -DCROSS_COMPILE -g -O2 -W -Wall -Wwrite-strings
-Wstrict-prototypes -Wmissing-prototypes -Wtraditional -pedantic
-Wno-long-long
-DHAVE_CONFIG_H -DGENERATOR_FILE -o gengenrtl \
gengenrtl.o ../libiberty/libiberty.a
../libiberty/libiberty.a: could not read symbols: Archive has no index; run
ranlib to add one
collect2: ld returned 1 exit status
make[1]: *** [gengenrtl] Error 1
make[1]: Leaving directory `/home/lineo/xcompiler/mips-gcc-3.2.7/gcc'
make: *** [all-gcc] Error 2
Do I miss something?
Since I download the gcc3.2-7.1.src.rpm (only srpm format), I use
rpm --rebuild gcc3.2-7.1.src.rpm
then I got gcc-3.2-20020903.tar.bz2 and many patch files.
I umcompress the gcc-3.2-20020903.tar.bz2 using the command
tar -xvIf gcc-3.2-20020903.tar.bz2
==>I get the gcc-3.2-20020903.
Questions:
Do I need to patch all the patch files? If so, how can I patch all
of them?
or is the tarball pached?
Regarding to the error message, is it caused by missing some patch files?
How can I fix this problem?
Thanks.
Chien-Lung
-----Original Message-----
From: Brad Barrett [mailto:brad@patton.com]
Sent: Wednesday, December 18, 2002 12:34 PM
To: Chien-Lung Wu; linux-mips@linux-mips.org
Subject: RE: Help in cross-compiler
On Wednesday 18 December 2002 10:57 am, you wrote:
> I am working on the embedded linux system on bug endian mips (mips-linux).
> As I understand, I need to get the cross-compiler work on my linux-i686
> host (redhat 7.2).
> Following the Bradly's "Building a modern MIPS cross-toolchain for linux",
> I download following packages:
>
> binutils-2.11
> gcc-2.95
> glibc-2.2.5
> glibc-linuxthreads-2.2.5
>
> And following the procedue:
...
> However, I got the error_message:
...
>
/usr/toolchain1-mips/lib/gcc-lib/mips-linux/2.95/../../../../mips-linux/sys
>- include/bits/mathinline.h:426:
> unknown register name `st(1)' in `asm'
...
> Does any have any idea to fix this error?
It sounds like you used the standard binutils. You should probably use H.J.
Lu's binutils (they have some MIPS patches applied), and also his gcc (same
story). They're available at:
http://ftp.kernel.org/pub/linux/devel/binutils/
ftp://ftp.linux-mips.org/pub/linux/mips/redhat/7.3/test/
> When I build the C cross-compiler, I use the "dubious hack"
> --with-headers=/usr/include copy the "MIPS host header files". Are there
> any other ways to copy the MIPS-host headers?
I never understood why anyone would use this method. If you're building a
mips-linux cross-compiler, you should have a copy of the Linux kernel source
from linux-mips.org lying around somewhere (or are you using a pre-compiled
kernel image?). Just copy the include directory from this source to a
convenient location, symbolically link asm to asm-mips and point the gcc
configure to it.
I've included below my personal build notes from a mipsel (little-endian)
cross-toolchain I built a couple months ago. Hopefully these will be
helpful.
Note that I chose /opt/toolchains/mips for the installed path, rather than
/usr/local. My build system was SuSE 7.2 (gcc version 2.95.3 20010315
(SuSE)
and binutils version 2.10.91).
Also, you don't mention applying the glibc-2.2.5-mips-build-gmon.diff patch
that
Brad LaRonde recommends. If you didn't apply this patch, you might also
want to
do that.
Brad
----------------Build Notes------------------------------------
I relied primarily on Steven J. Hill's build script [SJH], but with several
adjustments.
H.J. Lu says only his binutils will work:
http://ftp.kernel.org/pub/linux/devel/binutils/
I got the latest version.
H.J. Lu also says to use his gcc 3.2. This is available only in source rpm
format, at:
ftp://ftp.linux-mips.org/pub/linux/mips/redhat/7.3/test/
Glibc came from the standard location:
ftp://ftp.gnu.org/gnu/glibc/
*Except*...patched with "glibc-2.2.5-mips-build-gmon.diff" from [BDL2.4].
This source also recommends the "-finline-limit=10000" CFLAG value (claims
ld.so won't work without it, and this seems to be true).
Tool versions:
Binutils v2.13.90.0.10 (H.J. Lu)
GCC v3.2 (H.J. Lu)
Glibc v2.2.5
Glibc-linuxthreads v2.2.5
Patch:
glibc-2.2.5-mips-build-gmon.diff
(http://www.ltc.com/~brad/mips/glibc-2.2.5-mips-build-gmon.diff)
-------------------------
Build Log
-------------------------
[Implied "su" to root prior to each "make install" below.]
1. Downloaded tarballs/rpms and unpacked to:
~/mipsel-cross/binutils-2.13
~/mipsel-cross/gcc-3.2
~/mipsel-cross/glibc-2.2.5
(linuxthreads is unpacked into the glibc-2.2.5 directory)
2. Binutils:
cd ~/mipsel-cross/binutils-2.13/mips
chmod 744 README
cd ..
./mips/README (apply HJ Lu's patches)
mkdir ~/mipsel-cross/mipsel-binutils
cd ~/mipsel-cross/mipsel-binutils
../binutils-2.13/configure --prefix=/opt/toolchains/mips \
--enable-targets=mips64el-linux,mipsel-linux --target=mipsel-linux \
--enable-shared
make
make install
3. Gcc (1st time)
cp -R ~/linux-2.4/include/asm-mips
/opt/toolchains/mips/mipsel-linux/include
cp -R ~/linux-2.4/include/linux
/opt/toolchains/mips/mipsel-linux/include
cd /opt/toolchains/mips/mipsel-linux/include
ln -s asm-mips asm
mkdir ~/mipsel-cross/mipsel-gcc
cd ~/mipsel-cross/mipsel-gcc
AR=mipsel-linux-ar RANLIB=mipsel-linux-ranlib ../gcc-3.2/configure \
--prefix=/opt/toolchains/mips --with-newlib --enable-languages=c \
--target=mipsel-linux --disable-shared --disable-threads
make
make install
4. Glibc
cd ~/mipsel-cross/glibc-2.2.5
patch -p1 -i ../glibc-2.2.5-mips-build-gmon.diff
(patch asked for name of each file to patch...had to type them in)
mkdir ~/mipsel-cross/mipsel-glibc
cd ~/mipsel-cross/mipsel-glibc
CFLAGS="-O2 -g -finline-limit=10000" LD_LIBRARY_PATH= \
BUILD_CC=gcc CC=mipsel-linux-gcc AR=mipsel-linux-ar AS=mipsel-linux-as
\
RANLIB=mipsel-linux-ranlib ../glibc-2.2.5/configure \
--prefix=/opt/toolchains/mips/mipsel-linux --host=mipsel-linux \
--build=i686-pc-linux-gnu --enable-add-ons --with-elf \
--disable-profile \
--with-headers=/opt/toolchains/mips/mipsel-linux/include \
--mandir=/opt/toolchains/mips/man --infodir=/opt/toolchains/mips/info
\
--enable-kernel=2.4.0
make
make install
5. Gcc (2nd time - with full glibc support)
mkdir ~/mipsel-cross/mipsel-gccfull
cd ~/mipsel-cross/mipsel-gccfull
AR=mipsel-linux-ar RANLIB=mipsel-linux-ranlib ../gcc-3.2/configure \
--prefix=/opt/toolchains/mips --enable-languages=c,c++ \
--target=mipsel-linux --enable-shared --enable-threads \
--includedir=/opt/toolchains/mips/mipsel-linux/include \
--with-gxx-include-dir=/opt/toolchains/mips/mipsel-linux/include \
--mandir=/opt/toolchains/mips/man --infodir=/opt/toolchains/mips/info
\
--disable-checking
make
make install
Sources:
--------
[BDL2.4] LaRonde, Bradley D., "Building a Modern MIPS Cross-Toolchain for
Linux", v2.4, 2002-09-25,
http://www.ltc.com/~brad/mips/mips-cross-toolchain.html
[SJH]
ftp://ftp.cotw.com/Linux/MIPS/toolchain/stable/sources/mipsel-linux-toolchai
n-bu
ild.sh
----------------End Build Notes--------------------------------
--
Brad Barrett
Staff Engineer, Patton Electronics
brad@patton.com
^ permalink raw reply
* Re: [PATCH]:
From: Ralf Baechle @ 2002-12-18 22:35 UTC (permalink / raw)
To: Juan Quintela; +Cc: linux mips mailing list
In-Reply-To: <m2ptrzngy8.fsf@demo.mitica>
On Wed, Dec 18, 2002 at 10:41:03PM +0100, Juan Quintela wrote:
> ralf> On Wed, Dec 18, 2002 at 02:42:25AM +0100, Juan Quintela wrote:
> >> PD. Someone can explain me what mean:
> >> __attribute__ ((__mode__ (__SI__)));
> >>
> >> The SI part don't appear in the gcc info pages :(
>
> ralf> Single Integer, a 32-bit integer.
>
> Changing the code to u32 & friends will be acepted?
Yes.
Ralf
^ permalink raw reply
* RE: [ANNOUNCE] Intel PRO/100 software developer manual released
From: Feldman, Scott @ 2002-12-18 22:41 UTC (permalink / raw)
To: 'James Morris'; +Cc: linux-kernel, netdev, LOSTeam
> Any chance of releasing documentation on
> the crypto hardware which resides on the PRO/100 S?
No plans, sorry.
-scott
^ permalink raw reply
* Re: Horrible drive performance under concurrent i/o jobs (dlh problem?)
From: Torben Frey @ 2002-12-18 22:40 UTC (permalink / raw)
To: Con Kolivas; +Cc: linux kernel mailing list
In-Reply-To: <3E00F3B4.7050209@mailsammler.de>
Ok, found the complete aa1-patch, so I am compiling this right now (hope
the machine at work comes up again, otherwise I am stuck until tomorrow
morning...
I will let you know about the results, for sure!
Torben
^ permalink raw reply
* Re: Intel P6 vs P7 system call performance
From: Linus Torvalds @ 2002-12-18 22:37 UTC (permalink / raw)
To: Jamie Lokier
Cc: H. Peter Anvin, Terje Eggestad, Ulrich Drepper, Matti Aarnio,
Hugh Dickins, Dave Jones, Ingo Molnar, linux-kernel
In-Reply-To: <20021218222835.GA14801@bjl1.asuk.net>
On Wed, 18 Dec 2002, Jamie Lokier wrote:
>
> That said, you always need the page at 0xfffe0000 mapped anyway, so
> that sysexit can jump to a fixed address (which is fastest).
Yes. This is important. There _needs_ to be some fixed address at least as
far as the kernel is concerned (it might move around between reboots or
something like that, but it needs to be something the kernel knows about
intimately and doesn't need lots of dynamic lookup).
However, there's another issue, namely process startup cost. I personally
want it to be as light as at all possible. I hate doing an "strace" on
user processes and seeing tons and tons of crapola showing up. Just for
fun, do a
strace /bin/sh -c "echo hello"
to see what I'm talking about. And that's actually a _lot_ better these
days than it used to be.
Anyway, I really hate to see "unnecessary crap" in the user mode startup
just because kernel interfaces are bad. That's why I like the AT_SYSINFO
ELF auxilliary table approach - it's something that is already _there_ for
the process to just take advantage of. Having to do a magic mmap for
somehting that everybody needs to do is just bad design.
Linus
^ permalink raw reply
* Re: Intel P6 vs P7 system call performance
From: H. Peter Anvin @ 2002-12-18 22:39 UTC (permalink / raw)
To: Jamie Lokier
Cc: Terje Eggestad, Linus Torvalds, Ulrich Drepper, Matti Aarnio,
Hugh Dickins, Dave Jones, Ingo Molnar, linux-kernel
In-Reply-To: <20021218222835.GA14801@bjl1.asuk.net>
Jamie Lokier wrote:
> H. Peter Anvin wrote:
>
>>Terje Eggestad wrote:
>>
>>>fd = open("/dev/vsyscall", );
>>>_vsyscall = mmap(NULL, getpagesize(), PROT_READ|PROT_EXEC, MAP_SHARED,
>>>fd, 0);
>>
>>Very ugly -- then the application has to do indirect calls.
>
>
> No it doesn't.
>
> The application, or library, would map the vsyscall page to an address
> in its own data section. This means that position-independent code
> can do vsyscalls without any relocations, and hence without dirtying
> its own caller pages.
>
Oh, I see... you don't really mean NULL in the first argument :)
This has one additional advantage: an application which wants to
override vsyscalls can simply map something instead of the kernel page,
and UML can present its own vsyscall page.
> In some ways this is better than the 0xfffe0000 address: _that_
> requires position-independent code to do indirect calls to the
> absolute address, or to dirty its caller pages.
>
> That said, you always need the page at 0xfffe0000 mapped anyway, so
> that sysexit can jump to a fixed address (which is fastest).
That's a possiblity, or if the task_struct contains the desired return
address for a particular process that might also work -- it's just a GPR
after all.
-hpa
^ permalink raw reply
* Re: Horrible drive performance under concurrent i/o jobs (dlh problem?)
From: Andrew Morton @ 2002-12-18 22:37 UTC (permalink / raw)
To: Torben Frey; +Cc: Con Kolivas, linux kernel mailing list
In-Reply-To: <3E00F3B4.7050209@mailsammler.de>
Torben Frey wrote:
>
> Hi Con,
>
> thanks for your fast reply. Unfortunately - I cannot patch a vanilla
> 2.4.20 kernel using patch -p1. The first hunk fails, the other ones are
> found with offsets or even fuzz. Although I applied the first hunk
> manually, compiling fails.
>
> Do I need the other patches, too? Or a special version of the kernel?
>
Here's a diff against base 2.4.20. It may be a little out of date
wrt Andrea's latest but it should tell us if we're looking in the
right place.
I doubt it though. This problem will be exceedingly rare on kernels
which do not have a voluntary scheduling point in submit_bh(). SMP and
preemptible kernels will hit it, but rarely.
So please try this patch. Also it would be interesting to know if
read activity against the device fixes the problem. Try doing a
cat /dev/sda1 > /dev/null
and see if that unjams things. If so then yes, it's a queue unplugging
problem.
drivers/block/ll_rw_blk.c | 25 ++++++++++++++++++++-----
fs/buffer.c | 22 +++++++++++++++++++++-
fs/reiserfs/inode.c | 1 +
include/linux/pagemap.h | 2 ++
kernel/ksyms.c | 1 +
mm/filemap.c | 14 ++++++++++++++
6 files changed, 59 insertions(+), 6 deletions(-)
--- 24/drivers/block/ll_rw_blk.c~fix-pausing Wed Dec 18 14:32:06 2002
+++ 24-akpm/drivers/block/ll_rw_blk.c Wed Dec 18 14:32:06 2002
@@ -590,12 +590,20 @@ static struct request *__get_request_wai
register struct request *rq;
DECLARE_WAITQUEUE(wait, current);
- generic_unplug_device(q);
add_wait_queue_exclusive(&q->wait_for_requests[rw], &wait);
do {
set_current_state(TASK_UNINTERRUPTIBLE);
- if (q->rq[rw].count == 0)
+ if (q->rq[rw].count == 0) {
+ /*
+ * All we care about is not to stall if any request
+ * is been released after we set TASK_UNINTERRUPTIBLE.
+ * This is the most efficient place to unplug the queue
+ * in case we hit the race and we can get the request
+ * without waiting.
+ */
+ generic_unplug_device(q);
schedule();
+ }
spin_lock_irq(&io_request_lock);
rq = get_request(q, rw);
spin_unlock_irq(&io_request_lock);
@@ -829,9 +837,11 @@ void blkdev_release_request(struct reque
*/
if (q) {
list_add(&req->queue, &q->rq[rw].free);
- if (++q->rq[rw].count >= q->batch_requests &&
- waitqueue_active(&q->wait_for_requests[rw]))
- wake_up(&q->wait_for_requests[rw]);
+ if (++q->rq[rw].count >= q->batch_requests) {
+ smp_mb();
+ if (waitqueue_active(&q->wait_for_requests[rw]))
+ wake_up(&q->wait_for_requests[rw]);
+ }
}
}
@@ -1200,6 +1210,11 @@ void submit_bh(int rw, struct buffer_hea
generic_make_request(rw, bh);
+ /* fix race condition with wait_on_buffer() */
+ smp_mb(); /* spin_unlock may have inclusive semantics */
+ if (waitqueue_active(&bh->b_wait))
+ wake_up(&bh->b_wait);
+
switch (rw) {
case WRITE:
kstat.pgpgout += count;
--- 24/fs/buffer.c~fix-pausing Wed Dec 18 14:32:06 2002
+++ 24-akpm/fs/buffer.c Wed Dec 18 14:32:06 2002
@@ -153,10 +153,23 @@ void __wait_on_buffer(struct buffer_head
get_bh(bh);
add_wait_queue(&bh->b_wait, &wait);
do {
- run_task_queue(&tq_disk);
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
if (!buffer_locked(bh))
break;
+ /*
+ * We must read tq_disk in TQ_ACTIVE after the
+ * add_wait_queue effect is visible to other cpus.
+ * We could unplug some line above it wouldn't matter
+ * but we can't do that right after add_wait_queue
+ * without an smp_mb() in between because spin_unlock
+ * has inclusive semantics.
+ * Doing it here is the most efficient place so we
+ * don't do a suprious unplug if we get a racy
+ * wakeup that make buffer_locked to return 0, and
+ * doing it here avoids an explicit smp_mb() we
+ * rely on the implicit one in set_task_state.
+ */
+ run_task_queue(&tq_disk);
schedule();
} while (buffer_locked(bh));
tsk->state = TASK_RUNNING;
@@ -1512,6 +1525,9 @@ static int __block_write_full_page(struc
/* Done - end_buffer_io_async will unlock */
SetPageUptodate(page);
+
+ wakeup_page_waiters(page);
+
return 0;
out:
@@ -1543,6 +1559,7 @@ out:
} while (bh != head);
if (need_unlock)
UnlockPage(page);
+ wakeup_page_waiters(page);
return err;
}
@@ -1770,6 +1787,8 @@ int block_read_full_page(struct page *pa
else
submit_bh(READ, bh);
}
+
+ wakeup_page_waiters(page);
return 0;
}
@@ -2383,6 +2402,7 @@ int brw_page(int rw, struct page *page,
submit_bh(rw, bh);
bh = next;
} while (bh != head);
+ wakeup_page_waiters(page);
return 0;
}
--- 24/fs/reiserfs/inode.c~fix-pausing Wed Dec 18 14:32:06 2002
+++ 24-akpm/fs/reiserfs/inode.c Wed Dec 18 14:32:06 2002
@@ -1993,6 +1993,7 @@ static int reiserfs_write_full_page(stru
*/
if (nr) {
submit_bh_for_writepage(arr, nr) ;
+ wakeup_page_waiters(page);
} else {
UnlockPage(page) ;
}
--- 24/include/linux/pagemap.h~fix-pausing Wed Dec 18 14:32:06 2002
+++ 24-akpm/include/linux/pagemap.h Wed Dec 18 14:32:06 2002
@@ -97,6 +97,8 @@ static inline void wait_on_page(struct p
___wait_on_page(page);
}
+extern void wakeup_page_waiters(struct page * page);
+
/*
* Returns locked page at given index in given cache, creating it if needed.
*/
--- 24/kernel/ksyms.c~fix-pausing Wed Dec 18 14:32:06 2002
+++ 24-akpm/kernel/ksyms.c Wed Dec 18 14:32:06 2002
@@ -293,6 +293,7 @@ EXPORT_SYMBOL(filemap_fdatasync);
EXPORT_SYMBOL(filemap_fdatawait);
EXPORT_SYMBOL(lock_page);
EXPORT_SYMBOL(unlock_page);
+EXPORT_SYMBOL(wakeup_page_waiters);
/* device registration */
EXPORT_SYMBOL(register_chrdev);
--- 24/mm/filemap.c~fix-pausing Wed Dec 18 14:32:06 2002
+++ 24-akpm/mm/filemap.c Wed Dec 18 14:32:06 2002
@@ -909,6 +909,20 @@ void lock_page(struct page *page)
}
/*
+ * This must be called after every submit_bh with end_io
+ * callbacks that would result into the blkdev layer waking
+ * up the page after a queue unplug.
+ */
+void wakeup_page_waiters(struct page * page)
+{
+ wait_queue_head_t * head;
+
+ head = page_waitqueue(page);
+ if (waitqueue_active(head))
+ wake_up(head);
+}
+
+/*
* a rather lightweight function, finding and getting a reference to a
* hashed page atomically.
*/
_
^ permalink raw reply
* [PATCH][2.4] generic cluster APIC support for systems with more than 8 CPUs
From: Pallipadi, Venkatesh @ 2002-12-18 22:36 UTC (permalink / raw)
To: Linux Kernel
Cc: Martin Bligh, John Stultz, Nakajima, Jun, jamesclv,
Mallick, Asit K, Saxena, Sunil
[-- Attachment #1: Type: text/plain, Size: 4237 bytes --]
2.4.21-pre1 (i386) based patch to fix the issues with systems having more than
8 CPUs, in a generic way.
Motivation:
The current APIC destination mode ("Flat Logical") used in linux kernel has
an upper limit of 8 CPUs. For more than 8 CPUs, either "Clustered Logical" or
"Physical" mode has to be used.
There is already some code in current kernel (2.4.21-pre1), to support such
conditions. Specifically, IBM Summit, uses Physical mode, and IBM NUMAQ
uses clustered mode. But, there are some issues too:
- it is not generic enough to support any other more than 8 CPU system
out of the box. Supporting different systems may need more hacks in the code.
- clustered mode setup is tightly coupled with NUMA system. Whereas, in reality,
we can as well have logical clusters in a non-NUMA system as well.
- physical mode setup is somewhat tightly coupled with xAPIC. But, xAPIC doesn't
necessarily imply physical mode. You can as well have clustered mode with xAPIC
- APIC destination mode is selected based on particular OEM string.
These reasons together led to panics on other OEM systems with > 8 CPUS. The
patch tries to fix this issue in a generic way (in place of having multiple
hacks for different OEMs). Note, the patch only intends to change the
initialization of systems with more than 8 CPUs and it will not affect
other systems (apart from possible bugs in my code itself).
Description:
The basic idea is to use the number of processors detected on the system, to
decide on which APIC destination mode is to be used. Once all the CPU info, is
collected either from ACPI or MP table, we can check the total number of
processors in the system.
If the number of processors in less than equal to 8,
then no change is required, and we can use the default, "Flat Logical" set up.
If the number of processors is more than 8
we can switch to clustered logical setup.
The logical clusters set up as follows.
Cluster 0 (CPU 0-3), Cluster 1 (CPU 4-7), Cluster 2 (CPU 8-11) and so on..
The other things that are done in the patch include:
- Separate out the NUMA specific stuff from APIC setup in cluster mode. Also,
NUMA has its own way of setting up the clusters, and doesn't follow the
logical cluster mapping defined above.
- Separate out xAPIC stuff from APIC destination setup. And the availability of
xAPIC support can actually be determined from the LAPIC version.
- physical mode support _removed_, as we can use clustered logical setup to
support can support upto a max of 60 CPUs. This is mainly because of the
advantage of being able to setup IOAPICs in LowestPrio, when using clustered mode.
The whole stuff is protected by 'Clustered APIC (> 8 CPUs) support
(CONFIG_X86_APIC_CLUSTER)' config option under Processor Type and Features.
But going forward, we can actually make this as default, as this doesn't
affect the systems with less than equal to 8 CPUs (Apart from minor increase
in code size and couple of additional checks during boot up), but gives the
default support to more than 8 CPU systems.
Please let me know your comments/criticisms about this.
I was able to test this successfully on an 8-way with HT(16 logical)
CPU systems that I have access to. But, I haven't tested it on x440, or NUMAQ
systems. Would love to hear about the effect of this patch on these systems.
Thanks,
-Venkatesh
> -----Original Message-----
> From: Nakajima, Jun
> Sent: Thursday, December 12, 2002 7:06 PM
> To: jamesclv@us.ibm.com; Zwane Mwaikambo
> Cc: Martin Bligh; John Stultz; Linux Kernel
> Subject: RE: [PATCH][2.5][RFC] Using xAPIC apic address space
> on !Summit
>
>
> BTW, we are working on a xAPIC patch that supports more than
> 8 CPUs in a
> generic fashion (don't use hardcode OEM checking). We already
> tested it on
> two OEM systems with 16 CPUs.
> - It uses clustered mode. We don't want to use physical mode
> because it does
> not support lowest priority delivery mode.
> - We also check the version of the local APIC if it's xAPIC
> or not. It's
> possible that some other x86 architecture (other than P4P) uses xAPIC.
>
> Stay tuned.
>
> Jun
[-- Attachment #2: cluster-2.4.21-pre1.patch --]
[-- Type: application/octet-stream, Size: 25995 bytes --]
diff -urN linux-2.4.21-pre1.org/Documentation/Configure.help linux-test1/Documentation/Configure.help
--- linux-2.4.21-pre1.org/Documentation/Configure.help 2002-12-13 17:53:58.000000000 -0800
+++ linux-test1/Documentation/Configure.help 2002-12-14 15:00:39.000000000 -0800
@@ -246,6 +246,13 @@
If unsure, say N.
+Clustered APIC support for x86 systems
+CONFIG_X86_APIC_CLUSTER
+ This option is used for getting Linux to run on more than 8 CPU system.
+ This dynamically changes the way that processors are bootstrapped,
+ and uses Clustered Logical APIC addressing mode instead of Flat Logical, for
+ more than 8 CPU system. It doesn't effect the systems with less than 8 CPUs.
+
Multiquad support for NUMAQ systems
CONFIG_X86_NUMAQ
This option is used for getting Linux to run on a (IBM/Sequent) NUMA
diff -urN linux-2.4.21-pre1.org/arch/i386/config.in linux-test1/arch/i386/config.in
--- linux-2.4.21-pre1.org/arch/i386/config.in 2002-12-13 17:53:58.000000000 -0800
+++ linux-test1/arch/i386/config.in 2002-12-14 14:59:22.000000000 -0800
@@ -216,17 +216,13 @@
define_bool CONFIG_X86_IO_APIC y
fi
else
- bool 'Multi-node NUMA system support' CONFIG_X86_NUMA
- if [ "$CONFIG_X86_NUMA" = "y" ]; then
+ bool 'Clustered APIC (> 8 CPUs) support' CONFIG_X86_APIC_CLUSTER
+ if [ "$CONFIG_X86_APIC_CLUSTER" = "y" ]; then
+ define_bool CONFIG_X86_CLUSTERED_APIC y
#Platform Choices
bool ' Multiquad (IBM/Sequent) NUMAQ support' CONFIG_X86_NUMAQ
if [ "$CONFIG_X86_NUMAQ" = "y" ]; then
- define_bool CONFIG_X86_CLUSTERED_APIC y
- define_bool CONFIG_MULTIQUAD y
- fi
- bool ' IBM x440 (Summit/EXA) support' CONFIG_X86_SUMMIT
- if [ "$CONFIG_X86_SUMMIT" = "y" ]; then
- define_bool CONFIG_X86_CLUSTERED_APIC y
+ define_bool CONFIG_MULTIQUAD y
fi
fi
fi
diff -urN linux-2.4.21-pre1.org/arch/i386/defconfig linux-test1/arch/i386/defconfig
--- linux-2.4.21-pre1.org/arch/i386/defconfig 2002-11-28 15:53:09.000000000 -0800
+++ linux-test1/arch/i386/defconfig 2002-12-14 14:59:52.000000000 -0800
@@ -62,6 +62,7 @@
# CONFIG_MATH_EMULATION is not set
# CONFIG_MTRR is not set
CONFIG_SMP=y
+CONFIG_X86_APIC_CLUSTER=y
# CONFIG_MULTIQUAD is not set
CONFIG_HAVE_DEC_LOCK=y
diff -urN linux-2.4.21-pre1.org/arch/i386/kernel/acpitable.c linux-test1/arch/i386/kernel/acpitable.c
--- linux-2.4.21-pre1.org/arch/i386/kernel/acpitable.c 2002-08-02 17:39:42.000000000 -0700
+++ linux-test1/arch/i386/kernel/acpitable.c 2002-12-13 23:25:09.000000000 -0800
@@ -314,12 +314,15 @@
int have_acpi_tables;
extern void __init MP_processor_info(struct mpc_config_processor *);
+extern unsigned int xapic_support;
static void __init
acpi_parse_lapic(struct acpi_table_lapic *local_apic)
{
struct mpc_config_processor proc_entry;
int ix = 0;
+ static unsigned long apic_ver;
+ static int first_time = 1;
if (!local_apic)
return;
@@ -357,7 +360,16 @@
proc_entry.mpc_featureflag = boot_cpu_data.x86_capability[0];
proc_entry.mpc_reserved[0] = 0;
proc_entry.mpc_reserved[1] = 0;
- proc_entry.mpc_apicver = 0x10; /* integrated APIC */
+ if (first_time) {
+ first_time = 0;
+ set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE);
+ Dprintk("Local APIC ID %lx\n", apic_read(APIC_ID));
+ apic_ver = apic_read(APIC_LVR);
+ Dprintk("Local APIC Version %lx\n", apic_ver);
+ if (APIC_XAPIC_SUPPORT(apic_ver))
+ xapic_support = 1;
+ }
+ proc_entry.mpc_apicver = apic_ver;
MP_processor_info(&proc_entry);
} else {
printk(" disabled");
diff -urN linux-2.4.21-pre1.org/arch/i386/kernel/apic.c linux-test1/arch/i386/kernel/apic.c
--- linux-2.4.21-pre1.org/arch/i386/kernel/apic.c 2002-12-13 17:53:58.000000000 -0800
+++ linux-test1/arch/i386/kernel/apic.c 2002-12-13 23:25:09.000000000 -0800
@@ -264,8 +264,8 @@
static unsigned long calculate_ldr(unsigned long old)
{
unsigned long id;
- if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
- id = physical_to_logical_apicid(hard_smp_processor_id());
+ if(clustered_apic_mode)
+ id = cpu_2_logical_apicid[smp_processor_id()];
else
id = 1UL << smp_processor_id();
return (old & ~APIC_LDR_MASK)|SET_APIC_LOGICAL_ID(id);
@@ -302,22 +302,26 @@
* an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
* document number 292116). So here it goes...
*/
- if (clustered_apic_mode != CLUSTERED_APIC_NUMAQ) {
+ if (configured_platform_type != CONFIGURED_PLATFORM_NUMA) {
+ unsigned int dfr;
/*
* For NUMA-Q (clustered apic logical), the firmware does this
* for us. Otherwise put the APIC into clustered or flat
* delivery mode. Must be "all ones" explicitly for 82489DX.
*/
- if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
- apic_write_around(APIC_DFR, APIC_DFR_CLUSTER);
+ if(clustered_apic_mode)
+ dfr = APIC_DFR_CLUSTER;
else
- apic_write_around(APIC_DFR, APIC_DFR_FLAT);
+ dfr = APIC_DFR_FLAT;
+ apic_write_around(APIC_DFR, dfr);
/*
* Set up the logical destination ID.
*/
value = apic_read(APIC_LDR);
apic_write_around(APIC_LDR, calculate_ldr(value));
+ Dprintk("setup_local_APIC: CPU#%d LDR 0x%lx\n", smp_processor_id(), calculate_ldr(value));
+ Dprintk("setup_local_APIC: CPU#%d DFR 0x%lx\n", smp_processor_id(), dfr);
}
/*
diff -urN linux-2.4.21-pre1.org/arch/i386/kernel/io_apic.c linux-test1/arch/i386/kernel/io_apic.c
--- linux-2.4.21-pre1.org/arch/i386/kernel/io_apic.c 2002-12-13 17:53:58.000000000 -0800
+++ linux-test1/arch/i386/kernel/io_apic.c 2002-12-13 23:25:09.000000000 -0800
@@ -40,8 +40,9 @@
static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
-unsigned int int_dest_addr_mode = APIC_DEST_LOGICAL;
-unsigned char int_delivery_mode = dest_LowestPrio;
+extern unsigned int int_dest_addr_mode; /* Default = APIC_DEST_LOGICAL */
+extern unsigned char int_delivery_mode; /* Default = dest_LowestPrio */
+extern unsigned int xapic_support;
/*
@@ -658,7 +659,8 @@
* skip adding the timer int on secondary nodes, which causes
* a small but painful rift in the time-space continuum
*/
- if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
+ if (clustered_apic_mode &&
+ (configured_platform_type == CONFIGURED_PLATFORM_NUMA)
&& (apic != 0) && (irq == 0))
continue;
else
@@ -1067,7 +1069,8 @@
old_id = mp_ioapics[apic].mpc_apicid;
- if (mp_ioapics[apic].mpc_apicid >= apic_broadcast_id) {
+ if ( !xapic_support &&
+ (mp_ioapics[apic].mpc_apicid >= apic_broadcast_id)) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
apic, mp_ioapics[apic].mpc_apicid);
printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
@@ -1081,22 +1084,23 @@
* 'stuck on smp_invalidate_needed IPI wait' messages.
* I/O APIC IDs no longer have any meaning for xAPICs and SAPICs.
*/
- if ((clustered_apic_mode != CLUSTERED_APIC_XAPIC) &&
- (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid))) {
- printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
- apic, mp_ioapics[apic].mpc_apicid);
- for (i = 0; i < 0xf; i++)
- if (!(phys_id_present_map & (1 << i)))
- break;
- if (i >= apic_broadcast_id)
- panic("Max APIC ID exceeded!\n");
- printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
- i);
- phys_id_present_map |= 1 << i;
- mp_ioapics[apic].mpc_apicid = i;
- } else {
- printk("Setting %d in the phys_id_present_map\n", mp_ioapics[apic].mpc_apicid);
- phys_id_present_map |= 1 << mp_ioapics[apic].mpc_apicid;
+ if ( !xapic_support ) {
+ if (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid)) {
+ printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
+ apic, mp_ioapics[apic].mpc_apicid);
+ for (i = 0; i < 0xf; i++)
+ if (!(phys_id_present_map & (1 << i)))
+ break;
+ if (i >= 0xf)
+ panic("Max APIC ID exceeded!\n");
+ printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
+ i);
+ phys_id_present_map |= 1 << i;
+ mp_ioapics[apic].mpc_apicid = i;
+ } else {
+ printk("Setting %d in the phys_id_present_map\n", mp_ioapics[apic].mpc_apicid);
+ phys_id_present_map |= 1 << mp_ioapics[apic].mpc_apicid;
+ }
}
diff -urN linux-2.4.21-pre1.org/arch/i386/kernel/mpparse.c linux-test1/arch/i386/kernel/mpparse.c
--- linux-2.4.21-pre1.org/arch/i386/kernel/mpparse.c 2002-12-13 17:53:58.000000000 -0800
+++ linux-test1/arch/i386/kernel/mpparse.c 2002-12-13 23:25:09.000000000 -0800
@@ -10,6 +10,8 @@
* Alan Cox : Added EBDA scanning
* Ingo Molnar : various cleanups and rewrites
* Maciej W. Rozycki : Bits for default MP configurations
+ * Venkatesh Pallipadi : Added generic support for Clustered
+ * int. dest. modes
*/
#include <linux/mm.h>
@@ -67,11 +69,17 @@
unsigned long phys_cpu_present_map;
unsigned long logical_cpu_present_map;
+/* Default values are for Logical Flat destination set up */
#ifdef CONFIG_X86_CLUSTERED_APIC
unsigned char esr_disable = 0;
-unsigned char clustered_apic_mode = CLUSTERED_APIC_NONE;
+unsigned char clustered_apic_mode = CONFIGURED_APIC_NONE;
+unsigned char configured_platform_type = CONFIGURED_PLATFORM_NONE;
unsigned int apic_broadcast_id = APIC_BROADCAST_ID_APIC;
#endif
+unsigned int xapic_support=0;
+unsigned int int_dest_addr_mode = APIC_DEST_LOGICAL;
+unsigned char int_delivery_mode = dest_LowestPrio;
+
unsigned char raw_phys_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
/*
@@ -156,14 +164,15 @@
return;
logical_apicid = m->mpc_apicid;
- if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
+ if (clustered_apic_mode &&
+ (configured_platform_type == CONFIGURED_PLATFORM_NUMA) ) {
quad = translation_table[mpc_record]->trans_quad;
logical_apicid = (quad << 4) +
(m->mpc_apicid ? m->mpc_apicid << 1 : 1);
printk("Processor #%d %s APIC version %d (quad %d, apic %d)\n",
m->mpc_apicid,
mpc_family((m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
- (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
+ (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
m->mpc_apicver, quad, logical_apicid);
} else {
printk("Processor #%d %s APIC version %d\n",
@@ -236,6 +245,8 @@
return;
}
ver = m->mpc_apicver;
+ if (APIC_XAPIC_SUPPORT(ver))
+ xapic_support = 1;
logical_cpu_present_map |= 1 << (num_processors-1);
phys_cpu_present_map |= apicid_to_phys_cpu_present(m->mpc_apicid);
@@ -259,7 +270,8 @@
memcpy(str, m->mpc_bustype, 6);
str[6] = 0;
- if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
+ if (clustered_apic_mode &&
+ (configured_platform_type == CONFIGURED_PLATFORM_NUMA) ) {
quad = translation_table[mpc_record]->trans_quad;
mp_bus_id_to_node[m->mpc_busid] = quad;
mp_bus_id_to_local[m->mpc_busid] = translation_table[mpc_record]->trans_local;
@@ -446,7 +458,9 @@
if (!have_acpi_tables)
mp_lapic_addr = mpc->mpc_lapic;
- if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) && mpc->mpc_oemptr) {
+ if (clustered_apic_mode &&
+ (configured_platform_type == CONFIGURED_PLATFORM_NUMA) &&
+ mpc->mpc_oemptr) {
/* We need to process the oem mpc tables to tell us which quad things are in ... */
mpc_record = 0;
smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr, mpc->mpc_oemsize);
@@ -516,20 +530,11 @@
++mpc_record;
}
- if (clustered_apic_mode){
+ if (clustered_apic_mode &&
+ (configured_platform_type==CONFIGURED_PLATFORM_NUMA)){
phys_cpu_present_map = logical_cpu_present_map;
}
-
- printk("Enabling APIC mode: ");
- if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
- printk("Clustered Logical. ");
- else if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
- printk("Physical. ");
- else
- printk("Flat. ");
- printk("Using %d I/O APICs\n",nr_ioapics);
-
if (!num_processors)
printk(KERN_ERR "SMP mptable: no processors registered!\n");
return num_processors;
@@ -712,7 +717,7 @@
*/
config_acpi_tables();
#endif
-
+
printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
if (mpf->mpf_feature2 & (1<<7)) {
printk(" IMCR and PIC compatibility mode.\n");
@@ -764,6 +769,29 @@
BUG();
printk("Processors: %d\n", num_processors);
+
+#ifdef CONFIG_X86_CLUSTERED_APIC
+ /* Default is Logical Flat destination mode */
+ apic_broadcast_id = xapic_support?APIC_BROADCAST_ID_XAPIC:APIC_BROADCAST_ID_APIC;
+ if ((clustered_apic_mode == CONFIGURED_APIC_NONE) &&
+ (num_processors > FLAT_APIC_CPU_MAX)) {
+ /*Clustered Logical destination mode*/
+ configured_platform_type = CONFIGURED_PLATFORM_NONE;
+ clustered_apic_mode = CONFIGURED_APIC_CLUSTERED;
+ int_dest_addr_mode = APIC_DEST_LOGICAL;
+ int_delivery_mode = dest_LowestPrio;
+ esr_disable = 1;
+ }
+#endif //CONFIG_X86_CLUSTERED_APIC
+
+ printk("Enabling APIC mode: ");
+ if(clustered_apic_mode == CONFIGURED_APIC_CLUSTERED)
+ printk("Clustered Logical. ");
+ else
+ printk("Flat Logical. ");
+ printk("Using %d I/O APICs\n",nr_ioapics);
+ printk("xAPIC support %s\n", (xapic_support?"Enabled":"Disabled"));
+
/*
* Only use the first configuration found.
*/
diff -urN linux-2.4.21-pre1.org/arch/i386/kernel/pci-pc.c linux-test1/arch/i386/kernel/pci-pc.c
--- linux-2.4.21-pre1.org/arch/i386/kernel/pci-pc.c 2002-11-28 15:53:09.000000000 -0800
+++ linux-test1/arch/i386/kernel/pci-pc.c 2002-12-13 23:25:09.000000000 -0800
@@ -478,7 +478,7 @@
#ifdef CONFIG_MULTIQUAD
/* Multi-Quad has an extended PCI Conf1 */
- if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
+ if(configured_platform_type == CONFIGURED_PLATFORM_NUMA)
return &pci_direct_mq_conf1;
#endif
return &pci_direct_conf1;
@@ -1407,7 +1407,7 @@
printk(KERN_INFO "PCI: Probing PCI hardware\n");
pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
- if (clustered_apic_mode && (numnodes > 1)) {
+ if ( (configured_platform_type==CONFIGURED_PLATFORM_NUMA) && (numnodes > 1)) {
for (quad = 1; quad < numnodes; ++quad) {
printk("Scanning PCI bus %d for quad %d\n",
QUADLOCAL2BUS(quad,0), quad);
diff -urN linux-2.4.21-pre1.org/arch/i386/kernel/smp.c linux-test1/arch/i386/kernel/smp.c
--- linux-2.4.21-pre1.org/arch/i386/kernel/smp.c 2002-12-13 17:53:58.000000000 -0800
+++ linux-test1/arch/i386/kernel/smp.c 2002-12-13 23:25:09.000000000 -0800
@@ -214,10 +214,7 @@
/*
* prepare target chip field
*/
- if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
- cfg = __prepare_ICR2(cpu_to_physical_apicid(query_cpu));
- else
- cfg = __prepare_ICR2(cpu_to_logical_apicid(query_cpu));
+ cfg = __prepare_ICR2(cpu_to_logical_apicid(query_cpu));
apic_write_around(APIC_ICR2, cfg);
/*
diff -urN linux-2.4.21-pre1.org/arch/i386/kernel/smpboot.c linux-test1/arch/i386/kernel/smpboot.c
--- linux-2.4.21-pre1.org/arch/i386/kernel/smpboot.c 2002-12-13 17:53:58.000000000 -0800
+++ linux-test1/arch/i386/kernel/smpboot.c 2002-12-13 23:25:09.000000000 -0800
@@ -30,6 +30,8 @@
* Tigran Aivazian : fixed "0.00 in /proc/uptime on SMP" bug.
* Maciej W. Rozycki : Bits for genuine 82489DX APICs
* Martin J. Bligh : Added support for multi-quad systems
+ * Venkatesh Pallipadi : Added generic support for Clustered
+ * int. dest. modes
*/
#include <linux/config.h>
@@ -358,7 +360,7 @@
* our local APIC. We have to wait for the IPI or we'll
* lock up on an APIC access.
*/
- if (!clustered_apic_mode)
+ if (configured_platform_type != CONFIGURED_PLATFORM_NUMA)
while (!atomic_read(&init_deasserted));
/*
@@ -412,7 +414,7 @@
* Because we use NMIs rather than the INIT-STARTUP sequence to
* bootstrap the CPUs, the APIC may be in a wierd state. Kick it.
*/
- if (clustered_apic_mode)
+ if (configured_platform_type == CONFIGURED_PLATFORM_NUMA)
clear_local_APIC();
setup_local_APIC();
@@ -540,9 +542,10 @@
* else physical apic ids
*/
{
- if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
- logical_apicid_2_cpu[apicid] = cpu;
+ Dprintk("cpu %d, apicid %d, clustered %d\n", cpu, apicid, clustered_apic_mode);
+ if (clustered_apic_mode) {
cpu_2_logical_apicid[cpu] = apicid;
+ logical_apicid_2_cpu[apicid] = cpu;
} else {
physical_apicid_2_cpu[apicid] = cpu;
cpu_2_physical_apicid[cpu] = apicid;
@@ -555,7 +558,7 @@
* else physical apic ids
*/
{
- if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
+ if (clustered_apic_mode) {
logical_apicid_2_cpu[apicid] = BAD_APICID;
cpu_2_logical_apicid[cpu] = BAD_APICID;
} else {
@@ -702,6 +705,7 @@
* Determine this based on the APIC version.
* If we don't have an integrated APIC, don't send the STARTUP IPIs.
*/
+ Dprintk("###phys_apicid: %d.\n", phys_apicid);
if (APIC_INTEGRATED(apic_version[phys_apicid]))
num_starts = 2;
else
@@ -778,7 +782,7 @@
static void __init do_boot_cpu (int apicid)
/*
* NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
- * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
+ * (ie NUMA ), this is a LOGICAL apic ID.
*/
{
struct task_struct *idle;
@@ -806,7 +810,17 @@
idle->processor = cpu;
idle->cpus_runnable = 1 << cpu; /* we schedule the first task manually */
- map_cpu_to_boot_apicid(cpu, apicid);
+ /*
+ * In Clustered mode interrupt delivery, without NUMA, we
+ * initialize all the CPUs in normal IPI fashion and use their
+ * logical_apicid while setting the local apics. Thats when clustering
+ * is enabled. So, setup their logical_apicid here.
+ */
+ if (clustered_apic_mode &&
+ (configured_platform_type != CONFIGURED_PLATFORM_NUMA))
+ map_cpu_to_boot_apicid(cpu, physical_to_logical_apicid(apicid));
+ else
+ map_cpu_to_boot_apicid(cpu, apicid);
idle->thread.eip = (unsigned long) start_secondary;
@@ -830,7 +844,7 @@
Dprintk("Setting warm reset code and vector.\n");
- if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
+ if (configured_platform_type == CONFIGURED_PLATFORM_NUMA) {
/* stash the current NMI vector, so we can put things back */
nmi_high = *((volatile unsigned short *) TRAMPOLINE_HIGH);
nmi_low = *((volatile unsigned short *) TRAMPOLINE_LOW);
@@ -847,7 +861,7 @@
/*
* Be paranoid about clearing APIC errors.
*/
- if (!clustered_apic_mode && APIC_INTEGRATED(apic_version[apicid])) {
+ if ((configured_platform_type!=CONFIGURED_PLATFORM_NUMA) && APIC_INTEGRATED(apic_version[apicid])) {
apic_read_around(APIC_SPIV);
apic_write(APIC_ESR, 0);
apic_read(APIC_ESR);
@@ -862,7 +876,7 @@
* Starting actual IPI sequence...
*/
- if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
+ if (configured_platform_type == CONFIGURED_PLATFORM_NUMA)
boot_error = wakeup_secondary_via_NMI(apicid);
else
boot_error = wakeup_secondary_via_INIT(apicid, start_eip);
@@ -917,7 +931,7 @@
/* mark "stuck" area as not stuck */
*((volatile unsigned long *)phys_to_virt(8192)) = 0;
- if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
+ if(configured_platform_type == CONFIGURED_PLATFORM_NUMA) {
printk("Restoring NMI vector\n");
*((volatile unsigned short *) TRAMPOLINE_HIGH) = nmi_high;
*((volatile unsigned short *) TRAMPOLINE_LOW) = nmi_low;
@@ -981,7 +995,7 @@
{
int apicid, cpu, bit;
- if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) && (numnodes > 1)) {
+ if ((configured_platform_type == CONFIGURED_PLATFORM_NUMA) && (numnodes > 1)) {
printk("Remapping cross-quad port I/O for %d quads\n",
numnodes);
printk("xquad_portio vaddr 0x%08lx, len %08lx\n",
@@ -1019,11 +1033,22 @@
* We have the boot CPU online for sure.
*/
set_bit(0, &cpu_online_map);
- if (clustered_apic_mode == CLUSTERED_APIC_XAPIC)
+ if (clustered_apic_mode)
boot_cpu_logical_apicid = physical_to_logical_apicid(boot_cpu_physical_apicid);
else
boot_cpu_logical_apicid = logical_smp_processor_id();
- map_cpu_to_boot_apicid(0, boot_cpu_apicid);
+
+ /*
+ * In Clustered mode interrupt delivery, without NUMA, we
+ * initialize all the CPUs in normal IPI fashion and use their
+ * logical_apicid while setting the local apics. Thats when clustering
+ * is enabled. So, setup their logical_apicid here.
+ */
+ if (clustered_apic_mode &&
+ (configured_platform_type != CONFIGURED_PLATFORM_NUMA))
+ map_cpu_to_boot_apicid(0, physical_to_logical_apicid(boot_cpu_apicid));
+ else
+ map_cpu_to_boot_apicid(0, boot_cpu_apicid);
global_irq_holder = 0;
current->processor = 0;
@@ -1111,6 +1136,7 @@
/*
* Don't even attempt to start the boot CPU!
*/
+ Dprintk("apicid %d, boot_cpu_apicid %d, bit %d\n", apicid, boot_cpu_apicid, bit);
if (apicid == boot_cpu_apicid)
continue;
@@ -1201,7 +1227,7 @@
}
}
}
-
+
#ifndef CONFIG_VISWS
/*
* Here we can be sure that there is an IO-APIC in the system. Let's
diff -urN linux-2.4.21-pre1.org/include/asm-i386/apicdef.h linux-test1/include/asm-i386/apicdef.h
--- linux-2.4.21-pre1.org/include/asm-i386/apicdef.h 2002-12-13 17:53:58.000000000 -0800
+++ linux-test1/include/asm-i386/apicdef.h 2002-12-13 23:26:22.000000000 -0800
@@ -18,6 +18,7 @@
#define GET_APIC_VERSION(x) ((x)&0xFF)
#define GET_APIC_MAXLVT(x) (((x)>>16)&0xFF)
#define APIC_INTEGRATED(x) ((x)&0xF0)
+#define APIC_XAPIC_SUPPORT(x) (x >= 0x14)
#define APIC_TASKPRI 0x80
#define APIC_TPRI_MASK 0xFF
#define APIC_ARBPRI 0x90
diff -urN linux-2.4.21-pre1.org/include/asm-i386/smpboot.h linux-test1/include/asm-i386/smpboot.h
--- linux-2.4.21-pre1.org/include/asm-i386/smpboot.h 2002-12-13 17:53:58.000000000 -0800
+++ linux-test1/include/asm-i386/smpboot.h 2002-12-13 23:26:40.000000000 -0800
@@ -3,14 +3,22 @@
/*emum for clustered_apic_mode values*/
enum{
- CLUSTERED_APIC_NONE = 0,
- CLUSTERED_APIC_XAPIC,
- CLUSTERED_APIC_NUMAQ
+ CONFIGURED_APIC_NONE = 0,
+ CONFIGURED_APIC_CLUSTERED
};
+/*emum for configured_platform_type values*/
+enum{
+ CONFIGURED_PLATFORM_NONE = 0,
+ CONFIGURED_PLATFORM_NUMA
+};
+
+#define FLAT_APIC_CPU_MAX 8
+
#ifdef CONFIG_X86_CLUSTERED_APIC
extern unsigned int apic_broadcast_id;
extern unsigned char clustered_apic_mode;
+extern unsigned char configured_platform_type;
extern unsigned char esr_disable;
extern unsigned char int_delivery_mode;
extern unsigned int int_dest_addr_mode;
@@ -20,14 +28,15 @@
* Can't recognize Summit xAPICs at present, so use the OEM ID.
*/
if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(prod, "VIGIL SMP", 9)){
- clustered_apic_mode = CLUSTERED_APIC_XAPIC;
- apic_broadcast_id = APIC_BROADCAST_ID_XAPIC;
- int_dest_addr_mode = APIC_DEST_PHYSICAL;
- int_delivery_mode = dest_Fixed;
+ clustered_apic_mode = CONFIGURED_APIC_CLUSTERED;
+ apic_broadcast_id = APIC_BROADCAST_ID_APIC;
+ int_dest_addr_mode = APIC_DEST_LOGICAL;
+ int_delivery_mode = dest_LowestPrio;
esr_disable = 1;
}
else if (!strncmp(oem, "IBM NUMA", 8)){
- clustered_apic_mode = CLUSTERED_APIC_NUMAQ;
+ configured_platform_type = CONFIGURED_PLATFORM_NUMA;
+ clustered_apic_mode = CONFIGURED_APIC_CLUSTERED;
apic_broadcast_id = APIC_BROADCAST_ID_APIC;
int_dest_addr_mode = APIC_DEST_LOGICAL;
int_delivery_mode = dest_LowestPrio;
@@ -38,7 +47,8 @@
#define INT_DELIVERY_MODE (int_delivery_mode)
#else /* CONFIG_X86_CLUSTERED_APIC */
#define apic_broadcast_id (APIC_BROADCAST_ID_APIC)
-#define clustered_apic_mode (CLUSTERED_APIC_NONE)
+#define configured_platform_type (CONFIGURED_PLATFORM_NONE)
+#define clustered_apic_mode (CONFIGURED_APIC_NONE)
#define esr_disable (0)
#define detect_clustered_apic(x,y)
#define INT_DEST_ADDR_MODE (APIC_DEST_LOGICAL) /* logical delivery */
@@ -46,10 +56,10 @@
#endif /* CONFIG_X86_CLUSTERED_APIC */
#define BAD_APICID 0xFFu
-#define TRAMPOLINE_LOW phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0x8:0x467)
-#define TRAMPOLINE_HIGH phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0xa:0x469)
+#define TRAMPOLINE_LOW phys_to_virt((configured_platform_type == CONFIGURED_PLATFORM_NUMA)?0x8:0x467)
+#define TRAMPOLINE_HIGH phys_to_virt((configured_platform_type == CONFIGURED_PLATFORM_NUMA)?0xa:0x469)
-#define boot_cpu_apicid ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?boot_cpu_logical_apicid:boot_cpu_physical_apicid)
+#define boot_cpu_apicid ((configured_platform_type == CONFIGURED_PLATFORM_NUMA)? boot_cpu_logical_apicid: boot_cpu_physical_apicid)
extern unsigned char raw_phys_apicid[NR_CPUS];
@@ -58,21 +68,30 @@
*/
static inline int cpu_present_to_apicid(int mps_cpu)
{
- if (clustered_apic_mode == CLUSTERED_APIC_XAPIC)
- return raw_phys_apicid[mps_cpu];
- if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
+ if (clustered_apic_mode &&
+ (configured_platform_type == CONFIGURED_PLATFORM_NUMA))
return (mps_cpu/4)*16 + (1<<(mps_cpu%4));
return mps_cpu;
}
static inline unsigned long apicid_to_phys_cpu_present(int apicid)
{
- if(clustered_apic_mode)
+ if (clustered_apic_mode &&
+ (configured_platform_type == CONFIGURED_PLATFORM_NUMA))
return 1UL << (((apicid >> 4) << 2) + (apicid & 0x3));
return 1UL << apicid;
}
-#define physical_to_logical_apicid(phys_apic) ( (1ul << (phys_apic & 0x3)) | (phys_apic & 0xF0u) )
+static inline unsigned long physical_to_logical_apicid(int apicid)
+{
+ if (clustered_apic_mode) {
+ if (configured_platform_type == CONFIGURED_PLATFORM_NUMA)
+ return ((1ul << (apicid & 0x3)) | (apicid & 0xF0u));
+ else
+ return ((1ul << (apicid & 0x3)) + ((apicid&(~0x3))<<2));
+ }
+ return apicid;
+}
/*
* Mappings between logical cpu number and logical / physical apicid
@@ -100,13 +119,12 @@
{
static int cpu;
switch(clustered_apic_mode){
- case CLUSTERED_APIC_NUMAQ:
+ case CONFIGURED_APIC_CLUSTERED:
/* Broadcast intrs to local quad only. */
- return APIC_BROADCAST_ID_APIC;
- case CLUSTERED_APIC_XAPIC:
- /*round robin the interrupts*/
- cpu = (cpu+1)%smp_num_cpus;
- return cpu_to_physical_apicid(cpu);
+#define APIC_BROADCAST_CLUSTER 0xf
+ if (configured_platform_type == CONFIGURED_PLATFORM_NUMA)
+ return APIC_BROADCAST_CLUSTER;
+ return (cpu_online_map&APIC_BROADCAST_CLUSTER);
default:
}
return cpu_online_map;
^ permalink raw reply
* [PATCH] (3/5) improved notifier callback mechanism - use lists
From: Stephen Hemminger @ 2002-12-18 22:35 UTC (permalink / raw)
To: Linus Torvalds, Alan Cox; +Cc: Kernel List
This patch converts the notifier interface from a single linked list to
using the standard kernel doubly-linked list interface. The parameters
to notifier_chain_register/unregister changed from being
pointer-to-pointer to notifier_block to pointer list_head.
There is no change in functionality of notifiers, it just makes changing
to RCU easier.
diff -Nru a/arch/i386/kernel/profile.c b/arch/i386/kernel/profile.c
--- a/arch/i386/kernel/profile.c Wed Dec 18 09:36:46 2002
+++ b/arch/i386/kernel/profile.c Wed Dec 18 09:36:46 2002
@@ -11,7 +11,7 @@
#include <linux/irq.h>
#include <asm/hw_irq.h>
-static struct notifier_block * profile_listeners;
+static LIST_HEAD(profile_listeners);
static rwlock_t profile_lock = RW_LOCK_UNLOCKED;
int register_profile_notifier(struct notifier_block * nb)
diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
--- a/arch/x86_64/kernel/traps.c Wed Dec 18 09:36:46 2002
+++ b/arch/x86_64/kernel/traps.c Wed Dec 18 09:36:46 2002
@@ -75,7 +75,7 @@
extern int exception_trace;
-struct notifier_block *die_chain;
+LIST_HEAD(die_chain);
static int kstack_depth_to_print = 10;
diff -Nru a/include/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h
--- a/include/asm-x86_64/kdebug.h Wed Dec 18 09:03:09 2002
+++ b/include/asm-x86_64/kdebug.h Wed Dec 18 09:03:09 2002
@@ -11,7 +11,7 @@
long err;
};
-extern struct notifier_block *die_chain;
+extern LIST_HEAD(die_chain);
/* Grossly misnamed. */
enum die_val {
diff -Nru a/include/linux/notifier.h b/include/linux/notifier.h
--- a/include/linux/notifier.h Wed Dec 18 09:03:09 2002
+++ b/include/linux/notifier.h Wed Dec 18 09:03:09 2002
@@ -9,21 +9,22 @@
#ifndef _LINUX_NOTIFIER_H
#define _LINUX_NOTIFIER_H
-#include <linux/errno.h>
-struct notifier_block
-{
- int (*notifier_call)(struct notifier_block *self, unsigned long, void
*);
- struct notifier_block *next;
+#include <linux/list.h>
+
+struct notifier_block {
+ int (*notifier_call)(struct notifier_block *, unsigned long, void *);
int priority;
+
+ struct list_head link;
};
#ifdef __KERNEL__
-extern int notifier_chain_register(struct notifier_block **list, struct
notifier_block *n);
-extern int notifier_chain_unregister(struct notifier_block **nl, struct
notifier_block *n);
-extern int notifier_call_chain(struct notifier_block **n, unsigned long
val, void *v);
+extern int notifier_chain_register(struct list_head *, struct
notifier_block *);
+extern int notifier_chain_unregister(struct list_head *, struct
notifier_block *);
+extern int notifier_call_chain(struct list_head *, unsigned long, void
*);
extern int register_panic_notifier(struct notifier_block *);
extern int unregister_panic_notifier(struct notifier_block *);
diff -Nru a/kernel/cpu.c b/kernel/cpu.c
--- a/kernel/cpu.c Wed Dec 18 09:03:09 2002
+++ b/kernel/cpu.c Wed Dec 18 09:03:09 2002
@@ -13,7 +13,7 @@
/* This protects CPUs going up and down... */
DECLARE_MUTEX(cpucontrol);
-static struct notifier_block *cpu_chain = NULL;
+static LIST_HEAD(cpu_chain);
/* Need to know about CPUs going up/down? */
int register_cpu_notifier(struct notifier_block *nb)
diff -Nru a/kernel/cpufreq.c b/kernel/cpufreq.c
--- a/kernel/cpufreq.c Wed Dec 18 09:03:09 2002
+++ b/kernel/cpufreq.c Wed Dec 18 09:03:09 2002
@@ -48,8 +48,8 @@
* and cpufreq_notifier_sem need to be hold, get cpufreq_driver_sem
* first.
*/
-static struct notifier_block *cpufreq_policy_notifier_list;
-static struct notifier_block *cpufreq_transition_notifier_list;
+static LIST_HEAD(cpufreq_policy_notifier_list);
+static LIST_HEAD(cpufreq_transition_notifier_list);
static DECLARE_MUTEX (cpufreq_notifier_sem);
diff -Nru a/kernel/panic.c b/kernel/panic.c
--- a/kernel/panic.c Wed Dec 18 09:03:09 2002
+++ b/kernel/panic.c Wed Dec 18 09:03:09 2002
@@ -14,6 +14,7 @@
#include <linux/reboot.h>
#include <linux/notifier.h>
#include <linux/init.h>
+#include <linux/errno.h>
#include <linux/sysrq.h>
#include <linux/interrupt.h>
@@ -21,7 +22,7 @@
int panic_timeout;
-static struct notifier_block *panic_notifier_list;
+static LIST_HEAD(panic_notifier_list);
int register_panic_notifier(struct notifier_block * nb)
{
diff -Nru a/kernel/profile.c b/kernel/profile.c
--- a/kernel/profile.c Wed Dec 18 09:03:09 2002
+++ b/kernel/profile.c Wed Dec 18 09:03:09 2002
@@ -48,9 +48,9 @@
#ifdef CONFIG_PROFILING
static DECLARE_RWSEM(profile_rwsem);
-static struct notifier_block * exit_task_notifier;
-static struct notifier_block * exit_mmap_notifier;
-static struct notifier_block * exec_unmap_notifier;
+static LIST_HEAD(exit_task_notifier);
+static LIST_HEAD(exit_mmap_notifier);
+static LIST_HEAD(exec_unmap_notifier);
void profile_exit_task(struct task_struct * task)
{
diff -Nru a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c Wed Dec 18 09:03:09 2002
+++ b/kernel/sys.c Wed Dec 18 09:03:09 2002
@@ -77,8 +77,8 @@
* and the like.
*/
-static struct notifier_block *reboot_notifier_list;
-rwlock_t notifier_lock = RW_LOCK_UNLOCKED;
+static LIST_HEAD(reboot_notifier_list);
+static rwlock_t notifier_lock = RW_LOCK_UNLOCKED;
/**
* notifier_chain_register - Add notifier to a notifier chain
@@ -90,17 +90,20 @@
* Currently always returns zero.
*/
-int notifier_chain_register(struct notifier_block **list, struct
notifier_block *n)
+int notifier_chain_register(struct list_head *list, struct
notifier_block *n)
{
+ struct list_head *p;
+
+ INIT_LIST_HEAD(&n->link);
write_lock(¬ifier_lock);
- while(*list)
- {
- if(n->priority > (*list)->priority)
+ list_for_each(p, list) {
+ struct notifier_block *e
+ = list_entry(p, struct notifier_block, link);
+ if (n->priority > e->priority)
break;
- list= &((*list)->next);
}
- n->next = *list;
- *list=n;
+
+ list_add(&n->link, p);
write_unlock(¬ifier_lock);
return 0;
}
@@ -115,18 +118,17 @@
* Returns zero on success, or %-ENOENT on failure.
*/
-int notifier_chain_unregister(struct notifier_block **nl, struct
notifier_block *n)
+int notifier_chain_unregister(struct list_head *list, struct
notifier_block *n)
{
+ struct list_head *cur;
+
write_lock(¬ifier_lock);
- while((*nl)!=NULL)
- {
- if((*nl)==n)
- {
- *nl=n->next;
+ list_for_each(cur, list) {
+ if (n == list_entry(cur, struct notifier_block, link)) {
+ list_del(cur);
write_unlock(¬ifier_lock);
return 0;
}
- nl=&((*nl)->next);
}
write_unlock(¬ifier_lock);
return -ENOENT;
@@ -148,20 +150,21 @@
* of the last notifier function called.
*/
-int notifier_call_chain(struct notifier_block **n, unsigned long val,
void *v)
+int notifier_call_chain(struct list_head *list, unsigned long val, void
*v)
{
- int ret=NOTIFY_DONE;
- struct notifier_block *nb = *n;
+ struct list_head *p;
+ int ret = NOTIFY_DONE;
- while(nb)
- {
- ret=nb->notifier_call(nb,val,v);
- if(ret&NOTIFY_STOP_MASK)
- {
- return ret;
- }
- nb=nb->next;
+ list_for_each(p, list) {
+ struct notifier_block *nb =
+ list_entry(p, struct notifier_block, link);
+
+ ret = nb->notifier_call(nb,val,v);
+ if (ret & NOTIFY_STOP_MASK)
+ goto end_loop;
}
+
+ end_loop:
return ret;
}
@@ -195,6 +198,8 @@
{
return notifier_chain_unregister(&reboot_notifier_list, nb);
}
+
+
asmlinkage long sys_ni_syscall(void)
{
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c Wed Dec 18 09:03:09 2002
+++ b/net/core/dev.c Wed Dec 18 09:03:09 2002
@@ -188,7 +188,7 @@
* Our notifier list
*/
-static struct notifier_block *netdev_chain;
+static LIST_HEAD(netdev_chain);
/*
* Device drivers call our routines to queue packets here. We empty the
diff -Nru a/net/ipv4/devinet.c b/net/ipv4/devinet.c
--- a/net/ipv4/devinet.c Wed Dec 18 09:03:09 2002
+++ b/net/ipv4/devinet.c Wed Dec 18 09:03:09 2002
@@ -78,7 +78,7 @@
static void rtmsg_ifa(int event, struct in_ifaddr *);
-static struct notifier_block *inetaddr_chain;
+static LIST_HEAD(inetaddr_chain);
static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr
**ifap,
int destroy);
#ifdef CONFIG_SYSCTL
diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
--- a/net/ipv6/addrconf.c Wed Dec 18 09:03:09 2002
+++ b/net/ipv6/addrconf.c Wed Dec 18 09:03:09 2002
@@ -106,7 +106,7 @@
static void addrconf_rs_timer(unsigned long data);
static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
-static struct notifier_block *inet6addr_chain;
+static LIST_HEAD(inet6addr_chain);
struct ipv6_devconf ipv6_devconf =
{
diff -Nru a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
--- a/net/netlink/af_netlink.c Wed Dec 18 09:03:09 2002
+++ b/net/netlink/af_netlink.c Wed Dec 18 09:03:09 2002
@@ -83,7 +83,7 @@
static rwlock_t nl_table_lock = RW_LOCK_UNLOCKED;
static atomic_t nl_table_users = ATOMIC_INIT(0);
-static struct notifier_block *netlink_chain;
+static LIST_HEAD(netlink_chain);
static void netlink_sock_destruct(struct sock *sk)
{
^ permalink raw reply
* Re: [PATCH]: c-r4k.c, new gcc's don't like empty labels
From: Ralf Baechle @ 2002-12-18 22:27 UTC (permalink / raw)
To: Juan Quintela; +Cc: linux mips mailing list
In-Reply-To: <m2k7i7nf6b.fsf@demo.mitica>
On Wed, Dec 18, 2002 at 11:19:24PM +0100, Juan Quintela wrote:
> ralf> On Wed, Dec 18, 2002 at 02:43:07AM +0100, Juan Quintela wrote:
> >> patch is trivial to eliminate warnings from the compiler
>
> ralf> And yet I didn't like it. The new syntax requirement isn't only ugly code,
> ralf> it's harder to read than a replacing the gotos with a simple return ...
>
> I thought that the gotos to end was there for generation of code
> reasons.
Doesn't make a code difference in this case for MIPS.
Ralf
^ permalink raw reply
* Re: Domain transition -- enabling user_r in eklogin
From: Brian May @ 2002-12-18 22:27 UTC (permalink / raw)
To: Russell Coker; +Cc: SELinux
In-Reply-To: <200212180845.22750.russell@coker.com.au>
On Wed, Dec 18, 2002 at 08:45:22AM +0100, Russell Coker wrote:
> Which is something you could easily achieve through PAM configuration if that
> is what you desire, without any kerberos issues etc.
How would you do it with PAM?
What security issues would this raise?
> Also I think that in most situations where a user could be tricked into
> running newrole then it's game-over anyway.
OK. I was thinking more of scripts, etc.
> > I am not yet sure how good SE-Linux will be at solving this type of
> > problem, without duplicating a lot of domains, for instance
> > a set of domains for programs with Kerberos ticket access, and
> > a duplicate set for programs without Kerberos ticket access).
>
> What exactly is "ticket access" and how does it conceptually differ from read
> access to /etc/shadow? Couldn't we just treat ticket access in the same way
> as access to /etc/shadow?
There are several differences:
- the ticket is created by login/PAM or kinit, not sysadm_r.
- the ticket has a limited life time, so if somebody accesses it,
its not quite as bad as somebody accessing one weak entry of the
shadow file.
- more importantly, there are no immediate security risks by proving a
trusted program access to the shadow file. It is not the
authentication key, it is the lock.
However, a kerberos ticket is the key. So if you provide, say rsh access
to the ticket, any process that has ability to run rsh, directly via
exec, or indirectly, say via bash, can run commands like (note I don't
have a man page handy, so I can't check the parameters for certain) "rsh
remotehost rm -rf ."
Even worse is if this ticket allows root access...
So you might need some instances of bash that can run rsh, and
other instances that are used for running untrusted scripts that
cannot run rsh.
I talk about Kerberos tickets here, the same thing would also apply to
ssh-agent connections, with the exception that once the connection is
closed, it is no longer a security threat.
--
Brian May <bam@snoopy.apana.org.au>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply
* Re: [LARTC] WonderShaper on LAN link kills to-host speed
From: Kenneth Porter @ 2002-12-18 22:25 UTC (permalink / raw)
To: lartc
In-Reply-To: <marc-lartc-104016341620263@msgid-missing>
--On Wednesday, December 18, 2002 10:53 PM +0100 Jose Luis Domingo Lopez
<lartc@24x7linux.com> wrote:
> As far as I know, inbound traffic (ingress) can only police packets,
> that is, discard traffic on excess hoping the other end will notice it
> and slow down a bit. If you want to classify incoming traffic
I don't know that I even need the policing function, esp. for LAN traffic
that is only queued at the original sender and in switches. (About 150
clients on a mixed 100/1000 Mbps LAN.) I was just surprised that it killed
traffic so badly. Perhaps I need to read up more on exactly what it's doing.
_______________________________________________
LARTC mailing list / LARTC@mailman.ds9a.nl
http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/
^ permalink raw reply
* Re: Intel P6 vs P7 system call performance
From: Jamie Lokier @ 2002-12-18 22:28 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Terje Eggestad, Linus Torvalds, Ulrich Drepper, Matti Aarnio,
Hugh Dickins, Dave Jones, Ingo Molnar, linux-kernel
In-Reply-To: <3E00D716.1010503@transmeta.com>
H. Peter Anvin wrote:
> Terje Eggestad wrote:
> > fd = open("/dev/vsyscall", );
> > _vsyscall = mmap(NULL, getpagesize(), PROT_READ|PROT_EXEC, MAP_SHARED,
> > fd, 0);
>
> Very ugly -- then the application has to do indirect calls.
No it doesn't.
The application, or library, would map the vsyscall page to an address
in its own data section. This means that position-independent code
can do vsyscalls without any relocations, and hence without dirtying
its own caller pages.
In some ways this is better than the 0xfffe0000 address: _that_
requires position-independent code to do indirect calls to the
absolute address, or to dirty its caller pages.
That said, you always need the page at 0xfffe0000 mapped anyway, so
that sysexit can jump to a fixed address (which is fastest).
-- Jamie
^ permalink raw reply
* Re: [LARTC] WonderShaper on LAN link kills to-host speed
From: Kenneth Porter @ 2002-12-18 22:22 UTC (permalink / raw)
To: lartc
In-Reply-To: <marc-lartc-104016341620263@msgid-missing>
--On Wednesday, December 18, 2002 10:43 PM +0100 Stef Coene
<stef.coene@docum.org> wrote:
> I'm not sure, but the policer can calculate the rate in the class in 2
> ways. And maybe your CPU can't handle the calculations. What CPU do
> you have and what's the load on the sstem?
It's a P2-233 with 128 MB memory (Dell PowerEdge 4200). It's a bit
memory-starved but otherwise seems to handle the load. It plays router,
mail server, DNS, and file server. (Long-term plan is to offload
non-gateway functions, once another box is freed up.)
What are the "2 ways"? A pointer to source code would be fine, I just need
to know where to start looking.
_______________________________________________
LARTC mailing list / LARTC@mailman.ds9a.nl
http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/
^ permalink raw reply
* Re: [PATCH]: fix compiler warnings in the math-emulator
From: Juan Quintela @ 2002-12-18 22:27 UTC (permalink / raw)
To: Greg Lindahl; +Cc: linux mips mailing list
In-Reply-To: <20021218132726.A2572@wumpus.internal.keyresearch.com>
>>>>> "greg" == Greg Lindahl <lindahl@keyresearch.com> writes:
>> > Sometimes you don't care whether you do only "half" a macro instruction
>> > if the branch is taken. Usually though, the warning is a good thing - I
>> > remember having spent many hours finding bugs like this with assemblers
>> > that don't issue warnings.
>>
>> This is exactly what ".set nomacro" is for -- I can't see any reason for
>> such warnings when ".set macro" is active.
greg> While in general I like playing with sharp knives (you should see my
greg> cluster admin toolkit), and I like my kernel to run fast, and the only
greg> thing that gets trashed is usually at, I still think I'd prefer to
greg> have nops in those delay slots in the kernel. Hand-written assembly is
greg> unlikely to use ".set nomacro" properly.
In the kernel for IP22 (I suppose the same for other architectures),
it has only two Assembler warnings. And they are all in the fast
path :(
one is in entry.S:excetp_vec3_r4000
and the other is in head.S:ejtag_debug_handler
I am not sure about the first one, but the second one shouldn't be
performance critical :(
Later, Juan.
--
In theory, practice and theory are the same, but in practice they
are different -- Larry McVoy
^ permalink raw reply
* One-liner to make S4 work
From: Pavel Machek @ 2002-12-18 22:24 UTC (permalink / raw)
To: kernel list, Swsusp mailing list
Hi!
This should make swsusp to work on 2.5.52...
Pavel
--- clean/mm/page_alloc.c 2002-12-18 22:21:13.000000000 +0100
+++ linux-swsusp/mm/page_alloc.c 2002-12-18 22:30:47.000000000 +0100
@@ -389,7 +389,7 @@
unsigned long flags;
struct page *page = NULL;
- if (order == 0) {
+ if ((order == 0) && !cold) {
struct per_cpu_pages *pcp;
pcp = &zone->pageset[get_cpu()].pcp[cold];
--
Worst form of spam? Adding advertisment signatures ala sourceforge.net.
What goes next? Inserting advertisment *into* email?
^ permalink raw reply
* Re: IDE-CD and VT8235 issue!!!
From: Marcelo Tosatti @ 2002-12-18 19:27 UTC (permalink / raw)
To: AnonimoVeneziano; +Cc: John Reiser, linux-kernel, Vojtech Pavlik, black666
In-Reply-To: <3E00F161.8090501@tin.it>
On Wed, 18 Dec 2002, AnonimoVeneziano wrote:
> John Reiser wrote:
>
> > Vojtech Pavlik wrote:
> >
> >> One more here, if you can try it (and remove the two previous ones
> >> first).
> >
> >
> > The earlier vt8235-dvd patch worked for me, but the later vt8235-min
> > did not.
> >
> > Mitsumi FX4830T ATAPI CD-ROM, MSI KT3 Ultra2 (KT333) mainboard, vt8235.
> > -----
> > kernel: hdc: status error: status=0x58 { DriveReady SeekComplete
> > DataRequest }
> > kernel: hdc: drive not ready for command
> > kernel: hdc: status timeout: status=0xd1 { Busy }
> > kernel: hdc: DMA disabled
> > kernel: hdc: drive not ready for command
> > kernel: hdc: ATAPI reset complete
> > kernel: hdc: status timeout: status=0xd1 { Busy }
> > kernel: hdc: drive not ready for command
> > -----
>
> Hunks error? during the patching?
>
> byez
>
> Marcello
Hi,
The lattest workaround from Vojtech fixed the problem for you ?
^ 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.