diff options
42 files changed, 279 insertions, 307 deletions
@@ -67,6 +67,8 @@ Koushik <raghavendra.koushik@neterion.com> Leonid I Ananiev <leonid.i.ananiev@intel.com> Linas Vepstas <linas@austin.ibm.com> Matthieu CASTET <castet.matthieu@free.fr> +Michael Buesch <mb@bu3sch.de> +Michael Buesch <mbuesch@freenet.de> Michel Dänzer <michel@tungstengraphics.com> Mitesh shah <mshah@teja.com> Morten Welinder <terra@gnome.org> diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index d3aae1f9b4c..702d1d8dd04 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -851,6 +851,15 @@ accept_redirects - BOOLEAN Functional default: enabled if local forwarding is disabled. disabled if local forwarding is enabled. +accept_source_route - INTEGER + Accept source routing (routing extension header). + + > 0: Accept routing header. + = 0: Accept only routing header type 2. + < 0: Do not accept routing header. + + Default: 0 + autoconf - BOOLEAN Autoconfigure addresses using Prefix Information in Router Advertisements. diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt index 625a21db0c2..85f51e5a749 100644 --- a/Documentation/x86_64/boot-options.txt +++ b/Documentation/x86_64/boot-options.txt @@ -293,7 +293,3 @@ Debugging stuck (default) Miscellaneous - - noreplacement Don't replace instructions with more appropriate ones - for the CPU. This may be useful on asymmetric MP systems - where some CPUs have less capabilities than others. diff --git a/MAINTAINERS b/MAINTAINERS index ef84419ade3..277877a34ef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1318,7 +1318,7 @@ S: Maintained ETHERNET BRIDGE P: Stephen Hemminger M: shemminger@linux-foundation.org -L: bridge@lists.osdl.org +L: bridge@lists.linux-foundation.org W: http://bridge.sourceforge.net/ S: Maintained @@ -1355,6 +1355,11 @@ M: kevin.curtis@farsite.co.uk W: http://www.farsite.co.uk/ S: Supported +FAULT INJECTION SUPPORT +P: Akinobu Mita +M: akinobu.mita@gmail.com +S: Supported + FRAMEBUFFER LAYER P: Antonino Daplas M: adaplas@gmail.com @@ -1690,7 +1695,7 @@ S: Maintained IEEE 1394 SUBSYSTEM P: Ben Collins -M: bcollins@debian.org +M: ben.collins@ubuntu.com P: Stefan Richter M: stefanr@s5r6.in-berlin.de L: linux1394-devel@lists.sourceforge.net @@ -1698,25 +1703,11 @@ W: http://www.linux1394.org/ T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git S: Maintained -IEEE 1394 IPV4 DRIVER (eth1394) -P: Stefan Richter -M: stefanr@s5r6.in-berlin.de -L: linux1394-devel@lists.sourceforge.net -S: Odd Fixes - -IEEE 1394 PCILYNX DRIVER -P: Jody McIntyre -M: scjody@modernduck.com -P: Stefan Richter -M: stefanr@s5r6.in-berlin.de -L: linux1394-devel@lists.sourceforge.net -S: Odd Fixes - -IEEE 1394 RAW I/O DRIVER -P: Ben Collins -M: bcollins@debian.org +IEEE 1394 RAW I/O DRIVER (raw1394) P: Dan Dennedy M: dan@dennedy.org +P: Stefan Richter +M: stefanr@s5r6.in-berlin.de L: linux1394-devel@lists.sourceforge.net S: Maintained @@ -1951,7 +1942,7 @@ P: Vivek Goyal M: vgoyal@in.ibm.com P: Haren Myneni M: hbabu@us.ibm.com -L: fastboot@lists.osdl.org +L: fastboot@lists.linux-foundation.org L: linux-kernel@vger.kernel.org W: http://lse.sourceforge.net/kdump/ S: Maintained @@ -1978,7 +1969,7 @@ S: Maintained KERNEL JANITORS P: Several -L: kernel-janitors@lists.osdl.org +L: kernel-janitors@lists.linux-foundation.org W: http://www.kerneljanitors.org/ S: Maintained @@ -2001,7 +1992,7 @@ P: Eric Biederman M: ebiederm@xmission.com W: http://www.xmission.com/~ebiederm/files/kexec/ L: linux-kernel@vger.kernel.org -L: fastboot@lists.osdl.org +L: fastboot@lists.linux-foundation.org S: Maintained KPROBES @@ -2339,7 +2330,7 @@ S: Maintained NETEM NETWORK EMULATOR P: Stephen Hemminger M: shemminger@linux-foundation.org -L: netem@lists.osdl.org +L: netem@lists.linux-foundation.org S: Maintained NETFILTER/IPTABLES/IPCHAINS @@ -3068,7 +3059,7 @@ S: Supported SOFTWARE SUSPEND: P: Pavel Machek M: pavel@suse.cz -L: linux-pm@lists.osdl.org +L: linux-pm@lists.linux-foundation.org S: Maintained SONIC NETWORK DRIVER diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 9eca21b49f6..426f59b0106 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -5,15 +5,9 @@ #include <asm/alternative.h> #include <asm/sections.h> -static int no_replacement = 0; static int smp_alt_once = 0; static int debug_alternative = 0; -static int __init noreplacement_setup(char *s) -{ - no_replacement = 1; - return 1; -} static int __init bootonly(char *str) { smp_alt_once = 1; @@ -25,7 +19,6 @@ static int __init debug_alt(char *str) return 1; } -__setup("noreplacement", noreplacement_setup); __setup("smp-alt-boot", bootonly); __setup("debug-alternative", debug_alt); @@ -252,9 +245,6 @@ void alternatives_smp_module_add(struct module *mod, char *name, struct smp_alt_module *smp; unsigned long flags; - if (no_replacement) - return; - if (smp_alt_once) { if (boot_cpu_has(X86_FEATURE_UP)) alternatives_smp_unlock(locks, locks_end, @@ -289,7 +279,7 @@ void alternatives_smp_module_del(struct module *mod) struct smp_alt_module *item; unsigned long flags; - if (no_replacement || smp_alt_once) + if (smp_alt_once) return; spin_lock_irqsave(&smp_alt, flags); @@ -320,7 +310,7 @@ void alternatives_smp_switch(int smp) return; #endif - if (no_replacement || smp_alt_once) + if (smp_alt_once) return; BUG_ON(!smp && (num_online_cpus() > 1)); @@ -386,13 +376,6 @@ extern struct paravirt_patch __start_parainstructions[], void __init alternative_instructions(void) { unsigned long flags; - if (no_replacement) { - printk(KERN_INFO "(SMP-)alternatives turned off\n"); - free_init_pages("SMP alternatives", - (unsigned long)__smp_alt_begin, - (unsigned long)__smp_alt_end); - return; - } local_irq_save(flags); apply_alternatives(__alt_instructions, __alt_instructions_end); diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 9f1e8c1afab..84c3497efb6 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -126,7 +126,7 @@ int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) int cpu; BUG_ON(counter > NMI_MAX_COUNTER_BITS); for_each_possible_cpu (cpu) { - if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) + if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) return 0; } return 1; @@ -142,7 +142,7 @@ int avail_to_resrv_perfctr_nmi(unsigned int msr) BUG_ON(counter > NMI_MAX_COUNTER_BITS); for_each_possible_cpu (cpu) { - if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) + if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) return 0; } return 1; @@ -157,7 +157,7 @@ static int __reserve_perfctr_nmi(int cpu, unsigned int msr) counter = nmi_perfctr_msr_to_bit(msr); BUG_ON(counter > NMI_MAX_COUNTER_BITS); - if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) + if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) return 1; return 0; } @@ -171,7 +171,7 @@ static void __release_perfctr_nmi(int cpu, unsigned int msr) counter = nmi_perfctr_msr_to_bit(msr); BUG_ON(counter > NMI_MAX_COUNTER_BITS); - clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)); + clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0]); } int reserve_perfctr_nmi(unsigned int msr) diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 69a8bcfe72b..4f94fa261aa 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -35,7 +35,7 @@ #define vpe_id() smp_processor_id() #else #define WHAT 0 -#define vpe_id() smp_processor_id() +#define vpe_id() 0 #endif #define __define_perf_accessors(r, n, np) \ diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index 2bac8c60ad6..0bae862e9a5 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c @@ -519,7 +519,11 @@ static __init int init_k8_gatt(struct agp_kern_info *info) gatt_size = (aper_size >> PAGE_SHIFT) * sizeof(u32); gatt = (void *)__get_free_pages(GFP_KERNEL, get_order(gatt_size)); if (!gatt) - panic("Cannot allocate GATT table"); + panic("Cannot allocate GATT table"); + if (change_page_attr_addr((unsigned long)gatt, gatt_size >> PAGE_SHIFT, PAGE_KERNEL_NOCACHE)) + panic("Could not set GART PTEs to uncacheable pages"); + global_flush_tlb(); + memset(gatt, 0, gatt_size); agp_gatt_table = gatt; diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index 65c5eaa5990..081409aa345 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c @@ -81,8 +81,8 @@ static void flush_kernel_map(void *arg) void *adr = page_address(pg); if (cpu_has_clflush) cache_flush_page(adr); - __flush_tlb_one(adr); } + __flush_tlb_all(); } static inline void flush_map(struct list_head *l) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 9e3797167c8..f92ba2a869b 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -532,6 +532,12 @@ static void cfq_add_rq_rb(struct request *rq) if (!cfq_cfqq_on_rr(cfqq)) cfq_add_cfqq_rr(cfqd, cfqq); + + /* + * check if this request is a better next-serve candidate + */ + cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq); + BUG_ON(!cfqq->next_rq); } static inline void @@ -1639,12 +1645,6 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfqq->meta_pending++; /* - * check if this request is a better next-serve candidate)) { - */ - cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq); - BUG_ON(!cfqq->next_rq); - - /* * we never wait for an async request and we don't allow preemption * of an async request. so just return early */ diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 0ae8b9310cb..589b98b7b21 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -758,7 +758,8 @@ static void acpi_thermal_check(void *data) del_timer(&(tz->timer)); } else { if (timer_pending(&(tz->timer))) - mod_timer(&(tz->timer), (HZ * sleep_time) / 1000); + mod_timer(&(tz->timer), + jiffies + (HZ * sleep_time) / 1000); else { tz->timer.data = (unsigned long)tz; tz->timer.function = acpi_thermal_run; diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index c852eed91e4..1eeb8f2cde7 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -140,7 +140,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY}; #include <linux/blkdev.h> #include <asm/uaccess.h> -static spinlock_t pcd_lock; +static DEFINE_SPINLOCK(pcd_lock); module_param(verbose, bool, 0644); module_param(major, int, 0); diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index 7cdaa195126..5826508f673 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -154,7 +154,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY}; #include <linux/blkpg.h> #include <asm/uaccess.h> -static spinlock_t pf_spin_lock; +static DEFINE_SPINLOCK(pf_spin_lock); module_param(verbose, bool, 0644); module_param(major, int, 0); diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index a4fb7038318..f1b9dd7d47d 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -777,7 +777,8 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command * rq->cmd_flags |= REQ_QUIET; blk_execute_rq(rq->q, pd->bdev->bd_disk, rq, 0); - ret = rq->errors; + if (rq->errors) + ret = -EIO; out: blk_put_request(rq); return ret; diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index a61fb6da5d0..80a01150b86 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -1338,43 +1338,23 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int c * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) * Caller should use TIOCGICOUNT to see which one it was */ - case TIOCMIWAIT: { - DECLARE_WAITQUEUE(wait, current); - int ret; + case TIOCMIWAIT: + spin_lock_irqsave(&info->slock, flags); + cnow = info->icount; /* note the counters on entry */ + spin_unlock_irqrestore(&info->slock, flags); + + wait_event_interruptible(info->delta_msr_wait, ({ + cprev = cnow; spin_lock_irqsave(&info->slock, flags); - cprev = info->icount; /* note the counters on entry */ + cnow = info->icount; /* atomic copy */ spin_unlock_irqrestore(&info->slock, flags); - add_wait_queue(&info->delta_msr_wait, &wait); - while (1) { - spin_lock_irqsave(&info->slock, flags); - cnow = info->icount; /* atomic copy */ - spin_unlock_irqrestore(&info->slock, flags); - - set_current_state(TASK_INTERRUPTIBLE); - if (((arg & TIOCM_RNG) && - (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && - (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && - (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && - (cnow.cts != cprev.cts))) { - ret = 0; - break; - } - /* see if a signal did it */ - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - cprev = cnow; - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->delta_msr_wait, &wait); - break; - } - /* NOTREACHED */ + ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)); + })); + break; /* * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) * Return: write counters to the user passed counter struct diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c index 9af07e4999d..f7603b6aeb8 100644 --- a/drivers/char/mxser_new.c +++ b/drivers/char/mxser_new.c @@ -1758,43 +1758,23 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) * Caller should use TIOCGICOUNT to see which one it was */ - case TIOCMIWAIT: { - DECLARE_WAITQUEUE(wait, current); - int ret; + case TIOCMIWAIT: spin_lock_irqsave(&info->slock, flags); - cprev = info->icount; /* note the counters on entry */ + cnow = info->icount; /* note the counters on entry */ spin_unlock_irqrestore(&info->slock, flags); - add_wait_queue(&info->delta_msr_wait, &wait); - while (1) { + wait_event_interruptible(info->delta_msr_wait, ({ + cprev = cnow; spin_lock_irqsave(&info->slock, flags); cnow = info->icount; /* atomic copy */ spin_unlock_irqrestore(&info->slock, flags); - set_current_state(TASK_INTERRUPTIBLE); - if (((arg & TIOCM_RNG) && - (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && - (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && - (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && - (cnow.cts != cprev.cts))) { - ret = 0; - break; - } - /* see if a signal did it */ - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - cprev = cnow; - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->delta_msr_wait, &wait); + ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)); + })); break; - } - /* NOTREACHED */ /* * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) * Return: write counters to the user passed counter struct @@ -2230,7 +2210,14 @@ end_intr: port->mon_data.rxcnt += cnt; port->mon_data.up_rxcnt += cnt; + /* + * We are called from an interrupt context with &port->slock + * being held. Drop it temporarily in order to prevent + * recursive locking. + */ + spin_unlock(&port->slock); tty_flip_buffer_push(tty); + spin_lock(&port->slock); } static void mxser_transmit_chars(struct mxser_port *port) diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 01206ebb1cf..30a76404f0a 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -121,9 +121,9 @@ superio_exit(void) * ISA constants */ -#define REGION_ALIGNMENT ~7 -#define REGION_OFFSET 5 -#define REGION_LENGTH 2 +#define IOREGION_ALIGNMENT ~7 +#define IOREGION_OFFSET 5 +#define IOREGION_LENGTH 2 #define ADDR_REG_OFFSET 5 #define DATA_REG_OFFSET 6 @@ -1194,7 +1194,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) u8 fan4pin, fan5pin; int i, err = 0; - if (!request_region(address + REGION_OFFSET, REGION_LENGTH, + if (!request_region(address + IOREGION_OFFSET, IOREGION_LENGTH, w83627ehf_driver.driver.name)) { err = -EBUSY; goto exit; @@ -1322,7 +1322,7 @@ exit_remove: exit_free: kfree(data); exit_release: - release_region(address + REGION_OFFSET, REGION_LENGTH); + release_region(address + IOREGION_OFFSET, IOREGION_LENGTH); exit: return err; } @@ -1337,7 +1337,7 @@ static int w83627ehf_detach_client(struct i2c_client *client) if ((err = i2c_detach_client(client))) return err; - release_region(client->addr + REGION_OFFSET, REGION_LENGTH); + release_region(client->addr + IOREGION_OFFSET, IOREGION_LENGTH); kfree(data); return 0; @@ -1380,7 +1380,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr) superio_select(W83627EHF_LD_HWM); val = (superio_inb(SIO_REG_ADDR) << 8) | superio_inb(SIO_REG_ADDR + 1); - *addr = val & REGION_ALIGNMENT; + *addr = val & IOREGION_ALIGNMENT; if (*addr == 0) { superio_exit(); return -ENODEV; diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 0b7aded8dcf..e85f5ec48f9 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -54,8 +54,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.5.7" -#define DRV_MODULE_RELDATE "March 29, 2007" +#define DRV_MODULE_VERSION "1.5.8" +#define DRV_MODULE_RELDATE "April 24, 2007" #define RUN_AT(x) (jiffies + (x)) @@ -3421,6 +3421,9 @@ bnx2_init_chip(struct bnx2 *bp) val = REG_RD(bp, BNX2_MQ_CONFIG); val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE; val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256; + if (CHIP_ID(bp) == CHIP_ID_5709_A0 || CHIP_ID(bp) == CHIP_ID_5709_A1) + val |= BNX2_MQ_CONFIG_HALT_DIS; + REG_WR(bp, BNX2_MQ_CONFIG, val); val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE); diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index ccbdf81c659..878eee58f12 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6518,6 +6518,7 @@ struct bnx2 { #define CHIP_ID_5708_B0 0x57081000 #define CHIP_ID_5708_B1 0x57081010 #define CHIP_ID_5709_A0 0x57090000 +#define CHIP_ID_5709_A1 0x57090010 #define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0xf) diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 5113eef755b..f3807aaf10a 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -1491,8 +1491,9 @@ static void __init depca_platform_probe (void) depca_io_ports[i].device = pldev; if (platform_device_add(pldev)) { - platform_device_put(pldev); depca_io_ports[i].device = NULL; + pldev->dev.platform_data = NULL; + platform_device_put(pldev); continue; } diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index 59214e74b9c..30baf6ecfc6 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c @@ -75,12 +75,14 @@ #include <linux/ioport.h> #include <linux/string.h> #include <linux/init.h> -#include <asm/uaccess.h> -#include <asm/io.h> #include <linux/hdlcdrv.h> #include <linux/baycom.h> #include <linux/jiffies.h> +#include <asm/uaccess.h> +#include <asm/io.h> +#include <asm/irq.h> + /* --------------------------------------------------------------------- */ #define BAYCOM_DEBUG diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index b3750f28427..b2a3b19d773 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -1755,6 +1755,24 @@ static int sis900_rx(struct net_device *net_dev) } else { struct sk_buff * skb; + pci_unmap_single(sis_priv->pci_dev, + sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE, + PCI_DMA_FROMDEVICE); + + /* refill the Rx buffer, what if there is not enought + * memory for new socket buffer ?? */ + if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) { + /* + * Not enough memory to refill the buffer + * so we need to recycle the old one so + * as to avoid creating a memory hole + * in the rx ring + */ + skb = sis_priv->rx_skbuff[entry]; + sis_priv->stats.rx_dropped++; + goto refill_rx_ring; + } + /* This situation should never happen, but due to some unknow bugs, it is possible that we are working on NULL sk_buff :-( */ @@ -1768,9 +1786,6 @@ static int sis900_rx(struct net_device *net_dev) break; } - pci_unmap_single(sis_priv->pci_dev, - sis_priv->rx_ring[entry].bufptr, RX_BUF_SIZE, - PCI_DMA_FROMDEVICE); /* give the socket buffer to upper layers */ skb = sis_priv->rx_skbuff[entry]; skb_put(skb, rx_size); @@ -1783,33 +1798,14 @@ static int sis900_rx(struct net_device *net_dev) net_dev->last_rx = jiffies; sis_priv->stats.rx_bytes += rx_size; sis_priv->stats.rx_packets++; - - /* refill the Rx buffer, what if there is not enought - * memory for new socket buffer ?? */ - if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) { - /* not enough memory for skbuff, this makes a - * "hole" on the buffer ring, it is not clear - * how the hardware will react to this kind - * of degenerated buffer */ - if (netif_msg_rx_status(sis_priv)) - printk(KERN_INFO "%s: Memory squeeze," - "deferring packet.\n", - net_dev->name); - sis_priv->rx_skbuff[entry] = NULL; - /* reset buffer descriptor state */ - sis_priv->rx_ring[entry].cmdsts = 0; - sis_priv->rx_ring[entry].bufptr = 0; - sis_priv->stats.rx_dropped++; - sis_priv->cur_rx++; - break; - } + sis_priv->dirty_rx++; +refill_rx_ring: skb->dev = net_dev; sis_priv->rx_skbuff[entry] = skb; sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; sis_priv->rx_ring[entry].bufptr = pci_map_single(sis_priv->pci_dev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); - sis_priv->dirty_rx++; } sis_priv->cur_rx++; entry = sis_priv->cur_rx % NUM_RX_DESC; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index a4a96826d9e..2fe1d690eb1 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -682,34 +682,7 @@ static void pci_read_irq(struct pci_dev *dev) dev->irq = irq; } -static void change_legacy_io_resource(struct pci_dev * dev, unsigned index, - unsigned start, unsigned end) -{ - unsigned base = start & PCI_BASE_ADDRESS_IO_MASK; - unsigned len = (end | ~PCI_BASE_ADDRESS_IO_MASK) - base + 1; - - /* - * Some X versions get confused when the BARs reported through - * /sys or /proc differ from those seen in config space, thus - * try to update the config space values, too. - */ - if (!(pci_resource_flags(dev, index) & IORESOURCE_IO)) - printk(KERN_WARNING "%s: cannot adjust BAR%u (not I/O)\n", - pci_name(dev), index); - else if (pci_resource_len(dev, index) != len) - printk(KERN_WARNING "%s: cannot adjust BAR%u (size %04X)\n", - pci_name(dev), index, (unsigned)pci_resource_len(dev, index)); - else { - printk(KERN_INFO "%s: trying to change BAR%u from %04X to %04X\n", - pci_name(dev), index, - (unsigned)pci_resource_start(dev, index), base); - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + index * 4, base); - } - pci_resource_start(dev, index) = start; - pci_resource_end(dev, index) = end; - pci_resource_flags(dev, index) = - IORESOURCE_IO | IORESOURCE_PCI_FIXED | PCI_BASE_ADDRESS_SPACE_IO; -} +#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) /** * pci_setup_device - fill in class and map information of a device @@ -762,12 +735,20 @@ static int pci_setup_device(struct pci_dev * dev) u8 progif; pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); if ((progif & 1) == 0) { - change_legacy_io_resource(dev, 0, 0x1F0, 0x1F7); - change_legacy_io_resource(dev, 1, 0x3F6, 0x3F6); + dev->resource[0].start = 0x1F0; + dev->resource[0].end = 0x1F7; + dev->resource[0].flags = LEGACY_IO_RESOURCE; + dev->resource[1].start = 0x3F6; + dev->resource[1].end = 0x3F6; + dev->resource[1].flags = LEGACY_IO_RESOURCE; } if ((progif & 4) == 0) { - change_legacy_io_resource(dev, 2, 0x170, 0x177); - change_legacy_io_resource(dev, 3, 0x376, 0x376); + dev->resource[2].start = 0x170; + dev->resource[2].end = 0x177; + dev->resource[2].flags = LEGACY_IO_RESOURCE; + dev->resource[3].start = 0x376; + dev->resource[3].end = 0x376; + dev->resource[3].flags = LEGACY_IO_RESOURCE; } } break; diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index c129a0e8e80..90621c3312b 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -1310,7 +1310,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up) { unsigned int status = serial_in(up, UART_MSR); - if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI) { + if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && + up->port.info != NULL) { if (status & UART_MSR_TERI) up->port.icount.rng++; if (status & UART_MSR_DDSR) @@ -1333,8 +1334,9 @@ static inline void serial8250_handle_port(struct uart_8250_port *up) { unsigned int status; + unsigned long flags; - spin_lock(&up->port.lock); + spin_lock_irqsave(&up->port.lock, flags); status = serial_inp(up, UART_LSR); @@ -1346,7 +1348,7 @@ serial8250_handle_port(struct uart_8250_port *up) if (status & UART_LSR_THRE) transmit_chars(up); - spin_unlock(&up->port.lock); + spin_unlock_irqrestore(&up->port.lock, flags); } /* diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c index 41431d0d551..246c5572667 100644 --- a/drivers/serial/icom.c +++ b/drivers/serial/icom.c @@ -164,7 +164,7 @@ static void free_port_memory(struct icom_port *icom_port) } } -static int __init get_port_memory(struct icom_port *icom_port) +static int __devinit get_port_memory(struct icom_port *icom_port) { int index; unsigned long stgAddr; @@ -1380,7 +1380,7 @@ static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *i 0x8024 + 2 - 2 * (icom_port->port - 2); } } -static int __init icom_load_ports(struct icom_adapter *icom_adapter) +static int __devinit icom_load_ports(struct icom_adapter *icom_adapter) { struct icom_port *icom_port; int port_num; @@ -1473,7 +1473,7 @@ static void icom_remove_adapter(struct icom_adapter *icom_adapter) } } - free_irq(icom_adapter->irq_number, (void *) icom_adapter); + free_irq(icom_adapter->pci_dev->irq, (void *) icom_adapter); iounmap(icom_adapter->base_addr); icom_free_adapter(icom_adapter); pci_release_regions(icom_adapter->pci_dev); @@ -1539,7 +1539,6 @@ static int __devinit icom_probe(struct pci_dev *dev, } icom_adapter->base_addr_pci = pci_resource_start(dev, 0); - icom_adapter->irq_number = dev->irq; icom_adapter->pci_dev = dev; icom_adapter->version = ent->driver_data; icom_adapter->subsystem_id = ent->subdevice; @@ -1570,7 +1569,7 @@ static int __devinit icom_probe(struct pci_dev *dev, icom_port = &icom_adapter->port_info[index]; if (icom_port->status == ICOM_PORT_ACTIVE) { - icom_port->uart_port.irq = icom_port->adapter->irq_number; + icom_port->uart_port.irq = icom_port->adapter->pci_dev->irq; icom_port->uart_port.type = PORT_ICOM; icom_port->uart_port.iotype = UPIO_MEM; icom_port->uart_port.membase = diff --git a/drivers/serial/icom.h b/drivers/serial/icom.h index 798f1ef2371..e8578d8cd35 100644 --- a/drivers/serial/icom.h +++ b/drivers/serial/icom.h @@ -258,7 +258,6 @@ struct icom_port { struct icom_adapter { void __iomem * base_addr; unsigned long base_addr_pci; - unsigned char irq_number; struct pci_dev *pci_dev; struct icom_port port_info[4]; int index; diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index d48c024cff5..6d12961cf9f 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -316,6 +316,7 @@ static int update_eth_regs_async(pegasus_t * pegasus) return ret; } +/* Returns 0 on success, error on failure */ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) { int i; @@ -847,10 +848,16 @@ static void intr_callback(struct urb *urb) * d[0].NO_CARRIER kicks in only with failed TX. * ... so monitoring with MII may be safest. */ - if (d[0] & NO_CARRIER) - netif_carrier_off(net); - else - netif_carrier_on(net); + if (pegasus->features & TRUST_LINK_STATUS) { + if (d[5] & LINK_STATUS) + netif_carrier_on(net); + else + netif_carrier_off(net); + } else { + /* Never set carrier _on_ based on ! NO_CARRIER */ + if (d[0] & NO_CARRIER) + netif_carrier_off(net); + } /* bytes 3-4 == rx_lostpkt, reg 2E/2F */ pegasus->stats.rx_missed_errors += ((d[3] & 0x7f) << 8) | d[4]; @@ -950,7 +957,7 @@ static void set_carrier(struct net_device *net) pegasus_t *pegasus = netdev_priv(net); u16 tmp; - if (!read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp)) + if (read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp)) return; if (tmp & BMSR_LSTATUS) diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h index c7467823cd1..c7aadb413e8 100644 --- a/drivers/usb/net/pegasus.h +++ b/drivers/usb/net/pegasus.h @@ -11,6 +11,7 @@ #define PEGASUS_II 0x80000000 #define HAS_HOME_PNA 0x40000000 +#define TRUST_LINK_STATUS 0x20000000 #define PEGASUS_MTU 1536 #define RX_SKBS 4 @@ -203,7 +204,7 @@ PEGASUS_DEV( "AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701, PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, - DEFAULT_GPIO_RESET | PEGASUS_II ) + DEFAULT_GPIO_RESET | PEGASUS_II | TRUST_LINK_STATUS ) PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987, diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index e4f0dd00ae8..8372ace4a0d 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -139,7 +139,7 @@ config FB_TILEBLITTING This is particularly important to one driver, matroxfb. If unsure, say N. -comment "Frambuffer hardware drivers" +comment "Frame buffer hardware drivers" depends on FB config FB_CIRRUS diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 124a085d1f2..b01b0a45793 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -415,7 +415,7 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) file_inode = file->d_inode; sb = file_inode->i_sb; v9ses = v9fs_inode2v9ses(file_inode); - v9fid = v9fs_fid_lookup(file); + v9fid = v9fs_fid_clone(file); if(IS_ERR(v9fid)) return PTR_ERR(v9fid); diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index f01389fd162..c8178b7b921 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -54,82 +54,48 @@ static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char *prefix); -static struct dentry *create_xa_root(struct super_block *sb) +/* Returns the dentry referring to the root of the extended attribute + * directory tree. If it has already been retrieved, it is used. If it + * hasn't been created and the flags indicate creation is allowed, we + * attempt to create it. On error, we return a pointer-encoded error. + */ +static struct dentry *get_xa_root(struct super_block *sb, int flags) { struct dentry *privroot = dget(REISERFS_SB(sb)->priv_root); struct dentry *xaroot; /* This needs to be created at mount-time */ if (!privroot) - return ERR_PTR(-EOPNOTSUPP); + return ERR_PTR(-ENODATA); - xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME)); - if (IS_ERR(xaroot)) { + mutex_lock(&privroot->d_inode->i_mutex); + if (REISERFS_SB(sb)->xattr_root) { + xaroot = dget(REISERFS_SB(sb)->xattr_root); goto out; - } else if (!xaroot->d_inode) { - int err; - mutex_lock(&privroot->d_inode->i_mutex); - err = - privroot->d_inode->i_op->mkdir(privroot->d_inode, xaroot, - 0700); - mutex_unlock(&privroot->d_inode->i_mutex); - - if (err) { - dput(xaroot); - dput(privroot); - return ERR_PTR(err); - } - REISERFS_SB(sb)->xattr_root = dget(xaroot); } - out: - dput(privroot); - return xaroot; -} - -/* This will return a dentry, or error, refering to the xa root directory. - * If the xa root doesn't exist yet, the dentry will be returned without - * an associated inode. This dentry can be used with ->mkdir to create - * the xa directory. */ -static struct dentry *__get_xa_root(struct super_block *s) -{ - struct dentry *privroot = dget(REISERFS_SB(s)->priv_root); - struct dentry *xaroot = NULL; - - if (IS_ERR(privroot) || !privroot) - return privroot; - xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME)); if (IS_ERR(xaroot)) { goto out; } else if (!xaroot->d_inode) { - dput(xaroot); - xaroot = NULL; - goto out; + int err = -ENODATA; + if (flags == 0 || flags & XATTR_CREATE) + err = privroot->d_inode->i_op->mkdir(privroot->d_inode, + xaroot, 0700); + if (err) { + dput(xaroot); + xaroot = ERR_PTR(err); + goto out; + } } - - REISERFS_SB(s)->xattr_root = dget(xaroot); + REISERFS_SB(sb)->xattr_root = dget(xaroot); out: + mutex_unlock(&privroot->d_inode->i_mutex); dput(privroot); return xaroot; } -/* Returns the dentry (or NULL) referring to the root of the extended - * attribute directory tree. If it has already been retrieved, it is used. - * Otherwise, we attempt to retrieve it from disk. It may also return - * a pointer-encoded error. - */ -static inline struct dentry *get_xa_root(struct super_block *s) -{ - struct dentry *dentry = dget(REISERFS_SB(s)->xattr_root); - - if (!dentry) - dentry = __get_xa_root(s); - - return dentry; -} - /* Opens the directory corresponding to the inode's extended attribute store. * If flags allow, the tree to the directory may be created. If creation is * prohibited, -ENODATA is returned. */ @@ -138,21 +104,11 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags) struct dentry *xaroot, *xadir; char namebuf[17]; - xaroot = get_xa_root(inode->i_sb); - if (IS_ERR(xaroot)) { + xaroot = get_xa_root(inode->i_sb, flags); + if (IS_ERR(xaroot)) return xaroot; - } else if (!xaroot) { - if (flags == 0 || flags & XATTR_CREATE) { - xaroot = create_xa_root(inode->i_sb); - if (IS_ERR(xaroot)) - return xaroot; - } - if (!xaroot) - return ERR_PTR(-ENODATA); - } /* ok, we have xaroot open */ - snprintf(namebuf, sizeof(namebuf), "%X.%X", le32_to_cpu(INODE_PKEY(inode)->k_objectid), inode->i_generation); @@ -821,7 +777,7 @@ int reiserfs_delete_xattrs(struct inode *inode) /* Leftovers besides . and .. -- that's not good. */ if (dir->d_inode->i_nlink <= 2) { - root = get_xa_root(inode->i_sb); + root = get_xa_root(inode->i_sb, XATTR_REPLACE); reiserfs_write_lock_xattrs(inode->i_sb); err = vfs_rmdir(root->d_inode, dir); reiserfs_write_unlock_xattrs(inode->i_sb); diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f8241130f5e..713eb5eaa81 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -177,6 +177,7 @@ struct ipv6_devconf { #endif #endif __s32 proxy_ndp; + __s32 accept_source_route; void *sysctl; }; @@ -205,6 +206,8 @@ enum { DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_PROXY_NDP, + __DEVCONF_OPTIMISTIC_DAD, + DEVCONF_ACCEPT_SOURCE_ROUTE, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 2c5fb38d939..9a8970bf99a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -580,6 +580,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_ACCEPT_SOURCE_ROUTE=25, __NET_IPV6_MAX }; diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h index 3fced479825..a46104a28f6 100644 --- a/include/linux/taskstats.h +++ b/include/linux/taskstats.h @@ -31,7 +31,7 @@ */ -#define TASKSTATS_VERSION 3 +#define TASKSTATS_VERSION 4 #define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN * in linux/sched.h */ @@ -66,7 +66,7 @@ struct taskstats { /* Delay waiting for cpu, while runnable * count, delay_total NOT updated atomically */ - __u64 cpu_count; + __u64 cpu_count __attribute__((aligned(8))); __u64 cpu_delay_total; /* Following four fields atomically updated using task->delays->lock */ @@ -101,14 +101,17 @@ struct taskstats { /* Basic Accounting Fields start */ char ac_comm[TS_COMM_LEN]; /* Command name */ - __u8 ac_sched; /* Scheduling discipline */ + __u8 ac_sched __attribute__((aligned(8))); + /* Scheduling discipline */ __u8 ac_pad[3]; - __u32 ac_uid; /* User ID */ + __u32 ac_uid __attribute__((aligned(8))); + /* User ID */ __u32 ac_gid; /* Group ID */ __u32 ac_pid; /* Process ID */ __u32 ac_ppid; /* Parent process ID */ __u32 ac_btime; /* Begin time [sec since 1970] */ - __u64 ac_etime; /* Elapsed time [usec] */ + __u64 ac_etime __attribute__((aligned(8))); + /* Elapsed time [usec] */ __u64 ac_utime; /* User CPU time [usec] */ __u64 ac_stime; /* SYstem CPU time [usec] */ __u64 ac_minflt; /* Minor Page Fault Count */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 1b255df4fcd..c904748f229 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1676,7 +1676,7 @@ static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp, { int op; - if (!capable(CAP_SYS_ADMIN)) + if (write && !capable(CAP_SYS_ADMIN)) return -EPERM; op = OP_OR; diff --git a/mm/migrate.c b/mm/migrate.c index 7a66ca25dc8..a91ca00abeb 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -297,7 +297,7 @@ static int migrate_page_move_mapping(struct address_space *mapping, void **pslot; if (!mapping) { - /* Anonymous page */ + /* Anonymous page without mapping */ if (page_count(page) != 1) return -EAGAIN; return 0; @@ -333,6 +333,19 @@ static int migrate_page_move_mapping(struct address_space *mapping, */ __put_page(page); + /* + * If moved to a different zone then also account + * the page for that zone. Other VM counters will be + * taken care of when we establish references to the + * new page and drop references to the old page. + * + * Note that anonymous pages are accounted for + * via NR_FILE_PAGES and NR_ANON_PAGES if they + * are mapped to swap space. + */ + __dec_zone_page_state(page, NR_FILE_PAGES); + __inc_zone_page_state(newpage, NR_FILE_PAGES); + write_unlock_irq(&mapping->tree_lock); return 0; diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 2f3916986ab..3791edfffee 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -176,6 +176,8 @@ static inline int constrained_alloc(struct zonelist *zonelist, gfp_t gfp_mask) struct zone **z; nodemask_t nodes; int node; + + nodes_clear(nodes); /* node has memory ? */ for_each_online_node(node) if (NODE_DATA(node)->node_present_pages) @@ -333,7 +335,7 @@ static int oom_kill_task(struct task_struct *p) */ do_each_thread(g, q) { if (q->mm == mm && q->tgid != p->tgid) - force_sig(SIGKILL, p); + force_sig(SIGKILL, q); } while_each_thread(g, q); return 0; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index fc920f63452..cac06c43f00 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -776,6 +776,8 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb ) .nl_u = { .ip4_u = { .daddr = frn->fl_addr, .tos = frn->fl_tos, .scope = frn->fl_scope } } }; + + frn->err = -ENOENT; if (tb) { local_bh_disable(); @@ -787,6 +789,7 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb ) frn->nh_sel = res.nh_sel; frn->type = res.type; frn->scope = res.scope; + fib_res_put(&res); } local_bh_enable(); } @@ -801,6 +804,9 @@ static void nl_fib_input(struct sock *sk, int len) struct fib_table *tb; skb = skb_dequeue(&sk->sk_receive_queue); + if (skb == NULL) + return; + nlh = (struct nlmsghdr *)skb->data; if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len || nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) { @@ -813,7 +819,7 @@ static void nl_fib_input(struct sock *sk, int len) nl_fib_lookup(frn, tb); - pid = nlh->nlmsg_pid; /*pid of sending process */ + pid = NETLINK_CB(skb).pid; /* pid of sending process */ NETLINK_CB(skb).pid = 0; /* from kernel */ NETLINK_CB(skb).dst_group = 0; /* unicast */ netlink_unicast(sk, skb, pid, MSG_DONTWAIT); diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 5c8caf4a124..34ae3f13483 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c @@ -77,18 +77,19 @@ void tcp_init_congestion_control(struct sock *sk) struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_congestion_ops *ca; - if (icsk->icsk_ca_ops != &tcp_init_congestion_ops) - return; + /* if no choice made yet assign the current value set as default */ + if (icsk->icsk_ca_ops == &tcp_init_congestion_ops) { + rcu_read_lock(); + list_for_each_entry_rcu(ca, &tcp_cong_list, list) { + if (try_module_get(ca->owner)) { + icsk->icsk_ca_ops = ca; + break; + } - rcu_read_lock(); - list_for_each_entry_rcu(ca, &tcp_cong_list, list) { - if (try_module_get(ca->owner)) { - icsk->icsk_ca_ops = ca; - break; + /* fallback to next available */ } - + rcu_read_unlock(); } - rcu_read_unlock(); if (icsk->icsk_ca_ops->init) icsk->icsk_ca_ops->init(sk); @@ -236,6 +237,7 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) rcu_read_lock(); ca = tcp_ca_find(name); + /* no change asking for existing value */ if (ca == icsk->icsk_ca_ops) goto out; @@ -261,7 +263,8 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) else { tcp_cleanup_congestion_control(sk); icsk->icsk_ca_ops = ca; - if (icsk->icsk_ca_ops->init) + + if (sk->sk_state != TCP_CLOSE && icsk->icsk_ca_ops->init) icsk->icsk_ca_ops->init(sk); } out: diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c index f68dfd8a0f5..d419e15d980 100644 --- a/net/ipv4/xfrm4_mode_beet.c +++ b/net/ipv4/xfrm4_mode_beet.c @@ -52,7 +52,7 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) ph = (struct ip_beet_phdr *)skb->h.raw; ph->padlen = 4 - (optlen & 4); - ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8; + ph->hdrlen = optlen / 8; ph->nexthdr = top_iph->protocol; if (ph->padlen) memset(ph + 1, IPOPT_NOP, ph->padlen); @@ -85,7 +85,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) ph = (struct ip_beet_phdr *)(skb->h.ipiph + 1); phlen = sizeof(*ph) + ph->padlen; - optlen = ph->hdrlen * 8 - phlen; + optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen); if (optlen < 0 || optlen & 3 || optlen > 250) goto out; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 7552663aa12..452a82ce479 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -172,6 +172,7 @@ struct ipv6_devconf ipv6_devconf __read_mostly = { #endif #endif .proxy_ndp = 0, + .accept_source_route = 0, /* we do not accept RH0 by default. */ }; static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { @@ -203,6 +204,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { #endif #endif .proxy_ndp = 0, + .accept_source_route = 0, /* we do not accept RH0 by default. */ }; /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ @@ -3356,6 +3358,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, #endif #endif array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp; + array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route; } static inline size_t inet6_if_nlmsg_size(void) @@ -3884,6 +3887,14 @@ static struct addrconf_sysctl_table .proc_handler = &proc_dointvec, }, { + .ctl_name = NET_IPV6_ACCEPT_SOURCE_ROUTE, + .procname = "accept_source_route", + .data = &ipv6_devconf.accept_source_route, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { .ctl_name = 0, /* sentinel */ } }, diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 28e0c656827..fb39604c3d0 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -362,10 +362,27 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) struct inet6_skb_parm *opt = IP6CB(skb); struct in6_addr *addr = NULL; struct in6_addr daddr; + struct inet6_dev *idev; int n, i; - struct ipv6_rt_hdr *hdr; struct rt0_hdr *rthdr; + int accept_source_route = ipv6_devconf.accept_source_route; + + if (accept_source_route < 0 || + ((idev = in6_dev_get(skb->dev)) == NULL)) { + kfree_skb(skb); + return -1; + } + if (idev->cnf.accept_source_route < 0) { + in6_dev_put(idev); + kfree_skb(skb); + return -1; + } + + if (accept_source_route > idev->cnf.accept_source_route) + accept_source_route = idev->cnf.accept_source_route; + + in6_dev_put(idev); if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { @@ -377,6 +394,22 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp) hdr = (struct ipv6_rt_hdr *) skb->h.raw; + switch (hdr->type) { +#ifdef CONFIG_IPV6_MIP6 + break; +#endif + case IPV6_SRCRT_TYPE_0: + if (accept_source_route > 0) + break; + kfree_skb(skb); + return -1; + default: + IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), + IPSTATS_MIB_INHDRERRORS); + icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); + return -1; + } + if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) || skb->pkt_type != PACKET_HOST) { IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), @@ -434,11 +467,6 @@ looped_back: } break; #endif - default: - IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), - IPSTATS_MIB_INHDRERRORS); - icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); - return -1; } /* |