diff --git a/[refs] b/[refs] index f2eaa94dd625..632a82778278 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: af75cd3c67845ebe31d2df9a780889a5ebecef11 +refs/heads/master: 0a58e077eb600d1efd7e54ad9926a75a39d7f8ae diff --git a/trunk/Documentation/ABI/testing/sysfs-block b/trunk/Documentation/ABI/testing/sysfs-block index c1eb41cb9876..4873c759d535 100644 --- a/trunk/Documentation/ABI/testing/sysfs-block +++ b/trunk/Documentation/ABI/testing/sysfs-block @@ -142,67 +142,3 @@ Description: with the previous I/O request are enabled. When set to 2, all merge tries are disabled. The default value is 0 - which enables all types of merge tries. - -What: /sys/block//discard_alignment -Date: May 2011 -Contact: Martin K. Petersen -Description: - Devices that support discard functionality may - internally allocate space in units that are bigger than - the exported logical block size. The discard_alignment - parameter indicates how many bytes the beginning of the - device is offset from the internal allocation unit's - natural alignment. - -What: /sys/block///discard_alignment -Date: May 2011 -Contact: Martin K. Petersen -Description: - Devices that support discard functionality may - internally allocate space in units that are bigger than - the exported logical block size. The discard_alignment - parameter indicates how many bytes the beginning of the - partition is offset from the internal allocation unit's - natural alignment. - -What: /sys/block//queue/discard_granularity -Date: May 2011 -Contact: Martin K. Petersen -Description: - Devices that support discard functionality may - internally allocate space using units that are bigger - than the logical block size. The discard_granularity - parameter indicates the size of the internal allocation - unit in bytes if reported by the device. Otherwise the - discard_granularity will be set to match the device's - physical block size. A discard_granularity of 0 means - that the device does not support discard functionality. - -What: /sys/block//queue/discard_max_bytes -Date: May 2011 -Contact: Martin K. Petersen -Description: - Devices that support discard functionality may have - internal limits on the number of bytes that can be - trimmed or unmapped in a single operation. Some storage - protocols also have inherent limits on the number of - blocks that can be described in a single command. The - discard_max_bytes parameter is set by the device driver - to the maximum number of bytes that can be discarded in - a single operation. Discard requests issued to the - device must not exceed this limit. A discard_max_bytes - value of 0 means that the device does not support - discard functionality. - -What: /sys/block//queue/discard_zeroes_data -Date: May 2011 -Contact: Martin K. Petersen -Description: - Devices that support discard functionality may return - stale or random data when a previously discarded block - is read back. This can cause problems if the filesystem - expects discarded blocks to be explicitly cleared. If a - device reports that it deterministically returns zeroes - when a discarded area is read the discard_zeroes_data - parameter will be set to one. Otherwise it will be 0 and - the result of reading a discarded area is undefined. diff --git a/trunk/Makefile b/trunk/Makefile index 123d858dae03..41ea6fbec55a 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 39 -EXTRAVERSION = +EXTRAVERSION = -rc7 NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* diff --git a/trunk/arch/mips/ar7/gpio.c b/trunk/arch/mips/ar7/gpio.c index bb571bcdb8f2..425dfa5d6e12 100644 --- a/trunk/arch/mips/ar7/gpio.c +++ b/trunk/arch/mips/ar7/gpio.c @@ -325,7 +325,9 @@ int __init ar7_gpio_init(void) size = 0x1f; } - gpch->regs = ioremap_nocache(AR7_REGS_GPIO, size); + gpch->regs = ioremap_nocache(AR7_REGS_GPIO, + AR7_REGS_GPIO + 0x10); + if (!gpch->regs) { printk(KERN_ERR "%s: failed to ioremap regs\n", gpch->chip.label); diff --git a/trunk/arch/mips/include/asm/dma-mapping.h b/trunk/arch/mips/include/asm/dma-mapping.h index 7aa37ddfca4b..655f849bd08d 100644 --- a/trunk/arch/mips/include/asm/dma-mapping.h +++ b/trunk/arch/mips/include/asm/dma-mapping.h @@ -5,9 +5,7 @@ #include #include -#ifndef CONFIG_SGI_IP27 /* Kludge to fix 2.6.39 build for IP27 */ #include -#endif extern struct dma_map_ops *mips_dma_map_ops; diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index e9b3af27d844..71350f7f2d88 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -374,8 +374,7 @@ void __noreturn die(const char *str, struct pt_regs *regs) unsigned long dvpret = dvpe(); #endif /* CONFIG_MIPS_MT_SMTC */ - if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP) - sig = 0; + notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV); console_verbose(); spin_lock_irq(&die_lock); @@ -384,6 +383,9 @@ void __noreturn die(const char *str, struct pt_regs *regs) mips_mt_regdump(dvpret); #endif /* CONFIG_MIPS_MT_SMTC */ + if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP) + sig = 0; + printk("%s[#%d]:\n", str, ++die_counter); show_registers(regs); add_taint(TAINT_DIE); diff --git a/trunk/arch/mips/rb532/gpio.c b/trunk/arch/mips/rb532/gpio.c index 6c47dfeb7be3..37de05d595e7 100644 --- a/trunk/arch/mips/rb532/gpio.c +++ b/trunk/arch/mips/rb532/gpio.c @@ -185,7 +185,7 @@ int __init rb532_gpio_init(void) struct resource *r; r = rb532_gpio_reg0_res; - rb532_gpio_chip->regbase = ioremap_nocache(r->start, resource_size(r)); + rb532_gpio_chip->regbase = ioremap_nocache(r->start, r->end - r->start); if (!rb532_gpio_chip->regbase) { printk(KERN_ERR "rb532: cannot remap GPIO register 0\n"); diff --git a/trunk/arch/powerpc/platforms/83xx/suspend.c b/trunk/arch/powerpc/platforms/83xx/suspend.c index 104faa8aa23c..188272934cfb 100644 --- a/trunk/arch/powerpc/platforms/83xx/suspend.c +++ b/trunk/arch/powerpc/platforms/83xx/suspend.c @@ -318,20 +318,17 @@ static const struct platform_suspend_ops mpc83xx_suspend_ops = { .end = mpc83xx_suspend_end, }; -static struct of_device_id pmc_match[]; static int pmc_probe(struct platform_device *ofdev) { - const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct resource res; struct pmc_type *type; int ret = 0; - match = of_match_device(pmc_match, &ofdev->dev); - if (!match) + if (!ofdev->dev.of_match) return -EINVAL; - type = match->data; + type = ofdev->dev.of_match->data; if (!of_device_is_available(np)) return -ENODEV; diff --git a/trunk/arch/powerpc/sysdev/fsl_msi.c b/trunk/arch/powerpc/sysdev/fsl_msi.c index 01cd2f089512..d5679dc1e20f 100644 --- a/trunk/arch/powerpc/sysdev/fsl_msi.c +++ b/trunk/arch/powerpc/sysdev/fsl_msi.c @@ -304,10 +304,8 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi, return 0; } -static const struct of_device_id fsl_of_msi_ids[]; static int __devinit fsl_of_msi_probe(struct platform_device *dev) { - const struct of_device_id *match; struct fsl_msi *msi; struct resource res; int err, i, j, irq_index, count; @@ -318,10 +316,9 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) u32 offset; static const u32 all_avail[] = { 0, NR_MSI_IRQS }; - match = of_match_device(fsl_of_msi_ids, &dev->dev); - if (!match) + if (!dev->dev.of_match) return -EINVAL; - features = match->data; + features = dev->dev.of_match->data; printk(KERN_DEBUG "Setting up Freescale MSI support\n"); diff --git a/trunk/arch/sparc/kernel/pci_sabre.c b/trunk/arch/sparc/kernel/pci_sabre.c index d1840dbdaa2f..948068a083fc 100644 --- a/trunk/arch/sparc/kernel/pci_sabre.c +++ b/trunk/arch/sparc/kernel/pci_sabre.c @@ -452,10 +452,8 @@ static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm, sabre_scan_bus(pbm, &op->dev); } -static const struct of_device_id sabre_match[]; static int __devinit sabre_probe(struct platform_device *op) { - const struct of_device_id *match; const struct linux_prom64_registers *pr_regs; struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; @@ -465,8 +463,7 @@ static int __devinit sabre_probe(struct platform_device *op) const u32 *vdma; u64 clear_irq; - match = of_match_device(sabre_match, &op->dev); - hummingbird_p = match && (match->data != NULL); + hummingbird_p = op->dev.of_match && (op->dev.of_match->data != NULL); if (!hummingbird_p) { struct device_node *cpu_dp; diff --git a/trunk/arch/sparc/kernel/pci_schizo.c b/trunk/arch/sparc/kernel/pci_schizo.c index 283fbc329a43..fecfcb2063c8 100644 --- a/trunk/arch/sparc/kernel/pci_schizo.c +++ b/trunk/arch/sparc/kernel/pci_schizo.c @@ -1458,15 +1458,11 @@ static int __devinit __schizo_init(struct platform_device *op, unsigned long chi return err; } -static const struct of_device_id schizo_match[]; static int __devinit schizo_probe(struct platform_device *op) { - const struct of_device_id *match; - - match = of_match_device(schizo_match, &op->dev); - if (!match) + if (!op->dev.of_match) return -EINVAL; - return __schizo_init(op, (unsigned long)match->data); + return __schizo_init(op, (unsigned long) op->dev.of_match->data); } /* The ordering of this table is very important. Some Tomatillo diff --git a/trunk/block/blk-cgroup.c b/trunk/block/blk-cgroup.c index e41cc6f2ccc1..471fdcc5df85 100644 --- a/trunk/block/blk-cgroup.c +++ b/trunk/block/blk-cgroup.c @@ -385,40 +385,25 @@ void blkiocg_update_timeslice_used(struct blkio_group *blkg, unsigned long time, spin_lock_irqsave(&blkg->stats_lock, flags); blkg->stats.time += time; -#ifdef CONFIG_DEBUG_BLK_CGROUP blkg->stats.unaccounted_time += unaccounted_time; -#endif spin_unlock_irqrestore(&blkg->stats_lock, flags); } EXPORT_SYMBOL_GPL(blkiocg_update_timeslice_used); -/* - * should be called under rcu read lock or queue lock to make sure blkg pointer - * is valid. - */ void blkiocg_update_dispatch_stats(struct blkio_group *blkg, uint64_t bytes, bool direction, bool sync) { - struct blkio_group_stats_cpu *stats_cpu; + struct blkio_group_stats *stats; unsigned long flags; - /* - * Disabling interrupts to provide mutual exclusion between two - * writes on same cpu. It probably is not needed for 64bit. Not - * optimizing that case yet. - */ - local_irq_save(flags); - - stats_cpu = this_cpu_ptr(blkg->stats_cpu); - - u64_stats_update_begin(&stats_cpu->syncp); - stats_cpu->sectors += bytes >> 9; - blkio_add_stat(stats_cpu->stat_arr_cpu[BLKIO_STAT_CPU_SERVICED], - 1, direction, sync); - blkio_add_stat(stats_cpu->stat_arr_cpu[BLKIO_STAT_CPU_SERVICE_BYTES], - bytes, direction, sync); - u64_stats_update_end(&stats_cpu->syncp); - local_irq_restore(flags); + spin_lock_irqsave(&blkg->stats_lock, flags); + stats = &blkg->stats; + stats->sectors += bytes >> 9; + blkio_add_stat(stats->stat_arr[BLKIO_STAT_SERVICED], 1, direction, + sync); + blkio_add_stat(stats->stat_arr[BLKIO_STAT_SERVICE_BYTES], bytes, + direction, sync); + spin_unlock_irqrestore(&blkg->stats_lock, flags); } EXPORT_SYMBOL_GPL(blkiocg_update_dispatch_stats); @@ -453,20 +438,6 @@ void blkiocg_update_io_merged_stats(struct blkio_group *blkg, bool direction, } EXPORT_SYMBOL_GPL(blkiocg_update_io_merged_stats); -/* - * This function allocates the per cpu stats for blkio_group. Should be called - * from sleepable context as alloc_per_cpu() requires that. - */ -int blkio_alloc_blkg_stats(struct blkio_group *blkg) -{ - /* Allocate memory for per cpu stats */ - blkg->stats_cpu = alloc_percpu(struct blkio_group_stats_cpu); - if (!blkg->stats_cpu) - return -ENOMEM; - return 0; -} -EXPORT_SYMBOL_GPL(blkio_alloc_blkg_stats); - void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, struct blkio_group *blkg, void *key, dev_t dev, enum blkio_policy_id plid) @@ -537,30 +508,6 @@ struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key) } EXPORT_SYMBOL_GPL(blkiocg_lookup_group); -static void blkio_reset_stats_cpu(struct blkio_group *blkg) -{ - struct blkio_group_stats_cpu *stats_cpu; - int i, j, k; - /* - * Note: On 64 bit arch this should not be an issue. This has the - * possibility of returning some inconsistent value on 32bit arch - * as 64bit update on 32bit is non atomic. Taking care of this - * corner case makes code very complicated, like sending IPIs to - * cpus, taking care of stats of offline cpus etc. - * - * reset stats is anyway more of a debug feature and this sounds a - * corner case. So I am not complicating the code yet until and - * unless this becomes a real issue. - */ - for_each_possible_cpu(i) { - stats_cpu = per_cpu_ptr(blkg->stats_cpu, i); - stats_cpu->sectors = 0; - for(j = 0; j < BLKIO_STAT_CPU_NR; j++) - for (k = 0; k < BLKIO_STAT_TOTAL; k++) - stats_cpu->stat_arr_cpu[j][k] = 0; - } -} - static int blkiocg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, u64 val) { @@ -605,11 +552,7 @@ blkiocg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, u64 val) } #endif spin_unlock(&blkg->stats_lock); - - /* Reset Per cpu stats which don't take blkg->stats_lock */ - blkio_reset_stats_cpu(blkg); } - spin_unlock_irq(&blkcg->lock); return 0; } @@ -655,59 +598,6 @@ static uint64_t blkio_fill_stat(char *str, int chars_left, uint64_t val, return val; } - -static uint64_t blkio_read_stat_cpu(struct blkio_group *blkg, - enum stat_type_cpu type, enum stat_sub_type sub_type) -{ - int cpu; - struct blkio_group_stats_cpu *stats_cpu; - u64 val = 0, tval; - - for_each_possible_cpu(cpu) { - unsigned int start; - stats_cpu = per_cpu_ptr(blkg->stats_cpu, cpu); - - do { - start = u64_stats_fetch_begin(&stats_cpu->syncp); - if (type == BLKIO_STAT_CPU_SECTORS) - tval = stats_cpu->sectors; - else - tval = stats_cpu->stat_arr_cpu[type][sub_type]; - } while(u64_stats_fetch_retry(&stats_cpu->syncp, start)); - - val += tval; - } - - return val; -} - -static uint64_t blkio_get_stat_cpu(struct blkio_group *blkg, - struct cgroup_map_cb *cb, dev_t dev, enum stat_type_cpu type) -{ - uint64_t disk_total, val; - char key_str[MAX_KEY_LEN]; - enum stat_sub_type sub_type; - - if (type == BLKIO_STAT_CPU_SECTORS) { - val = blkio_read_stat_cpu(blkg, type, 0); - return blkio_fill_stat(key_str, MAX_KEY_LEN - 1, val, cb, dev); - } - - for (sub_type = BLKIO_STAT_READ; sub_type < BLKIO_STAT_TOTAL; - sub_type++) { - blkio_get_key_name(sub_type, dev, key_str, MAX_KEY_LEN, false); - val = blkio_read_stat_cpu(blkg, type, sub_type); - cb->fill(cb, key_str, val); - } - - disk_total = blkio_read_stat_cpu(blkg, type, BLKIO_STAT_READ) + - blkio_read_stat_cpu(blkg, type, BLKIO_STAT_WRITE); - - blkio_get_key_name(BLKIO_STAT_TOTAL, dev, key_str, MAX_KEY_LEN, false); - cb->fill(cb, key_str, disk_total); - return disk_total; -} - /* This should be called with blkg->stats_lock held */ static uint64_t blkio_get_stat(struct blkio_group *blkg, struct cgroup_map_cb *cb, dev_t dev, enum stat_type type) @@ -719,6 +609,9 @@ static uint64_t blkio_get_stat(struct blkio_group *blkg, if (type == BLKIO_STAT_TIME) return blkio_fill_stat(key_str, MAX_KEY_LEN - 1, blkg->stats.time, cb, dev); + if (type == BLKIO_STAT_SECTORS) + return blkio_fill_stat(key_str, MAX_KEY_LEN - 1, + blkg->stats.sectors, cb, dev); #ifdef CONFIG_DEBUG_BLK_CGROUP if (type == BLKIO_STAT_UNACCOUNTED_TIME) return blkio_fill_stat(key_str, MAX_KEY_LEN - 1, @@ -1182,8 +1075,8 @@ static int blkiocg_file_read(struct cgroup *cgrp, struct cftype *cft, } static int blkio_read_blkg_stats(struct blkio_cgroup *blkcg, - struct cftype *cft, struct cgroup_map_cb *cb, - enum stat_type type, bool show_total, bool pcpu) + struct cftype *cft, struct cgroup_map_cb *cb, enum stat_type type, + bool show_total) { struct blkio_group *blkg; struct hlist_node *n; @@ -1194,15 +1087,10 @@ static int blkio_read_blkg_stats(struct blkio_cgroup *blkcg, if (blkg->dev) { if (!cftype_blkg_same_policy(cft, blkg)) continue; - if (pcpu) - cgroup_total += blkio_get_stat_cpu(blkg, cb, - blkg->dev, type); - else { - spin_lock_irq(&blkg->stats_lock); - cgroup_total += blkio_get_stat(blkg, cb, - blkg->dev, type); - spin_unlock_irq(&blkg->stats_lock); - } + spin_lock_irq(&blkg->stats_lock); + cgroup_total += blkio_get_stat(blkg, cb, blkg->dev, + type); + spin_unlock_irq(&blkg->stats_lock); } } if (show_total) @@ -1226,47 +1114,47 @@ static int blkiocg_file_read_map(struct cgroup *cgrp, struct cftype *cft, switch(name) { case BLKIO_PROP_time: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_TIME, 0, 0); + BLKIO_STAT_TIME, 0); case BLKIO_PROP_sectors: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_CPU_SECTORS, 0, 1); + BLKIO_STAT_SECTORS, 0); case BLKIO_PROP_io_service_bytes: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_CPU_SERVICE_BYTES, 1, 1); + BLKIO_STAT_SERVICE_BYTES, 1); case BLKIO_PROP_io_serviced: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_CPU_SERVICED, 1, 1); + BLKIO_STAT_SERVICED, 1); case BLKIO_PROP_io_service_time: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_SERVICE_TIME, 1, 0); + BLKIO_STAT_SERVICE_TIME, 1); case BLKIO_PROP_io_wait_time: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_WAIT_TIME, 1, 0); + BLKIO_STAT_WAIT_TIME, 1); case BLKIO_PROP_io_merged: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_MERGED, 1, 0); + BLKIO_STAT_MERGED, 1); case BLKIO_PROP_io_queued: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_QUEUED, 1, 0); + BLKIO_STAT_QUEUED, 1); #ifdef CONFIG_DEBUG_BLK_CGROUP case BLKIO_PROP_unaccounted_time: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_UNACCOUNTED_TIME, 0, 0); + BLKIO_STAT_UNACCOUNTED_TIME, 0); case BLKIO_PROP_dequeue: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_DEQUEUE, 0, 0); + BLKIO_STAT_DEQUEUE, 0); case BLKIO_PROP_avg_queue_size: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_AVG_QUEUE_SIZE, 0, 0); + BLKIO_STAT_AVG_QUEUE_SIZE, 0); case BLKIO_PROP_group_wait_time: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_GROUP_WAIT_TIME, 0, 0); + BLKIO_STAT_GROUP_WAIT_TIME, 0); case BLKIO_PROP_idle_time: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_IDLE_TIME, 0, 0); + BLKIO_STAT_IDLE_TIME, 0); case BLKIO_PROP_empty_time: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_EMPTY_TIME, 0, 0); + BLKIO_STAT_EMPTY_TIME, 0); #endif default: BUG(); @@ -1276,10 +1164,10 @@ static int blkiocg_file_read_map(struct cgroup *cgrp, struct cftype *cft, switch(name){ case BLKIO_THROTL_io_service_bytes: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_CPU_SERVICE_BYTES, 1, 1); + BLKIO_STAT_SERVICE_BYTES, 1); case BLKIO_THROTL_io_serviced: return blkio_read_blkg_stats(blkcg, cft, cb, - BLKIO_STAT_CPU_SERVICED, 1, 1); + BLKIO_STAT_SERVICED, 1); default: BUG(); } diff --git a/trunk/block/blk-cgroup.h b/trunk/block/blk-cgroup.h index 262226798093..c774930cc206 100644 --- a/trunk/block/blk-cgroup.h +++ b/trunk/block/blk-cgroup.h @@ -14,7 +14,6 @@ */ #include -#include enum blkio_policy_id { BLKIO_POLICY_PROP = 0, /* Proportional Bandwidth division */ @@ -37,6 +36,10 @@ enum stat_type { * request completion for IOs doen by this cgroup. This may not be * accurate when NCQ is turned on. */ BLKIO_STAT_SERVICE_TIME = 0, + /* Total bytes transferred */ + BLKIO_STAT_SERVICE_BYTES, + /* Total IOs serviced, post merge */ + BLKIO_STAT_SERVICED, /* Total time spent waiting in scheduler queue in ns */ BLKIO_STAT_WAIT_TIME, /* Number of IOs merged */ @@ -45,9 +48,10 @@ enum stat_type { BLKIO_STAT_QUEUED, /* All the single valued stats go below this */ BLKIO_STAT_TIME, -#ifdef CONFIG_DEBUG_BLK_CGROUP + BLKIO_STAT_SECTORS, /* Time not charged to this cgroup */ BLKIO_STAT_UNACCOUNTED_TIME, +#ifdef CONFIG_DEBUG_BLK_CGROUP BLKIO_STAT_AVG_QUEUE_SIZE, BLKIO_STAT_IDLE_TIME, BLKIO_STAT_EMPTY_TIME, @@ -56,16 +60,6 @@ enum stat_type { #endif }; -/* Per cpu stats */ -enum stat_type_cpu { - BLKIO_STAT_CPU_SECTORS, - /* Total bytes transferred */ - BLKIO_STAT_CPU_SERVICE_BYTES, - /* Total IOs serviced, post merge */ - BLKIO_STAT_CPU_SERVICED, - BLKIO_STAT_CPU_NR -}; - enum stat_sub_type { BLKIO_STAT_READ = 0, BLKIO_STAT_WRITE, @@ -122,11 +116,11 @@ struct blkio_cgroup { struct blkio_group_stats { /* total disk time and nr sectors dispatched by this group */ uint64_t time; - uint64_t stat_arr[BLKIO_STAT_QUEUED + 1][BLKIO_STAT_TOTAL]; -#ifdef CONFIG_DEBUG_BLK_CGROUP + uint64_t sectors; /* Time not charged to this cgroup */ uint64_t unaccounted_time; - + uint64_t stat_arr[BLKIO_STAT_QUEUED + 1][BLKIO_STAT_TOTAL]; +#ifdef CONFIG_DEBUG_BLK_CGROUP /* Sum of number of IOs queued across all samples */ uint64_t avg_queue_size_sum; /* Count of samples taken for average */ @@ -151,13 +145,6 @@ struct blkio_group_stats { #endif }; -/* Per cpu blkio group stats */ -struct blkio_group_stats_cpu { - uint64_t sectors; - uint64_t stat_arr_cpu[BLKIO_STAT_CPU_NR][BLKIO_STAT_TOTAL]; - struct u64_stats_sync syncp; -}; - struct blkio_group { /* An rcu protected unique identifier for the group */ void *key; @@ -173,8 +160,6 @@ struct blkio_group { /* Need to serialize the stats in the case of reset/update */ spinlock_t stats_lock; struct blkio_group_stats stats; - /* Per cpu stats pointer */ - struct blkio_group_stats_cpu __percpu *stats_cpu; }; struct blkio_policy_node { @@ -310,7 +295,6 @@ extern struct blkio_cgroup *task_blkio_cgroup(struct task_struct *tsk); extern void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, struct blkio_group *blkg, void *key, dev_t dev, enum blkio_policy_id plid); -extern int blkio_alloc_blkg_stats(struct blkio_group *blkg); extern int blkiocg_del_blkio_group(struct blkio_group *blkg); extern struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg, void *key); @@ -338,8 +322,6 @@ static inline void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, struct blkio_group *blkg, void *key, dev_t dev, enum blkio_policy_id plid) {} -static inline int blkio_alloc_blkg_stats(struct blkio_group *blkg) { return 0; } - static inline int blkiocg_del_blkio_group(struct blkio_group *blkg) { return 0; } diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 9e8e297374b9..3fe00a14822a 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -1550,8 +1550,7 @@ static inline void __generic_make_request(struct bio *bio) goto end_io; } - if (blk_throtl_bio(q, &bio)) - goto end_io; + blk_throtl_bio(q, &bio); /* * If bio = NULL, bio has been throttled and will be submitted diff --git a/trunk/block/blk-exec.c b/trunk/block/blk-exec.c index 8a0e7ec056e7..81e31819a597 100644 --- a/trunk/block/blk-exec.c +++ b/trunk/block/blk-exec.c @@ -56,7 +56,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, spin_lock_irq(q->queue_lock); __elv_add_request(q, rq, where); __blk_run_queue(q); - /* the queue is stopped so it won't be run */ + /* the queue is stopped so it won't be plugged+unplugged */ if (rq->cmd_type == REQ_TYPE_PM_RESUME) q->request_fn(q); spin_unlock_irq(q->queue_lock); diff --git a/trunk/block/blk-flush.c b/trunk/block/blk-flush.c index bb21e4c36f70..6c9b5e189e62 100644 --- a/trunk/block/blk-flush.c +++ b/trunk/block/blk-flush.c @@ -212,19 +212,13 @@ static void flush_end_io(struct request *flush_rq, int error) } /* - * Kick the queue to avoid stall for two cases: - * 1. Moving a request silently to empty queue_head may stall the - * queue. - * 2. When flush request is running in non-queueable queue, the - * queue is hold. Restart the queue after flush request is finished - * to avoid stall. - * This function is called from request completion path and calling - * directly into request_fn may confuse the driver. Always use - * kblockd. + * Moving a request silently to empty queue_head may stall the + * queue. Kick the queue in those cases. This function is called + * from request completion path and calling directly into + * request_fn may confuse the driver. Always use kblockd. */ - if (queued || q->flush_queue_delayed) + if (queued) blk_run_queue_async(q); - q->flush_queue_delayed = 0; } /** diff --git a/trunk/block/blk-lib.c b/trunk/block/blk-lib.c index 78e627e2581d..25de73e4759b 100644 --- a/trunk/block/blk-lib.c +++ b/trunk/block/blk-lib.c @@ -9,20 +9,17 @@ #include "blk.h" -struct bio_batch { - atomic_t done; - unsigned long flags; - struct completion *wait; -}; - -static void bio_batch_end_io(struct bio *bio, int err) +static void blkdev_discard_end_io(struct bio *bio, int err) { - struct bio_batch *bb = bio->bi_private; + if (err) { + if (err == -EOPNOTSUPP) + set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); + clear_bit(BIO_UPTODATE, &bio->bi_flags); + } + + if (bio->bi_private) + complete(bio->bi_private); - if (err && (err != -EOPNOTSUPP)) - clear_bit(BIO_UPTODATE, &bb->flags); - if (atomic_dec_and_test(&bb->done)) - complete(bb->wait); bio_put(bio); } @@ -44,7 +41,6 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, struct request_queue *q = bdev_get_queue(bdev); int type = REQ_WRITE | REQ_DISCARD; unsigned int max_discard_sectors; - struct bio_batch bb; struct bio *bio; int ret = 0; @@ -71,11 +67,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, type |= REQ_SECURE; } - atomic_set(&bb.done, 1); - bb.flags = 1 << BIO_UPTODATE; - bb.wait = &wait; - - while (nr_sects) { + while (nr_sects && !ret) { bio = bio_alloc(gfp_mask, 1); if (!bio) { ret = -ENOMEM; @@ -83,9 +75,9 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, } bio->bi_sector = sector; - bio->bi_end_io = bio_batch_end_io; + bio->bi_end_io = blkdev_discard_end_io; bio->bi_bdev = bdev; - bio->bi_private = &bb; + bio->bi_private = &wait; if (nr_sects > max_discard_sectors) { bio->bi_size = max_discard_sectors << 9; @@ -96,21 +88,45 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, nr_sects = 0; } - atomic_inc(&bb.done); + bio_get(bio); submit_bio(type, bio); - } - /* Wait for bios in-flight */ - if (!atomic_dec_and_test(&bb.done)) wait_for_completion(&wait); - if (!test_bit(BIO_UPTODATE, &bb.flags)) - ret = -EIO; + if (bio_flagged(bio, BIO_EOPNOTSUPP)) + ret = -EOPNOTSUPP; + else if (!bio_flagged(bio, BIO_UPTODATE)) + ret = -EIO; + bio_put(bio); + } return ret; } EXPORT_SYMBOL(blkdev_issue_discard); +struct bio_batch +{ + atomic_t done; + unsigned long flags; + struct completion *wait; +}; + +static void bio_batch_end_io(struct bio *bio, int err) +{ + struct bio_batch *bb = bio->bi_private; + + if (err) { + if (err == -EOPNOTSUPP) + set_bit(BIO_EOPNOTSUPP, &bb->flags); + else + clear_bit(BIO_UPTODATE, &bb->flags); + } + if (bb) + if (atomic_dec_and_test(&bb->done)) + complete(bb->wait); + bio_put(bio); +} + /** * blkdev_issue_zeroout - generate number of zero filed write bios * @bdev: blockdev to issue @@ -135,6 +151,7 @@ int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, bb.flags = 1 << BIO_UPTODATE; bb.wait = &wait; +submit: ret = 0; while (nr_sects != 0) { bio = bio_alloc(gfp_mask, @@ -151,6 +168,9 @@ int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, while (nr_sects != 0) { sz = min((sector_t) PAGE_SIZE >> 9 , nr_sects); + if (sz == 0) + /* bio has maximum size possible */ + break; ret = bio_add_page(bio, ZERO_PAGE(0), sz << 9, 0); nr_sects -= ret >> 9; sector += ret >> 9; @@ -170,6 +190,16 @@ int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, /* One of bios in the batch was completed with error.*/ ret = -EIO; + if (ret) + goto out; + + if (test_bit(BIO_EOPNOTSUPP, &bb.flags)) { + ret = -EOPNOTSUPP; + goto out; + } + if (nr_sects != 0) + goto submit; +out: return ret; } EXPORT_SYMBOL(blkdev_issue_zeroout); diff --git a/trunk/block/blk-settings.c b/trunk/block/blk-settings.c index fa1eb0449a05..1fa769293597 100644 --- a/trunk/block/blk-settings.c +++ b/trunk/block/blk-settings.c @@ -120,7 +120,7 @@ void blk_set_default_limits(struct queue_limits *lim) lim->discard_granularity = 0; lim->discard_alignment = 0; lim->discard_misaligned = 0; - lim->discard_zeroes_data = 1; + lim->discard_zeroes_data = -1; lim->logical_block_size = lim->physical_block_size = lim->io_min = 512; lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT); lim->alignment_offset = 0; @@ -166,7 +166,6 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) blk_set_default_limits(&q->limits); blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS); - q->limits.discard_zeroes_data = 0; /* * by default assume old behaviour and bounce for any highmem page @@ -791,12 +790,6 @@ void blk_queue_flush(struct request_queue *q, unsigned int flush) } EXPORT_SYMBOL_GPL(blk_queue_flush); -void blk_queue_flush_queueable(struct request_queue *q, bool queueable) -{ - q->flush_not_queueable = !queueable; -} -EXPORT_SYMBOL_GPL(blk_queue_flush_queueable); - static int __init blk_settings_init(void) { blk_max_low_pfn = max_low_pfn - 1; diff --git a/trunk/block/blk-sysfs.c b/trunk/block/blk-sysfs.c index d935bd859c87..bd236313f35d 100644 --- a/trunk/block/blk-sysfs.c +++ b/trunk/block/blk-sysfs.c @@ -152,8 +152,7 @@ static ssize_t queue_discard_granularity_show(struct request_queue *q, char *pag static ssize_t queue_discard_max_show(struct request_queue *q, char *page) { - return sprintf(page, "%llu\n", - (unsigned long long)q->limits.max_discard_sectors << 9); + return queue_var_show(q->limits.max_discard_sectors << 9, page); } static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page) diff --git a/trunk/block/blk-throttle.c b/trunk/block/blk-throttle.c index a62be8d0dc1b..252a81a306f7 100644 --- a/trunk/block/blk-throttle.c +++ b/trunk/block/blk-throttle.c @@ -78,8 +78,6 @@ struct throtl_grp { /* Some throttle limits got updated for the group */ int limits_changed; - - struct rcu_head rcu_head; }; struct throtl_data @@ -90,7 +88,7 @@ struct throtl_data /* service tree for active throtl groups */ struct throtl_rb_root tg_service_tree; - struct throtl_grp *root_tg; + struct throtl_grp root_tg; struct request_queue *queue; /* Total Number of queued bios on READ and WRITE lists */ @@ -153,44 +151,56 @@ static inline struct throtl_grp *throtl_ref_get_tg(struct throtl_grp *tg) return tg; } -static void throtl_free_tg(struct rcu_head *head) -{ - struct throtl_grp *tg; - - tg = container_of(head, struct throtl_grp, rcu_head); - free_percpu(tg->blkg.stats_cpu); - kfree(tg); -} - static void throtl_put_tg(struct throtl_grp *tg) { BUG_ON(atomic_read(&tg->ref) <= 0); if (!atomic_dec_and_test(&tg->ref)) return; + kfree(tg); +} + +static struct throtl_grp * throtl_find_alloc_tg(struct throtl_data *td, + struct blkio_cgroup *blkcg) +{ + struct throtl_grp *tg = NULL; + void *key = td; + struct backing_dev_info *bdi = &td->queue->backing_dev_info; + unsigned int major, minor; /* - * A group is freed in rcu manner. But having an rcu lock does not - * mean that one can access all the fields of blkg and assume these - * are valid. For example, don't try to follow throtl_data and - * request queue links. - * - * Having a reference to blkg under an rcu allows acess to only - * values local to groups like group stats and group rate limits + * TODO: Speed up blkiocg_lookup_group() by maintaining a radix + * tree of blkg (instead of traversing through hash list all + * the time. */ - call_rcu(&tg->rcu_head, throtl_free_tg); -} -static void throtl_init_group(struct throtl_grp *tg) -{ + /* + * This is the common case when there are no blkio cgroups. + * Avoid lookup in this case + */ + if (blkcg == &blkio_root_cgroup) + tg = &td->root_tg; + else + tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key)); + + /* Fill in device details for root group */ + if (tg && !tg->blkg.dev && bdi->dev && dev_name(bdi->dev)) { + sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor); + tg->blkg.dev = MKDEV(major, minor); + goto done; + } + + if (tg) + goto done; + + tg = kzalloc_node(sizeof(*tg), GFP_ATOMIC, td->queue->node); + if (!tg) + goto done; + INIT_HLIST_NODE(&tg->tg_node); RB_CLEAR_NODE(&tg->rb_node); bio_list_init(&tg->bio_lists[0]); bio_list_init(&tg->bio_lists[1]); - tg->limits_changed = false; - - /* Practically unlimited BW */ - tg->bps[0] = tg->bps[1] = -1; - tg->iops[0] = tg->iops[1] = -1; + td->limits_changed = false; /* * Take the initial reference that will be released on destroy @@ -199,181 +209,33 @@ static void throtl_init_group(struct throtl_grp *tg) * exit or cgroup deletion path depending on who is exiting first. */ atomic_set(&tg->ref, 1); -} - -/* Should be called with rcu read lock held (needed for blkcg) */ -static void -throtl_add_group_to_td_list(struct throtl_data *td, struct throtl_grp *tg) -{ - hlist_add_head(&tg->tg_node, &td->tg_list); - td->nr_undestroyed_grps++; -} - -static void -__throtl_tg_fill_dev_details(struct throtl_data *td, struct throtl_grp *tg) -{ - struct backing_dev_info *bdi = &td->queue->backing_dev_info; - unsigned int major, minor; - - if (!tg || tg->blkg.dev) - return; - - /* - * Fill in device details for a group which might not have been - * filled at group creation time as queue was being instantiated - * and driver had not attached a device yet - */ - if (bdi->dev && dev_name(bdi->dev)) { - sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor); - tg->blkg.dev = MKDEV(major, minor); - } -} - -/* - * Should be called with without queue lock held. Here queue lock will be - * taken rarely. It will be taken only once during life time of a group - * if need be - */ -static void -throtl_tg_fill_dev_details(struct throtl_data *td, struct throtl_grp *tg) -{ - if (!tg || tg->blkg.dev) - return; - - spin_lock_irq(td->queue->queue_lock); - __throtl_tg_fill_dev_details(td, tg); - spin_unlock_irq(td->queue->queue_lock); -} - -static void throtl_init_add_tg_lists(struct throtl_data *td, - struct throtl_grp *tg, struct blkio_cgroup *blkcg) -{ - __throtl_tg_fill_dev_details(td, tg); /* Add group onto cgroup list */ + sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor); blkiocg_add_blkio_group(blkcg, &tg->blkg, (void *)td, - tg->blkg.dev, BLKIO_POLICY_THROTL); + MKDEV(major, minor), BLKIO_POLICY_THROTL); tg->bps[READ] = blkcg_get_read_bps(blkcg, tg->blkg.dev); tg->bps[WRITE] = blkcg_get_write_bps(blkcg, tg->blkg.dev); tg->iops[READ] = blkcg_get_read_iops(blkcg, tg->blkg.dev); tg->iops[WRITE] = blkcg_get_write_iops(blkcg, tg->blkg.dev); - throtl_add_group_to_td_list(td, tg); -} - -/* Should be called without queue lock and outside of rcu period */ -static struct throtl_grp *throtl_alloc_tg(struct throtl_data *td) -{ - struct throtl_grp *tg = NULL; - int ret; - - tg = kzalloc_node(sizeof(*tg), GFP_ATOMIC, td->queue->node); - if (!tg) - return NULL; - - ret = blkio_alloc_blkg_stats(&tg->blkg); - - if (ret) { - kfree(tg); - return NULL; - } - - throtl_init_group(tg); - return tg; -} - -static struct -throtl_grp *throtl_find_tg(struct throtl_data *td, struct blkio_cgroup *blkcg) -{ - struct throtl_grp *tg = NULL; - void *key = td; - - /* - * This is the common case when there are no blkio cgroups. - * Avoid lookup in this case - */ - if (blkcg == &blkio_root_cgroup) - tg = td->root_tg; - else - tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key)); - - __throtl_tg_fill_dev_details(td, tg); + hlist_add_head(&tg->tg_node, &td->tg_list); + td->nr_undestroyed_grps++; +done: return tg; } -/* - * This function returns with queue lock unlocked in case of error, like - * request queue is no more - */ static struct throtl_grp * throtl_get_tg(struct throtl_data *td) { - struct throtl_grp *tg = NULL, *__tg = NULL; + struct throtl_grp *tg = NULL; struct blkio_cgroup *blkcg; - struct request_queue *q = td->queue; rcu_read_lock(); blkcg = task_blkio_cgroup(current); - tg = throtl_find_tg(td, blkcg); - if (tg) { - rcu_read_unlock(); - return tg; - } - - /* - * Need to allocate a group. Allocation of group also needs allocation - * of per cpu stats which in-turn takes a mutex() and can block. Hence - * we need to drop rcu lock and queue_lock before we call alloc - * - * Take the request queue reference to make sure queue does not - * go away once we return from allocation. - */ - blk_get_queue(q); - rcu_read_unlock(); - spin_unlock_irq(q->queue_lock); - - tg = throtl_alloc_tg(td); - /* - * We might have slept in group allocation. Make sure queue is not - * dead - */ - if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) { - blk_put_queue(q); - if (tg) - kfree(tg); - - return ERR_PTR(-ENODEV); - } - blk_put_queue(q); - - /* Group allocated and queue is still alive. take the lock */ - spin_lock_irq(q->queue_lock); - - /* - * Initialize the new group. After sleeping, read the blkcg again. - */ - rcu_read_lock(); - blkcg = task_blkio_cgroup(current); - - /* - * If some other thread already allocated the group while we were - * not holding queue lock, free up the group - */ - __tg = throtl_find_tg(td, blkcg); - - if (__tg) { - kfree(tg); - rcu_read_unlock(); - return __tg; - } - - /* Group allocation failed. Account the IO to root group */ - if (!tg) { - tg = td->root_tg; - return tg; - } - - throtl_init_add_tg_lists(td, tg, blkcg); + tg = throtl_find_alloc_tg(td, blkcg); + if (!tg) + tg = &td->root_tg; rcu_read_unlock(); return tg; } @@ -682,12 +544,6 @@ static bool tg_with_in_bps_limit(struct throtl_data *td, struct throtl_grp *tg, return 0; } -static bool tg_no_rule_group(struct throtl_grp *tg, bool rw) { - if (tg->bps[rw] == -1 && tg->iops[rw] == -1) - return 1; - return 0; -} - /* * Returns whether one can dispatch a bio or not. Also returns approx number * of jiffies to wait before this bio is with-in IO rate and can be dispatched @@ -752,6 +608,10 @@ static void throtl_charge_bio(struct throtl_grp *tg, struct bio *bio) tg->bytes_disp[rw] += bio->bi_size; tg->io_disp[rw]++; + /* + * TODO: This will take blkg->stats_lock. Figure out a way + * to avoid this cost. + */ blkiocg_update_dispatch_stats(&tg->blkg, bio->bi_size, rw, sync); } @@ -1129,51 +989,15 @@ int blk_throtl_bio(struct request_queue *q, struct bio **biop) struct throtl_grp *tg; struct bio *bio = *biop; bool rw = bio_data_dir(bio), update_disptime = true; - struct blkio_cgroup *blkcg; if (bio->bi_rw & REQ_THROTTLED) { bio->bi_rw &= ~REQ_THROTTLED; return 0; } - /* - * A throtl_grp pointer retrieved under rcu can be used to access - * basic fields like stats and io rates. If a group has no rules, - * just update the dispatch stats in lockless manner and return. - */ - - rcu_read_lock(); - blkcg = task_blkio_cgroup(current); - tg = throtl_find_tg(td, blkcg); - if (tg) { - throtl_tg_fill_dev_details(td, tg); - - if (tg_no_rule_group(tg, rw)) { - blkiocg_update_dispatch_stats(&tg->blkg, bio->bi_size, - rw, bio->bi_rw & REQ_SYNC); - rcu_read_unlock(); - return 0; - } - } - rcu_read_unlock(); - - /* - * Either group has not been allocated yet or it is not an unlimited - * IO group - */ - spin_lock_irq(q->queue_lock); tg = throtl_get_tg(td); - if (IS_ERR(tg)) { - if (PTR_ERR(tg) == -ENODEV) { - /* - * Queue is gone. No queue lock held here. - */ - return -ENODEV; - } - } - if (tg->nr_queued[rw]) { /* * There is already another bio queued in same dir. No @@ -1236,24 +1060,39 @@ int blk_throtl_init(struct request_queue *q) INIT_HLIST_HEAD(&td->tg_list); td->tg_service_tree = THROTL_RB_ROOT; td->limits_changed = false; - INIT_DELAYED_WORK(&td->throtl_work, blk_throtl_work); - /* alloc and Init root group. */ - td->queue = q; - tg = throtl_alloc_tg(td); + /* Init root group */ + tg = &td->root_tg; + INIT_HLIST_NODE(&tg->tg_node); + RB_CLEAR_NODE(&tg->rb_node); + bio_list_init(&tg->bio_lists[0]); + bio_list_init(&tg->bio_lists[1]); - if (!tg) { - kfree(td); - return -ENOMEM; - } + /* Practically unlimited BW */ + tg->bps[0] = tg->bps[1] = -1; + tg->iops[0] = tg->iops[1] = -1; + td->limits_changed = false; + + /* + * Set root group reference to 2. One reference will be dropped when + * all groups on tg_list are being deleted during queue exit. Other + * reference will remain there as we don't want to delete this group + * as it is statically allocated and gets destroyed when throtl_data + * goes away. + */ + atomic_set(&tg->ref, 2); + hlist_add_head(&tg->tg_node, &td->tg_list); + td->nr_undestroyed_grps++; - td->root_tg = tg; + INIT_DELAYED_WORK(&td->throtl_work, blk_throtl_work); rcu_read_lock(); - throtl_init_add_tg_lists(td, tg, &blkio_root_cgroup); + blkiocg_add_blkio_group(&blkio_root_cgroup, &tg->blkg, (void *)td, + 0, BLKIO_POLICY_THROTL); rcu_read_unlock(); /* Attach throtl data to request queue */ + td->queue = q; q->td = td; return 0; } diff --git a/trunk/block/blk.h b/trunk/block/blk.h index 1f798b5a6f19..4df474d37e6d 100644 --- a/trunk/block/blk.h +++ b/trunk/block/blk.h @@ -61,27 +61,9 @@ static inline struct request *__elv_next_request(struct request_queue *q) rq = list_entry_rq(q->queue_head.next); return rq; } - /* - * Flush request is running and flush request isn't queueable - * in the drive, we can hold the queue till flush request is - * finished. Even we don't do this, driver can't dispatch next - * requests and will requeue them. And this can improve - * throughput too. For example, we have request flush1, write1, - * flush 2. flush1 is dispatched, then queue is hold, write1 - * isn't inserted to queue. After flush1 is finished, flush2 - * will be dispatched. Since disk cache is already clean, - * flush2 will be finished very soon, so looks like flush2 is - * folded to flush1. - * Since the queue is hold, a flag is set to indicate the queue - * should be restarted later. Please see flush_end_io() for - * details. - */ - if (q->flush_pending_idx != q->flush_running_idx && - !queue_flush_queueable(q)) { - q->flush_queue_delayed = 1; - return NULL; - } - if (!q->elevator->ops->elevator_dispatch_fn(q, 0)) + + if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags) || + !q->elevator->ops->elevator_dispatch_fn(q, 0)) return NULL; } } diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index d646b279c8bb..ab7a9e6a9b1c 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -300,9 +300,7 @@ struct cfq_data { /* List of cfq groups being managed on this device*/ struct hlist_head cfqg_list; - - /* Number of groups which are on blkcg->blkg_list */ - unsigned int nr_blkcg_linked_grps; + struct rcu_head rcu; }; static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd); @@ -1016,47 +1014,28 @@ void cfq_update_blkio_group_weight(void *key, struct blkio_group *blkg, cfqg->needs_update = true; } -static void cfq_init_add_cfqg_lists(struct cfq_data *cfqd, - struct cfq_group *cfqg, struct blkio_cgroup *blkcg) +static struct cfq_group * cfq_find_alloc_cfqg(struct cfq_data *cfqd, + struct blkio_cgroup *blkcg, int create) { + struct cfq_group *cfqg = NULL; + void *key = cfqd; + int i, j; + struct cfq_rb_root *st; struct backing_dev_info *bdi = &cfqd->queue->backing_dev_info; unsigned int major, minor; - /* - * Add group onto cgroup list. It might happen that bdi->dev is - * not initialized yet. Initialize this new group without major - * and minor info and this info will be filled in once a new thread - * comes for IO. - */ - if (bdi->dev) { + cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key)); + if (cfqg && !cfqg->blkg.dev && bdi->dev && dev_name(bdi->dev)) { sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor); - cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, - (void *)cfqd, MKDEV(major, minor)); - } else - cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, - (void *)cfqd, 0); - - cfqd->nr_blkcg_linked_grps++; - cfqg->weight = blkcg_get_weight(blkcg, cfqg->blkg.dev); - - /* Add group on cfqd list */ - hlist_add_head(&cfqg->cfqd_node, &cfqd->cfqg_list); -} - -/* - * Should be called from sleepable context. No request queue lock as per - * cpu stats are allocated dynamically and alloc_percpu needs to be called - * from sleepable context. - */ -static struct cfq_group * cfq_alloc_cfqg(struct cfq_data *cfqd) -{ - struct cfq_group *cfqg = NULL; - int i, j, ret; - struct cfq_rb_root *st; + cfqg->blkg.dev = MKDEV(major, minor); + goto done; + } + if (cfqg || !create) + goto done; cfqg = kzalloc_node(sizeof(*cfqg), GFP_ATOMIC, cfqd->queue->node); if (!cfqg) - return NULL; + goto done; for_each_cfqg_st(cfqg, i, j, st) *st = CFQ_RB_ROOT; @@ -1070,94 +1049,43 @@ static struct cfq_group * cfq_alloc_cfqg(struct cfq_data *cfqd) */ cfqg->ref = 1; - ret = blkio_alloc_blkg_stats(&cfqg->blkg); - if (ret) { - kfree(cfqg); - return NULL; - } - - return cfqg; -} - -static struct cfq_group * -cfq_find_cfqg(struct cfq_data *cfqd, struct blkio_cgroup *blkcg) -{ - struct cfq_group *cfqg = NULL; - void *key = cfqd; - struct backing_dev_info *bdi = &cfqd->queue->backing_dev_info; - unsigned int major, minor; - /* - * This is the common case when there are no blkio cgroups. - * Avoid lookup in this case + * Add group onto cgroup list. It might happen that bdi->dev is + * not initialized yet. Initialize this new group without major + * and minor info and this info will be filled in once a new thread + * comes for IO. See code above. */ - if (blkcg == &blkio_root_cgroup) - cfqg = &cfqd->root_group; - else - cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key)); - - if (cfqg && !cfqg->blkg.dev && bdi->dev && dev_name(bdi->dev)) { + if (bdi->dev) { sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor); - cfqg->blkg.dev = MKDEV(major, minor); - } + cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd, + MKDEV(major, minor)); + } else + cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd, + 0); + cfqg->weight = blkcg_get_weight(blkcg, cfqg->blkg.dev); + + /* Add group on cfqd list */ + hlist_add_head(&cfqg->cfqd_node, &cfqd->cfqg_list); + +done: return cfqg; } /* - * Search for the cfq group current task belongs to. request_queue lock must - * be held. + * Search for the cfq group current task belongs to. If create = 1, then also + * create the cfq group if it does not exist. request_queue lock must be held. */ -static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd) +static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create) { struct blkio_cgroup *blkcg; - struct cfq_group *cfqg = NULL, *__cfqg = NULL; - struct request_queue *q = cfqd->queue; - - rcu_read_lock(); - blkcg = task_blkio_cgroup(current); - cfqg = cfq_find_cfqg(cfqd, blkcg); - if (cfqg) { - rcu_read_unlock(); - return cfqg; - } - - /* - * Need to allocate a group. Allocation of group also needs allocation - * of per cpu stats which in-turn takes a mutex() and can block. Hence - * we need to drop rcu lock and queue_lock before we call alloc. - * - * Not taking any queue reference here and assuming that queue is - * around by the time we return. CFQ queue allocation code does - * the same. It might be racy though. - */ - - rcu_read_unlock(); - spin_unlock_irq(q->queue_lock); - - cfqg = cfq_alloc_cfqg(cfqd); - - spin_lock_irq(q->queue_lock); + struct cfq_group *cfqg = NULL; rcu_read_lock(); blkcg = task_blkio_cgroup(current); - - /* - * If some other thread already allocated the group while we were - * not holding queue lock, free up the group - */ - __cfqg = cfq_find_cfqg(cfqd, blkcg); - - if (__cfqg) { - kfree(cfqg); - rcu_read_unlock(); - return __cfqg; - } - - if (!cfqg) + cfqg = cfq_find_alloc_cfqg(cfqd, blkcg, create); + if (!cfqg && create) cfqg = &cfqd->root_group; - - cfq_init_add_cfqg_lists(cfqd, cfqg, blkcg); rcu_read_unlock(); return cfqg; } @@ -1190,7 +1118,6 @@ static void cfq_put_cfqg(struct cfq_group *cfqg) return; for_each_cfqg_st(cfqg, i, j, st) BUG_ON(!RB_EMPTY_ROOT(&st->rb)); - free_percpu(cfqg->blkg.stats_cpu); kfree(cfqg); } @@ -1249,7 +1176,7 @@ void cfq_unlink_blkio_group(void *key, struct blkio_group *blkg) } #else /* GROUP_IOSCHED */ -static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd) +static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create) { return &cfqd->root_group; } @@ -2984,7 +2911,7 @@ cfq_find_alloc_queue(struct cfq_data *cfqd, bool is_sync, struct cfq_group *cfqg; retry: - cfqg = cfq_get_cfqg(cfqd); + cfqg = cfq_get_cfqg(cfqd, 1); cic = cfq_cic_lookup(cfqd, ioc); /* cic always exists here */ cfqq = cic_to_cfqq(cic, is_sync); @@ -3888,11 +3815,15 @@ static void cfq_put_async_queues(struct cfq_data *cfqd) cfq_put_queue(cfqd->async_idle_cfqq); } +static void cfq_cfqd_free(struct rcu_head *head) +{ + kfree(container_of(head, struct cfq_data, rcu)); +} + static void cfq_exit_queue(struct elevator_queue *e) { struct cfq_data *cfqd = e->elevator_data; struct request_queue *q = cfqd->queue; - bool wait = false; cfq_shutdown_timer_wq(cfqd); @@ -3911,13 +3842,7 @@ static void cfq_exit_queue(struct elevator_queue *e) cfq_put_async_queues(cfqd); cfq_release_cfq_groups(cfqd); - - /* - * If there are groups which we could not unlink from blkcg list, - * wait for a rcu period for them to be freed. - */ - if (cfqd->nr_blkcg_linked_grps) - wait = true; + cfq_blkiocg_del_blkio_group(&cfqd->root_group.blkg); spin_unlock_irq(q->queue_lock); @@ -3927,20 +3852,8 @@ static void cfq_exit_queue(struct elevator_queue *e) ida_remove(&cic_index_ida, cfqd->cic_index); spin_unlock(&cic_index_lock); - /* - * Wait for cfqg->blkg->key accessors to exit their grace periods. - * Do this wait only if there are other unlinked groups out - * there. This can happen if cgroup deletion path claimed the - * responsibility of cleaning up a group before queue cleanup code - * get to the group. - * - * Do not call synchronize_rcu() unconditionally as there are drivers - * which create/delete request queue hundreds of times during scan/boot - * and synchronize_rcu() can take significant time and slow down boot. - */ - if (wait) - synchronize_rcu(); - kfree(cfqd); + /* Wait for cfqg->blkg->key accessors to exit their grace periods. */ + call_rcu(&cfqd->rcu, cfq_cfqd_free); } static int cfq_alloc_cic_index(void) @@ -3996,29 +3909,14 @@ static void *cfq_init_queue(struct request_queue *q) #ifdef CONFIG_CFQ_GROUP_IOSCHED /* - * Set root group reference to 2. One reference will be dropped when - * all groups on cfqd->cfqg_list are being deleted during queue exit. - * Other reference will remain there as we don't want to delete this - * group as it is statically allocated and gets destroyed when - * throtl_data goes away. + * Take a reference to root group which we never drop. This is just + * to make sure that cfq_put_cfqg() does not try to kfree root group */ - cfqg->ref = 2; - - if (blkio_alloc_blkg_stats(&cfqg->blkg)) { - kfree(cfqg); - kfree(cfqd); - return NULL; - } - + cfqg->ref = 1; rcu_read_lock(); - cfq_blkiocg_add_blkio_group(&blkio_root_cgroup, &cfqg->blkg, (void *)cfqd, 0); rcu_read_unlock(); - cfqd->nr_blkcg_linked_grps++; - - /* Add group on cfqd->cfqg_list */ - hlist_add_head(&cfqg->cfqd_node, &cfqd->cfqg_list); #endif /* * Not strictly needed (since RB_ROOT just clears the node and we diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 2a0b653c90fd..45ca1e34f582 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -155,8 +155,13 @@ static struct elevator_type *elevator_get(const char *name) e = elevator_find(name); if (!e) { + char elv[ELV_NAME_MAX + strlen("-iosched")]; + spin_unlock(&elv_list_lock); - request_module("%s-iosched", name); + + snprintf(elv, sizeof(elv), "%s-iosched", name); + + request_module("%s", elv); spin_lock(&elv_list_lock); e = elevator_find(name); } diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index dad2c952e0d2..e2f57e9e12f0 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -1089,21 +1089,21 @@ static int atapi_drain_needed(struct request *rq) static int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) { - struct request_queue *q = sdev->request_queue; - if (!ata_id_has_unload(dev->id)) dev->flags |= ATA_DFLAG_NO_UNLOAD; /* configure max sectors */ - blk_queue_max_hw_sectors(q, dev->max_sectors); + blk_queue_max_hw_sectors(sdev->request_queue, dev->max_sectors); if (dev->class == ATA_DEV_ATAPI) { + struct request_queue *q = sdev->request_queue; void *buf; sdev->sector_size = ATA_SECT_SIZE; /* set DMA padding */ - blk_queue_update_dma_pad(q, ATA_DMA_PAD_SZ - 1); + blk_queue_update_dma_pad(sdev->request_queue, + ATA_DMA_PAD_SZ - 1); /* configure draining */ buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL); @@ -1131,7 +1131,8 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, "sector_size=%u > PAGE_SIZE, PIO may malfunction\n", sdev->sector_size); - blk_queue_update_dma_alignment(q, sdev->sector_size - 1); + blk_queue_update_dma_alignment(sdev->request_queue, + sdev->sector_size - 1); if (dev->flags & ATA_DFLAG_AN) set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events); @@ -1144,8 +1145,6 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth); } - blk_queue_flush_queueable(q, false); - dev->sdev = sdev; return 0; } diff --git a/trunk/drivers/atm/fore200e.c b/trunk/drivers/atm/fore200e.c index bc9e702186dd..bdd2719f3f68 100644 --- a/trunk/drivers/atm/fore200e.c +++ b/trunk/drivers/atm/fore200e.c @@ -2643,19 +2643,16 @@ fore200e_init(struct fore200e* fore200e, struct device *parent) } #ifdef CONFIG_SBUS -static const struct of_device_id fore200e_sba_match[]; static int __devinit fore200e_sba_probe(struct platform_device *op) { - const struct of_device_id *match; const struct fore200e_bus *bus; struct fore200e *fore200e; static int index = 0; int err; - match = of_match_device(fore200e_sba_match, &op->dev); - if (!match) + if (!op->dev.of_match) return -EINVAL; - bus = match->data; + bus = op->dev.of_match->data; fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL); if (!fore200e) diff --git a/trunk/drivers/block/paride/pcd.c b/trunk/drivers/block/paride/pcd.c index a0aabd904a51..8690e31d9932 100644 --- a/trunk/drivers/block/paride/pcd.c +++ b/trunk/drivers/block/paride/pcd.c @@ -320,8 +320,6 @@ static void pcd_init_units(void) disk->first_minor = unit; strcpy(disk->disk_name, cd->name); /* umm... */ disk->fops = &pcd_bdops; - disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; - disk->events = DISK_EVENT_MEDIA_CHANGE; } } diff --git a/trunk/drivers/cdrom/viocd.c b/trunk/drivers/cdrom/viocd.c index ae15a4ddaa9b..e427fbe45999 100644 --- a/trunk/drivers/cdrom/viocd.c +++ b/trunk/drivers/cdrom/viocd.c @@ -625,9 +625,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) blk_queue_max_hw_sectors(q, 4096 / 512); gendisk->queue = q; gendisk->fops = &viocd_fops; - gendisk->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE | - GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; - gendisk->events = DISK_EVENT_MEDIA_CHANGE; + gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE; set_capacity(gendisk, 0); gendisk->private_data = d; d->viocd_disk = gendisk; diff --git a/trunk/drivers/char/hw_random/n2-drv.c b/trunk/drivers/char/hw_random/n2-drv.c index ac6739e085e3..43ac61978d8b 100644 --- a/trunk/drivers/char/hw_random/n2-drv.c +++ b/trunk/drivers/char/hw_random/n2-drv.c @@ -619,18 +619,15 @@ static void __devinit n2rng_driver_version(void) pr_info("%s", version); } -static const struct of_device_id n2rng_match[]; static int __devinit n2rng_probe(struct platform_device *op) { - const struct of_device_id *match; int victoria_falls; int err = -ENOMEM; struct n2rng *np; - match = of_match_device(n2rng_match, &op->dev); - if (!match) + if (!op->dev.of_match) return -EINVAL; - victoria_falls = (match->data != NULL); + victoria_falls = (op->dev.of_match->data != NULL); n2rng_driver_version(); np = kzalloc(sizeof(*np), GFP_KERNEL); diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index 64c6b8530615..cc6c9b2546a3 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -2554,11 +2554,9 @@ static struct pci_driver ipmi_pci_driver = { }; #endif /* CONFIG_PCI */ -static struct of_device_id ipmi_match[]; static int __devinit ipmi_probe(struct platform_device *dev) { #ifdef CONFIG_OF - const struct of_device_id *match; struct smi_info *info; struct resource resource; const __be32 *regsize, *regspacing, *regshift; @@ -2568,8 +2566,7 @@ static int __devinit ipmi_probe(struct platform_device *dev) dev_info(&dev->dev, "probing via device tree\n"); - match = of_match_device(ipmi_match, &dev->dev); - if (!match) + if (!dev->dev.of_match) return -EINVAL; ret = of_address_to_resource(np, 0, &resource); @@ -2604,7 +2601,7 @@ static int __devinit ipmi_probe(struct platform_device *dev) return -ENOMEM; } - info->si_type = (enum si_type) match->data; + info->si_type = (enum si_type) dev->dev.of_match->data; info->addr_source = SI_DEVICETREE; info->irq_setup = std_irq_setup; diff --git a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 39ccdeada791..d6412c16385f 100644 --- a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -715,13 +715,13 @@ static int __devexit hwicap_remove(struct device *dev) } #ifdef CONFIG_OF -static int __devinit hwicap_of_probe(struct platform_device *op, - const struct hwicap_driver_config *config) +static int __devinit hwicap_of_probe(struct platform_device *op) { struct resource res; const unsigned int *id; const char *family; int rc; + const struct hwicap_driver_config *config = op->dev.of_match->data; const struct config_registers *regs; @@ -751,24 +751,20 @@ static int __devinit hwicap_of_probe(struct platform_device *op, regs); } #else -static inline int hwicap_of_probe(struct platform_device *op, - const struct hwicap_driver_config *config) +static inline int hwicap_of_probe(struct platform_device *op) { return -EINVAL; } #endif /* CONFIG_OF */ -static const struct of_device_id __devinitconst hwicap_of_match[]; static int __devinit hwicap_drv_probe(struct platform_device *pdev) { - const struct of_device_id *match; struct resource *res; const struct config_registers *regs; const char *family; - match = of_match_device(hwicap_of_match, &pdev->dev); - if (match) - return hwicap_of_probe(pdev, match->data); + if (pdev->dev.of_match) + return hwicap_of_probe(pdev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) diff --git a/trunk/drivers/edac/ppc4xx_edac.c b/trunk/drivers/edac/ppc4xx_edac.c index af8e7b1aa290..c1f0045ceb8e 100644 --- a/trunk/drivers/edac/ppc4xx_edac.c +++ b/trunk/drivers/edac/ppc4xx_edac.c @@ -1019,7 +1019,7 @@ ppc4xx_edac_mc_init(struct mem_ctl_info *mci, struct ppc4xx_edac_pdata *pdata = NULL; const struct device_node *np = op->dev.of_node; - if (of_match_device(ppc4xx_edac_match, &op->dev) == NULL) + if (op->dev.of_match == NULL) return -EINVAL; /* Initial driver pointers and private data */ diff --git a/trunk/drivers/i2c/busses/i2c-mpc.c b/trunk/drivers/i2c/busses/i2c-mpc.c index 107397a606b4..75b984c519ac 100644 --- a/trunk/drivers/i2c/busses/i2c-mpc.c +++ b/trunk/drivers/i2c/busses/i2c-mpc.c @@ -560,18 +560,15 @@ static struct i2c_adapter mpc_ops = { .timeout = HZ, }; -static const struct of_device_id mpc_i2c_of_match[]; static int __devinit fsl_i2c_probe(struct platform_device *op) { - const struct of_device_id *match; struct mpc_i2c *i2c; const u32 *prop; u32 clock = MPC_I2C_CLOCK_LEGACY; int result = 0; int plen; - match = of_match_device(mpc_i2c_of_match, &op->dev); - if (!match) + if (!op->dev.of_match) return -EINVAL; i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); @@ -608,8 +605,8 @@ static int __devinit fsl_i2c_probe(struct platform_device *op) clock = *prop; } - if (match->data) { - struct mpc_i2c_data *data = match->data; + if (op->dev.of_match->data) { + struct mpc_i2c_data *data = op->dev.of_match->data; data->setup(op->dev.of_node, i2c, clock, data->prescaler); } else { /* Backwards compatibility */ diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c index 6e5123b1d341..a5ec5a7cb381 100644 --- a/trunk/drivers/ide/ide-cd.c +++ b/trunk/drivers/ide/ide-cd.c @@ -1781,8 +1781,7 @@ static int ide_cd_probe(ide_drive_t *drive) ide_cd_read_toc(drive, &sense); g->fops = &idecd_ops; - g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; - g->events = DISK_EVENT_MEDIA_CHANGE; + g->flags |= GENHD_FL_REMOVABLE; add_disk(g); return 0; diff --git a/trunk/drivers/mmc/host/sdhci-of-core.c b/trunk/drivers/mmc/host/sdhci-of-core.c index 60e4186a4345..f9b611fc773e 100644 --- a/trunk/drivers/mmc/host/sdhci-of-core.c +++ b/trunk/drivers/mmc/host/sdhci-of-core.c @@ -124,10 +124,8 @@ static bool __devinit sdhci_of_wp_inverted(struct device_node *np) #endif } -static const struct of_device_id sdhci_of_match[]; static int __devinit sdhci_of_probe(struct platform_device *ofdev) { - const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct sdhci_of_data *sdhci_of_data; struct sdhci_host *host; @@ -136,10 +134,9 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev) int size; int ret; - match = of_match_device(sdhci_of_match, &ofdev->dev); - if (!match) + if (!ofdev->dev.of_match) return -EINVAL; - sdhci_of_data = match->data; + sdhci_of_data = ofdev->dev.of_match->data; if (!of_device_is_available(np)) return -ENODEV; diff --git a/trunk/drivers/mtd/maps/physmap_of.c b/trunk/drivers/mtd/maps/physmap_of.c index c1d33464aee8..bd483f0c57e1 100644 --- a/trunk/drivers/mtd/maps/physmap_of.c +++ b/trunk/drivers/mtd/maps/physmap_of.c @@ -214,13 +214,11 @@ static void __devinit of_free_probes(const char **probes) } #endif -static struct of_device_id of_flash_match[]; static int __devinit of_flash_probe(struct platform_device *dev) { #ifdef CONFIG_MTD_PARTITIONS const char **part_probe_types; #endif - const struct of_device_id *match; struct device_node *dp = dev->dev.of_node; struct resource res; struct of_flash *info; @@ -234,10 +232,9 @@ static int __devinit of_flash_probe(struct platform_device *dev) struct mtd_info **mtd_list = NULL; resource_size_t res_size; - match = of_match_device(of_flash_match, &dev->dev); - if (!match) + if (!dev->dev.of_match) return -EINVAL; - probe_type = match->data; + probe_type = dev->dev.of_match->data; reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32); diff --git a/trunk/drivers/net/can/mscan/mpc5xxx_can.c b/trunk/drivers/net/can/mscan/mpc5xxx_can.c index 5fedc3375562..bd1d811c204f 100644 --- a/trunk/drivers/net/can/mscan/mpc5xxx_can.c +++ b/trunk/drivers/net/can/mscan/mpc5xxx_can.c @@ -247,10 +247,8 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, } #endif /* CONFIG_PPC_MPC512x */ -static struct of_device_id mpc5xxx_can_table[]; static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) { - const struct of_device_id *match; struct mpc5xxx_can_data *data; struct device_node *np = ofdev->dev.of_node; struct net_device *dev; @@ -260,10 +258,9 @@ static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) int irq, mscan_clksrc = 0; int err = -ENOMEM; - match = of_match_device(mpc5xxx_can_table, &ofdev->dev); - if (!match) + if (!ofdev->dev.of_match) return -EINVAL; - data = match->data; + data = (struct mpc5xxx_can_data *)ofdev->dev.of_match->data; base = of_iomap(np, 0); if (!base) { diff --git a/trunk/drivers/net/fs_enet/fs_enet-main.c b/trunk/drivers/net/fs_enet/fs_enet-main.c index 5131e61c358c..24cb953900dd 100644 --- a/trunk/drivers/net/fs_enet/fs_enet-main.c +++ b/trunk/drivers/net/fs_enet/fs_enet-main.c @@ -998,10 +998,8 @@ static const struct net_device_ops fs_enet_netdev_ops = { #endif }; -static struct of_device_id fs_enet_match[]; static int __devinit fs_enet_probe(struct platform_device *ofdev) { - const struct of_device_id *match; struct net_device *ndev; struct fs_enet_private *fep; struct fs_platform_info *fpi; @@ -1009,15 +1007,14 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev) const u8 *mac_addr; int privsize, len, ret = -ENODEV; - match = of_match_device(fs_enet_match, &ofdev->dev); - if (!match) + if (!ofdev->dev.of_match) return -EINVAL; fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); if (!fpi) return -ENOMEM; - if (!IS_FEC(match)) { + if (!IS_FEC(ofdev->dev.of_match)) { data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) goto out_free_fpi; @@ -1052,7 +1049,7 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev) fep->dev = &ofdev->dev; fep->ndev = ndev; fep->fpi = fpi; - fep->ops = match->data; + fep->ops = ofdev->dev.of_match->data; ret = fep->ops->setup_data(ndev); if (ret) diff --git a/trunk/drivers/net/fs_enet/mii-fec.c b/trunk/drivers/net/fs_enet/mii-fec.c index 6a2e150e75bb..7e840d373ab3 100644 --- a/trunk/drivers/net/fs_enet/mii-fec.c +++ b/trunk/drivers/net/fs_enet/mii-fec.c @@ -101,20 +101,17 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus) return 0; } -static struct of_device_id fs_enet_mdio_fec_match[]; static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) { - const struct of_device_id *match; struct resource res; struct mii_bus *new_bus; struct fec_info *fec; int (*get_bus_freq)(struct device_node *); int ret = -ENOMEM, clock, speed; - match = of_match_device(fs_enet_mdio_fec_match, &ofdev->dev); - if (!match) + if (!ofdev->dev.of_match) return -EINVAL; - get_bus_freq = match->data; + get_bus_freq = ofdev->dev.of_match->data; new_bus = mdiobus_alloc(); if (!new_bus) diff --git a/trunk/drivers/net/sunhme.c b/trunk/drivers/net/sunhme.c index bff2f7999ff0..eb4f59fb01e9 100644 --- a/trunk/drivers/net/sunhme.c +++ b/trunk/drivers/net/sunhme.c @@ -3237,18 +3237,15 @@ static void happy_meal_pci_exit(void) #endif #ifdef CONFIG_SBUS -static const struct of_device_id hme_sbus_match[]; static int __devinit hme_sbus_probe(struct platform_device *op) { - const struct of_device_id *match; struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); int is_qfe; - match = of_match_device(hme_sbus_match, &op->dev); - if (!match) + if (!op->dev.of_match) return -EINVAL; - is_qfe = (match->data != NULL); + is_qfe = (op->dev.of_match->data != NULL); if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe")) is_qfe = 1; diff --git a/trunk/drivers/scsi/qlogicpti.c b/trunk/drivers/scsi/qlogicpti.c index 9689d41c7888..e2d45c91b8e8 100644 --- a/trunk/drivers/scsi/qlogicpti.c +++ b/trunk/drivers/scsi/qlogicpti.c @@ -1292,10 +1292,8 @@ static struct scsi_host_template qpti_template = { .use_clustering = ENABLE_CLUSTERING, }; -static const struct of_device_id qpti_match[]; static int __devinit qpti_sbus_probe(struct platform_device *op) { - const struct of_device_id *match; struct scsi_host_template *tpnt; struct device_node *dp = op->dev.of_node; struct Scsi_Host *host; @@ -1303,10 +1301,9 @@ static int __devinit qpti_sbus_probe(struct platform_device *op) static int nqptis; const char *fcode; - match = of_match_device(qpti_match, &op->dev); - if (!match) + if (!op->dev.of_match) return -EINVAL; - tpnt = match->data; + tpnt = op->dev.of_match->data; /* Sometimes Antares cards come up not completely * setup, and we get a report of a zero IRQ. diff --git a/trunk/drivers/scsi/sr.c b/trunk/drivers/scsi/sr.c index 4778e2707168..95019c747cc1 100644 --- a/trunk/drivers/scsi/sr.c +++ b/trunk/drivers/scsi/sr.c @@ -636,7 +636,7 @@ static int sr_probe(struct device *dev) disk->first_minor = minor; sprintf(disk->disk_name, "sr%d", minor); disk->fops = &sr_bdops; - disk->flags = GENHD_FL_CD | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; + disk->flags = GENHD_FL_CD; disk->events = DISK_EVENT_MEDIA_CHANGE | DISK_EVENT_EJECT_REQUEST; blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT); diff --git a/trunk/drivers/tty/serial/of_serial.c b/trunk/drivers/tty/serial/of_serial.c index c911b2419abb..0e8eec516df4 100644 --- a/trunk/drivers/tty/serial/of_serial.c +++ b/trunk/drivers/tty/serial/of_serial.c @@ -80,17 +80,14 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, /* * Try to register a serial port */ -static struct of_device_id of_platform_serial_table[]; static int __devinit of_platform_serial_probe(struct platform_device *ofdev) { - const struct of_device_id *match; struct of_serial_info *info; struct uart_port port; int port_type; int ret; - match = of_match_device(of_platform_serial_table, &ofdev->dev); - if (!match) + if (!ofdev->dev.of_match) return -EINVAL; if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) @@ -100,7 +97,7 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev) if (info == NULL) return -ENOMEM; - port_type = (unsigned long)match->data; + port_type = (unsigned long)ofdev->dev.of_match->data; ret = of_platform_serial_setup(ofdev, port_type, &port); if (ret) goto out; diff --git a/trunk/drivers/usb/gadget/fsl_qe_udc.c b/trunk/drivers/usb/gadget/fsl_qe_udc.c index 3a68e09309f7..36613b37c504 100644 --- a/trunk/drivers/usb/gadget/fsl_qe_udc.c +++ b/trunk/drivers/usb/gadget/fsl_qe_udc.c @@ -2539,18 +2539,15 @@ static void qe_udc_release(struct device *dev) } /* Driver probe functions */ -static const struct of_device_id qe_udc_match[]; static int __devinit qe_udc_probe(struct platform_device *ofdev) { - const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct qe_ep *ep; unsigned int ret = 0; unsigned int i; const void *prop; - match = of_match_device(qe_udc_match, &ofdev->dev); - if (!match) + if (!ofdev->dev.of_match) return -EINVAL; prop = of_get_property(np, "mode", NULL); @@ -2564,7 +2561,7 @@ static int __devinit qe_udc_probe(struct platform_device *ofdev) return -ENOMEM; } - udc_controller->soc_type = (unsigned long)match->data; + udc_controller->soc_type = (unsigned long)ofdev->dev.of_match->data; udc_controller->usb_regs = of_iomap(np, 0); if (!udc_controller->usb_regs) { ret = -ENOMEM; diff --git a/trunk/drivers/watchdog/mpc8xxx_wdt.c b/trunk/drivers/watchdog/mpc8xxx_wdt.c index eed5436ffb51..528bceb220fd 100644 --- a/trunk/drivers/watchdog/mpc8xxx_wdt.c +++ b/trunk/drivers/watchdog/mpc8xxx_wdt.c @@ -185,20 +185,17 @@ static struct miscdevice mpc8xxx_wdt_miscdev = { .fops = &mpc8xxx_wdt_fops, }; -static const struct of_device_id mpc8xxx_wdt_match[]; static int __devinit mpc8xxx_wdt_probe(struct platform_device *ofdev) { int ret; - const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct mpc8xxx_wdt_type *wdt_type; u32 freq = fsl_get_sys_freq(); bool enabled; - match = of_match_device(mpc8xxx_wdt_match, &ofdev->dev); - if (!match) + if (!ofdev->dev.of_match) return -EINVAL; - wdt_type = match->data; + wdt_type = ofdev->dev.of_match->data; if (!freq || freq == -1) return -EINVAL; diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index d7c2e0fddc6f..257b00e98428 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -1237,8 +1237,6 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) res = __blkdev_get(bdev, mode, 0); if (whole) { - struct gendisk *disk = whole->bd_disk; - /* finish claiming */ mutex_lock(&bdev->bd_mutex); spin_lock(&bdev_lock); @@ -1265,16 +1263,15 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) spin_unlock(&bdev_lock); /* - * Block event polling for write claims if requested. Any - * write holder makes the write_holder state stick until - * all are released. This is good enough and tracking - * individual writeable reference is too fragile given the - * way @mode is used in blkdev_get/put(). + * Block event polling for write claims. Any write + * holder makes the write_holder state stick until all + * are released. This is good enough and tracking + * individual writeable reference is too fragile given + * the way @mode is used in blkdev_get/put(). */ - if ((disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE) && - !res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) { + if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) { bdev->bd_write_holder = true; - disk_block_events(disk); + disk_block_events(bdev->bd_disk); } mutex_unlock(&bdev->bd_mutex); diff --git a/trunk/fs/configfs/dir.c b/trunk/fs/configfs/dir.c index 9a37a9b6de3a..3313dd19f543 100644 --- a/trunk/fs/configfs/dir.c +++ b/trunk/fs/configfs/dir.c @@ -53,14 +53,11 @@ DEFINE_SPINLOCK(configfs_dirent_lock); static void configfs_d_iput(struct dentry * dentry, struct inode * inode) { - struct configfs_dirent *sd = dentry->d_fsdata; + struct configfs_dirent * sd = dentry->d_fsdata; if (sd) { BUG_ON(sd->s_dentry != dentry); - /* Coordinate with configfs_readdir */ - spin_lock(&configfs_dirent_lock); sd->s_dentry = NULL; - spin_unlock(&configfs_dirent_lock); configfs_put(sd); } iput(inode); @@ -692,8 +689,7 @@ static int create_default_group(struct config_group *parent_group, sd = child->d_fsdata; sd->s_type |= CONFIGFS_USET_DEFAULT; } else { - BUG_ON(child->d_inode); - d_drop(child); + d_delete(child); dput(child); } } @@ -1549,7 +1545,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir struct configfs_dirent * parent_sd = dentry->d_fsdata; struct configfs_dirent *cursor = filp->private_data; struct list_head *p, *q = &cursor->s_sibling; - ino_t ino = 0; + ino_t ino; int i = filp->f_pos; switch (i) { @@ -1577,7 +1573,6 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir struct configfs_dirent *next; const char * name; int len; - struct inode *inode = NULL; next = list_entry(p, struct configfs_dirent, s_sibling); @@ -1586,28 +1581,9 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir name = configfs_get_name(next); len = strlen(name); - - /* - * We'll have a dentry and an inode for - * PINNED items and for open attribute - * files. We lock here to prevent a race - * with configfs_d_iput() clearing - * s_dentry before calling iput(). - * - * Why do we go to the trouble? If - * someone has an attribute file open, - * the inode number should match until - * they close it. Beyond that, we don't - * care. - */ - spin_lock(&configfs_dirent_lock); - dentry = next->s_dentry; - if (dentry) - inode = dentry->d_inode; - if (inode) - ino = inode->i_ino; - spin_unlock(&configfs_dirent_lock); - if (!inode) + if (next->s_dentry) + ino = next->s_dentry->d_inode->i_ino; + else ino = iunique(configfs_sb, 2); if (filldir(dirent, name, len, filp->f_pos, ino, @@ -1707,8 +1683,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) err = configfs_attach_group(sd->s_element, &group->cg_item, dentry); if (err) { - BUG_ON(dentry->d_inode); - d_drop(dentry); + d_delete(dentry); dput(dentry); } else { spin_lock(&configfs_dirent_lock); diff --git a/trunk/fs/ocfs2/cluster/heartbeat.c b/trunk/fs/ocfs2/cluster/heartbeat.c index 9a3e6bbff27b..643720209a98 100644 --- a/trunk/fs/ocfs2/cluster/heartbeat.c +++ b/trunk/fs/ocfs2/cluster/heartbeat.c @@ -539,41 +539,25 @@ static int o2hb_verify_crc(struct o2hb_region *reg, /* We want to make sure that nobody is heartbeating on top of us -- * this will help detect an invalid configuration. */ -static void o2hb_check_last_timestamp(struct o2hb_region *reg) +static int o2hb_check_last_timestamp(struct o2hb_region *reg) { + int node_num, ret; struct o2hb_disk_slot *slot; struct o2hb_disk_heartbeat_block *hb_block; - char *errstr; - slot = ®->hr_slots[o2nm_this_node()]; - /* Don't check on our 1st timestamp */ - if (!slot->ds_last_time) - return; - - hb_block = slot->ds_raw_block; - if (le64_to_cpu(hb_block->hb_seq) == slot->ds_last_time && - le64_to_cpu(hb_block->hb_generation) == slot->ds_last_generation && - hb_block->hb_node == slot->ds_node_num) - return; + node_num = o2nm_this_node(); -#define ERRSTR1 "Another node is heartbeating on device" -#define ERRSTR2 "Heartbeat generation mismatch on device" -#define ERRSTR3 "Heartbeat sequence mismatch on device" + ret = 1; + slot = ®->hr_slots[node_num]; + /* Don't check on our 1st timestamp */ + if (slot->ds_last_time) { + hb_block = slot->ds_raw_block; - if (hb_block->hb_node != slot->ds_node_num) - errstr = ERRSTR1; - else if (le64_to_cpu(hb_block->hb_generation) != - slot->ds_last_generation) - errstr = ERRSTR2; - else - errstr = ERRSTR3; + if (le64_to_cpu(hb_block->hb_seq) != slot->ds_last_time) + ret = 0; + } - mlog(ML_ERROR, "%s (%s): expected(%u:0x%llx, 0x%llx), " - "ondisk(%u:0x%llx, 0x%llx)\n", errstr, reg->hr_dev_name, - slot->ds_node_num, (unsigned long long)slot->ds_last_generation, - (unsigned long long)slot->ds_last_time, hb_block->hb_node, - (unsigned long long)le64_to_cpu(hb_block->hb_generation), - (unsigned long long)le64_to_cpu(hb_block->hb_seq)); + return ret; } static inline void o2hb_prepare_block(struct o2hb_region *reg, @@ -999,7 +983,9 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) /* With an up to date view of the slots, we can check that no * other node has been improperly configured to heartbeat in * our slot. */ - o2hb_check_last_timestamp(reg); + if (!o2hb_check_last_timestamp(reg)) + mlog(ML_ERROR, "Device \"%s\": another node is heartbeating " + "in our slot!\n", reg->hr_dev_name); /* fill in the proper info for our next heartbeat */ o2hb_prepare_block(reg, reg->hr_generation); @@ -1013,8 +999,8 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) } i = -1; - while((i = find_next_bit(configured_nodes, - O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) { + while((i = find_next_bit(configured_nodes, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) { + change |= o2hb_check_slot(reg, ®->hr_slots[i]); } @@ -1704,7 +1690,6 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, struct file *filp = NULL; struct inode *inode = NULL; ssize_t ret = -EINVAL; - int live_threshold; if (reg->hr_bdev) goto out; @@ -1781,18 +1766,8 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, * A node is considered live after it has beat LIVE_THRESHOLD * times. We're not steady until we've given them a chance * _after_ our first read. - * The default threshold is bare minimum so as to limit the delay - * during mounts. For global heartbeat, the threshold doubled for the - * first region. */ - live_threshold = O2HB_LIVE_THRESHOLD; - if (o2hb_global_heartbeat_active()) { - spin_lock(&o2hb_live_lock); - if (o2hb_pop_count(&o2hb_region_bitmap, O2NM_MAX_REGIONS) == 1) - live_threshold <<= 1; - spin_unlock(&o2hb_live_lock); - } - atomic_set(®->hr_steady_iterations, live_threshold + 1); + atomic_set(®->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1); hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", reg->hr_item.ci_name); diff --git a/trunk/fs/ocfs2/dir.c b/trunk/fs/ocfs2/dir.c index 8582e3f4f120..9fe5b8fd658f 100644 --- a/trunk/fs/ocfs2/dir.c +++ b/trunk/fs/ocfs2/dir.c @@ -2868,7 +2868,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh, bytes = blocks_wanted << sb->s_blocksize_bits; struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); struct ocfs2_inode_info *oi = OCFS2_I(dir); - struct ocfs2_alloc_context *data_ac = NULL; + struct ocfs2_alloc_context *data_ac; struct ocfs2_alloc_context *meta_ac = NULL; struct buffer_head *dirdata_bh = NULL; struct buffer_head *dx_root_bh = NULL; diff --git a/trunk/fs/ocfs2/dlm/dlmdomain.c b/trunk/fs/ocfs2/dlm/dlmdomain.c index 3b179d6cbde0..7540a492eaba 100644 --- a/trunk/fs/ocfs2/dlm/dlmdomain.c +++ b/trunk/fs/ocfs2/dlm/dlmdomain.c @@ -1614,8 +1614,7 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm) spin_unlock(&dlm->spinlock); /* Support for global heartbeat and node info was added in 1.1 */ - if (dlm->dlm_locking_proto.pv_major > 1 || - dlm->dlm_locking_proto.pv_minor > 0) { + if (dlm_protocol.pv_major > 1 || dlm_protocol.pv_minor > 0) { status = dlm_send_nodeinfo(dlm, ctxt->yes_resp_map); if (status) { mlog_errno(status); diff --git a/trunk/fs/ocfs2/dlm/dlmmaster.c b/trunk/fs/ocfs2/dlm/dlmmaster.c index 84d166328cf7..fede57ed005f 100644 --- a/trunk/fs/ocfs2/dlm/dlmmaster.c +++ b/trunk/fs/ocfs2/dlm/dlmmaster.c @@ -2574,9 +2574,6 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, res->state &= ~DLM_LOCK_RES_MIGRATING; wake = 1; spin_unlock(&res->spinlock); - if (dlm_is_host_down(ret)) - dlm_wait_for_node_death(dlm, target, - DLM_NODE_DEATH_WAIT_MAX); goto leave; } diff --git a/trunk/fs/ocfs2/file.c b/trunk/fs/ocfs2/file.c index 89659d6dc206..41565ae52856 100644 --- a/trunk/fs/ocfs2/file.c +++ b/trunk/fs/ocfs2/file.c @@ -1607,9 +1607,6 @@ static void ocfs2_calc_trunc_pos(struct inode *inode, range = le32_to_cpu(rec->e_cpos) + ocfs2_rec_clusters(el, rec); if (le32_to_cpu(rec->e_cpos) >= trunc_start) { - /* - * remove an entire extent record. - */ *trunc_cpos = le32_to_cpu(rec->e_cpos); /* * Skip holes if any. @@ -1620,16 +1617,7 @@ static void ocfs2_calc_trunc_pos(struct inode *inode, *blkno = le64_to_cpu(rec->e_blkno); *trunc_end = le32_to_cpu(rec->e_cpos); } else if (range > trunc_start) { - /* - * remove a partial extent record, which means we're - * removing the last extent record. - */ *trunc_cpos = trunc_start; - /* - * skip hole if any. - */ - if (range < *trunc_end) - *trunc_end = range; *trunc_len = *trunc_end - trunc_start; coff = trunc_start - le32_to_cpu(rec->e_cpos); *blkno = le64_to_cpu(rec->e_blkno) + diff --git a/trunk/fs/ocfs2/journal.c b/trunk/fs/ocfs2/journal.c index 295d56454e8b..b141a44605ca 100644 --- a/trunk/fs/ocfs2/journal.c +++ b/trunk/fs/ocfs2/journal.c @@ -1260,9 +1260,6 @@ void ocfs2_complete_mount_recovery(struct ocfs2_super *osb) { struct ocfs2_journal *journal = osb->journal; - if (ocfs2_is_hard_readonly(osb)) - return; - /* No need to queue up our truncate_log as regular cleanup will catch * that */ ocfs2_queue_recovery_completion(journal, osb->slot_num, diff --git a/trunk/fs/partitions/check.c b/trunk/fs/partitions/check.c index 8ed4d3433199..d545e97d99c3 100644 --- a/trunk/fs/partitions/check.c +++ b/trunk/fs/partitions/check.c @@ -255,11 +255,7 @@ ssize_t part_discard_alignment_show(struct device *dev, struct device_attribute *attr, char *buf) { struct hd_struct *p = dev_to_part(dev); - struct gendisk *disk = dev_to_disk(dev); - - return sprintf(buf, "%u\n", - queue_limit_discard_alignment(&disk->queue->limits, - p->start_sect)); + return sprintf(buf, "%u\n", p->discard_alignment); } ssize_t part_stat_show(struct device *dev, @@ -453,6 +449,8 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, p->start_sect = start; p->alignment_offset = queue_limit_alignment_offset(&disk->queue->limits, start); + p->discard_alignment = + queue_limit_discard_alignment(&disk->queue->limits, start); p->nr_sects = len; p->partno = partno; p->policy = get_disk_ro(disk); diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index ae9091a68480..2ad95fa1d130 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -257,7 +257,7 @@ struct queue_limits { unsigned char misaligned; unsigned char discard_misaligned; unsigned char cluster; - unsigned char discard_zeroes_data; + signed char discard_zeroes_data; }; struct request_queue @@ -364,8 +364,6 @@ struct request_queue * for flush operations */ unsigned int flush_flags; - unsigned int flush_not_queueable:1; - unsigned int flush_queue_delayed:1; unsigned int flush_pending_idx:1; unsigned int flush_running_idx:1; unsigned long flush_pending_since; @@ -845,7 +843,6 @@ extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *); extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); extern void blk_queue_flush(struct request_queue *q, unsigned int flush); -extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable); extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); @@ -1069,16 +1066,13 @@ static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector { unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1); - if (!lim->max_discard_sectors) - return 0; - return (lim->discard_granularity + lim->discard_alignment - alignment) & (lim->discard_granularity - 1); } static inline unsigned int queue_discard_zeroes_data(struct request_queue *q) { - if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1) + if (q->limits.discard_zeroes_data == 1) return 1; return 0; @@ -1117,11 +1111,6 @@ static inline unsigned int block_size(struct block_device *bdev) return bdev->bd_block_size; } -static inline bool queue_flush_queueable(struct request_queue *q) -{ - return !q->flush_not_queueable; -} - typedef struct {struct page *v;} Sector; unsigned char *read_dev_sector(struct block_device *, sector_t, Sector *); diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index d08399db6e2c..ab8dfc095709 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -442,6 +442,7 @@ struct device { struct dev_archdata archdata; struct device_node *of_node; /* associated device tree node */ + const struct of_device_id *of_match; /* matching of_device_id from driver */ dev_t devt; /* dev_t, creates the sysfs "dev" */ diff --git a/trunk/include/linux/genhd.h b/trunk/include/linux/genhd.h index b78956b3c2e7..d764a426e9fd 100644 --- a/trunk/include/linux/genhd.h +++ b/trunk/include/linux/genhd.h @@ -100,6 +100,7 @@ struct hd_struct { sector_t start_sect; sector_t nr_sects; sector_t alignment_offset; + unsigned int discard_alignment; struct device __dev; struct kobject *holder_dir; int policy, partno; @@ -126,7 +127,6 @@ struct hd_struct { #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 #define GENHD_FL_EXT_DEVT 64 /* allow extended devt */ #define GENHD_FL_NATIVE_CAPACITY 128 -#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256 enum { DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */ diff --git a/trunk/include/linux/of_device.h b/trunk/include/linux/of_device.h index ae5638480ef2..8bfe6c1d4365 100644 --- a/trunk/include/linux/of_device.h +++ b/trunk/include/linux/of_device.h @@ -21,7 +21,8 @@ extern void of_device_make_bus_id(struct device *dev); static inline int of_driver_match_device(struct device *dev, const struct device_driver *drv) { - return of_match_device(drv->of_match_table, dev) != NULL; + dev->of_match = of_match_device(drv->of_match_table, dev); + return dev->of_match != NULL; } extern struct platform_device *of_dev_get(struct platform_device *dev); @@ -57,11 +58,6 @@ static inline int of_device_uevent(struct device *dev, static inline void of_device_node_put(struct device *dev) { } -static inline const struct of_device_id *of_match_device( - const struct of_device_id *matches, const struct device *dev) -{ - return NULL; -} #endif /* CONFIG_OF_DEVICE */ #endif /* _LINUX_OF_DEVICE_H */