diff options
41 files changed, 271 insertions, 153 deletions
diff --git a/arch/x86/include/asm/ce4100.h b/arch/x86/include/asm/ce4100.h new file mode 100644 index 000000000000..e656ad8c0a2e --- /dev/null +++ b/arch/x86/include/asm/ce4100.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef _ASM_CE4100_H_ | ||
| 2 | #define _ASM_CE4100_H_ | ||
| 3 | |||
| 4 | int ce4100_pci_init(void); | ||
| 5 | |||
| 6 | #endif | ||
diff --git a/arch/x86/kernel/check.c b/arch/x86/kernel/check.c index 13a389179514..452932d34730 100644 --- a/arch/x86/kernel/check.c +++ b/arch/x86/kernel/check.c | |||
| @@ -106,8 +106,8 @@ void __init setup_bios_corruption_check(void) | |||
| 106 | addr += size; | 106 | addr += size; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | printk(KERN_INFO "Scanning %d areas for low memory corruption\n", | 109 | if (num_scan_areas) |
| 110 | num_scan_areas); | 110 | printk(KERN_INFO "Scanning %d areas for low memory corruption\n", num_scan_areas); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | 113 | ||
| @@ -143,12 +143,12 @@ static void check_corruption(struct work_struct *dummy) | |||
| 143 | { | 143 | { |
| 144 | check_for_bios_corruption(); | 144 | check_for_bios_corruption(); |
| 145 | schedule_delayed_work(&bios_check_work, | 145 | schedule_delayed_work(&bios_check_work, |
| 146 | round_jiffies_relative(corruption_check_period*HZ)); | 146 | round_jiffies_relative(corruption_check_period*HZ)); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | static int start_periodic_check_for_corruption(void) | 149 | static int start_periodic_check_for_corruption(void) |
| 150 | { | 150 | { |
| 151 | if (!memory_corruption_check || corruption_check_period == 0) | 151 | if (!num_scan_areas || !memory_corruption_check || corruption_check_period == 0) |
| 152 | return 0; | 152 | return 0; |
| 153 | 153 | ||
| 154 | printk(KERN_INFO "Scanning for low memory corruption every %d seconds\n", | 154 | printk(KERN_INFO "Scanning for low memory corruption every %d seconds\n", |
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 7d90ceb882a4..20e3f8702d1e 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
| @@ -229,15 +229,14 @@ void vmalloc_sync_all(void) | |||
| 229 | for (address = VMALLOC_START & PMD_MASK; | 229 | for (address = VMALLOC_START & PMD_MASK; |
| 230 | address >= TASK_SIZE && address < FIXADDR_TOP; | 230 | address >= TASK_SIZE && address < FIXADDR_TOP; |
| 231 | address += PMD_SIZE) { | 231 | address += PMD_SIZE) { |
| 232 | |||
| 233 | unsigned long flags; | ||
| 234 | struct page *page; | 232 | struct page *page; |
| 235 | 233 | ||
| 236 | spin_lock_irqsave(&pgd_lock, flags); | 234 | spin_lock(&pgd_lock); |
| 237 | list_for_each_entry(page, &pgd_list, lru) { | 235 | list_for_each_entry(page, &pgd_list, lru) { |
| 238 | spinlock_t *pgt_lock; | 236 | spinlock_t *pgt_lock; |
| 239 | pmd_t *ret; | 237 | pmd_t *ret; |
| 240 | 238 | ||
| 239 | /* the pgt_lock only for Xen */ | ||
| 241 | pgt_lock = &pgd_page_get_mm(page)->page_table_lock; | 240 | pgt_lock = &pgd_page_get_mm(page)->page_table_lock; |
| 242 | 241 | ||
| 243 | spin_lock(pgt_lock); | 242 | spin_lock(pgt_lock); |
| @@ -247,7 +246,7 @@ void vmalloc_sync_all(void) | |||
| 247 | if (!ret) | 246 | if (!ret) |
| 248 | break; | 247 | break; |
| 249 | } | 248 | } |
| 250 | spin_unlock_irqrestore(&pgd_lock, flags); | 249 | spin_unlock(&pgd_lock); |
| 251 | } | 250 | } |
| 252 | } | 251 | } |
| 253 | 252 | ||
| @@ -828,6 +827,13 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code, | |||
| 828 | unsigned long address, unsigned int fault) | 827 | unsigned long address, unsigned int fault) |
| 829 | { | 828 | { |
| 830 | if (fault & VM_FAULT_OOM) { | 829 | if (fault & VM_FAULT_OOM) { |
| 830 | /* Kernel mode? Handle exceptions or die: */ | ||
| 831 | if (!(error_code & PF_USER)) { | ||
| 832 | up_read(¤t->mm->mmap_sem); | ||
| 833 | no_context(regs, error_code, address); | ||
| 834 | return; | ||
| 835 | } | ||
| 836 | |||
| 831 | out_of_memory(regs, error_code, address); | 837 | out_of_memory(regs, error_code, address); |
| 832 | } else { | 838 | } else { |
| 833 | if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| | 839 | if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 71a59296af80..c14a5422e152 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
| @@ -105,18 +105,18 @@ void sync_global_pgds(unsigned long start, unsigned long end) | |||
| 105 | 105 | ||
| 106 | for (address = start; address <= end; address += PGDIR_SIZE) { | 106 | for (address = start; address <= end; address += PGDIR_SIZE) { |
| 107 | const pgd_t *pgd_ref = pgd_offset_k(address); | 107 | const pgd_t *pgd_ref = pgd_offset_k(address); |
| 108 | unsigned long flags; | ||
| 109 | struct page *page; | 108 | struct page *page; |
| 110 | 109 | ||
| 111 | if (pgd_none(*pgd_ref)) | 110 | if (pgd_none(*pgd_ref)) |
| 112 | continue; | 111 | continue; |
| 113 | 112 | ||
| 114 | spin_lock_irqsave(&pgd_lock, flags); | 113 | spin_lock(&pgd_lock); |
| 115 | list_for_each_entry(page, &pgd_list, lru) { | 114 | list_for_each_entry(page, &pgd_list, lru) { |
| 116 | pgd_t *pgd; | 115 | pgd_t *pgd; |
| 117 | spinlock_t *pgt_lock; | 116 | spinlock_t *pgt_lock; |
| 118 | 117 | ||
| 119 | pgd = (pgd_t *)page_address(page) + pgd_index(address); | 118 | pgd = (pgd_t *)page_address(page) + pgd_index(address); |
| 119 | /* the pgt_lock only for Xen */ | ||
| 120 | pgt_lock = &pgd_page_get_mm(page)->page_table_lock; | 120 | pgt_lock = &pgd_page_get_mm(page)->page_table_lock; |
| 121 | spin_lock(pgt_lock); | 121 | spin_lock(pgt_lock); |
| 122 | 122 | ||
| @@ -128,7 +128,7 @@ void sync_global_pgds(unsigned long start, unsigned long end) | |||
| 128 | 128 | ||
| 129 | spin_unlock(pgt_lock); | 129 | spin_unlock(pgt_lock); |
| 130 | } | 130 | } |
| 131 | spin_unlock_irqrestore(&pgd_lock, flags); | 131 | spin_unlock(&pgd_lock); |
| 132 | } | 132 | } |
| 133 | } | 133 | } |
| 134 | 134 | ||
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index d343b3c81f3c..90825f2eb0f4 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
| @@ -57,12 +57,10 @@ static unsigned long direct_pages_count[PG_LEVEL_NUM]; | |||
| 57 | 57 | ||
| 58 | void update_page_count(int level, unsigned long pages) | 58 | void update_page_count(int level, unsigned long pages) |
| 59 | { | 59 | { |
| 60 | unsigned long flags; | ||
| 61 | |||
| 62 | /* Protect against CPA */ | 60 | /* Protect against CPA */ |
| 63 | spin_lock_irqsave(&pgd_lock, flags); | 61 | spin_lock(&pgd_lock); |
| 64 | direct_pages_count[level] += pages; | 62 | direct_pages_count[level] += pages; |
| 65 | spin_unlock_irqrestore(&pgd_lock, flags); | 63 | spin_unlock(&pgd_lock); |
| 66 | } | 64 | } |
| 67 | 65 | ||
| 68 | static void split_page_count(int level) | 66 | static void split_page_count(int level) |
| @@ -394,7 +392,7 @@ static int | |||
| 394 | try_preserve_large_page(pte_t *kpte, unsigned long address, | 392 | try_preserve_large_page(pte_t *kpte, unsigned long address, |
| 395 | struct cpa_data *cpa) | 393 | struct cpa_data *cpa) |
| 396 | { | 394 | { |
| 397 | unsigned long nextpage_addr, numpages, pmask, psize, flags, addr, pfn; | 395 | unsigned long nextpage_addr, numpages, pmask, psize, addr, pfn; |
| 398 | pte_t new_pte, old_pte, *tmp; | 396 | pte_t new_pte, old_pte, *tmp; |
| 399 | pgprot_t old_prot, new_prot, req_prot; | 397 | pgprot_t old_prot, new_prot, req_prot; |
| 400 | int i, do_split = 1; | 398 | int i, do_split = 1; |
| @@ -403,7 +401,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, | |||
| 403 | if (cpa->force_split) | 401 | if (cpa->force_split) |
| 404 | return 1; | 402 | return 1; |
| 405 | 403 | ||
| 406 | spin_lock_irqsave(&pgd_lock, flags); | 404 | spin_lock(&pgd_lock); |
| 407 | /* | 405 | /* |
| 408 | * Check for races, another CPU might have split this page | 406 | * Check for races, another CPU might have split this page |
| 409 | * up already: | 407 | * up already: |
| @@ -498,14 +496,14 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, | |||
| 498 | } | 496 | } |
| 499 | 497 | ||
| 500 | out_unlock: | 498 | out_unlock: |
| 501 | spin_unlock_irqrestore(&pgd_lock, flags); | 499 | spin_unlock(&pgd_lock); |
| 502 | 500 | ||
| 503 | return do_split; | 501 | return do_split; |
| 504 | } | 502 | } |
| 505 | 503 | ||
| 506 | static int split_large_page(pte_t *kpte, unsigned long address) | 504 | static int split_large_page(pte_t *kpte, unsigned long address) |
| 507 | { | 505 | { |
| 508 | unsigned long flags, pfn, pfninc = 1; | 506 | unsigned long pfn, pfninc = 1; |
| 509 | unsigned int i, level; | 507 | unsigned int i, level; |
| 510 | pte_t *pbase, *tmp; | 508 | pte_t *pbase, *tmp; |
| 511 | pgprot_t ref_prot; | 509 | pgprot_t ref_prot; |
| @@ -519,7 +517,7 @@ static int split_large_page(pte_t *kpte, unsigned long address) | |||
| 519 | if (!base) | 517 | if (!base) |
| 520 | return -ENOMEM; | 518 | return -ENOMEM; |
| 521 | 519 | ||
| 522 | spin_lock_irqsave(&pgd_lock, flags); | 520 | spin_lock(&pgd_lock); |
| 523 | /* | 521 | /* |
| 524 | * Check for races, another CPU might have split this page | 522 | * Check for races, another CPU might have split this page |
| 525 | * up for us already: | 523 | * up for us already: |
| @@ -591,7 +589,7 @@ out_unlock: | |||
| 591 | */ | 589 | */ |
| 592 | if (base) | 590 | if (base) |
| 593 | __free_page(base); | 591 | __free_page(base); |
| 594 | spin_unlock_irqrestore(&pgd_lock, flags); | 592 | spin_unlock(&pgd_lock); |
| 595 | 593 | ||
| 596 | return 0; | 594 | return 0; |
| 597 | } | 595 | } |
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 500242d3c96d..0113d19c8aa6 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c | |||
| @@ -121,14 +121,12 @@ static void pgd_ctor(struct mm_struct *mm, pgd_t *pgd) | |||
| 121 | 121 | ||
| 122 | static void pgd_dtor(pgd_t *pgd) | 122 | static void pgd_dtor(pgd_t *pgd) |
| 123 | { | 123 | { |
| 124 | unsigned long flags; /* can be called from interrupt context */ | ||
| 125 | |||
| 126 | if (SHARED_KERNEL_PMD) | 124 | if (SHARED_KERNEL_PMD) |
| 127 | return; | 125 | return; |
| 128 | 126 | ||
| 129 | spin_lock_irqsave(&pgd_lock, flags); | 127 | spin_lock(&pgd_lock); |
| 130 | pgd_list_del(pgd); | 128 | pgd_list_del(pgd); |
| 131 | spin_unlock_irqrestore(&pgd_lock, flags); | 129 | spin_unlock(&pgd_lock); |
| 132 | } | 130 | } |
| 133 | 131 | ||
| 134 | /* | 132 | /* |
| @@ -260,7 +258,6 @@ pgd_t *pgd_alloc(struct mm_struct *mm) | |||
| 260 | { | 258 | { |
| 261 | pgd_t *pgd; | 259 | pgd_t *pgd; |
| 262 | pmd_t *pmds[PREALLOCATED_PMDS]; | 260 | pmd_t *pmds[PREALLOCATED_PMDS]; |
| 263 | unsigned long flags; | ||
| 264 | 261 | ||
| 265 | pgd = (pgd_t *)__get_free_page(PGALLOC_GFP); | 262 | pgd = (pgd_t *)__get_free_page(PGALLOC_GFP); |
| 266 | 263 | ||
| @@ -280,12 +277,12 @@ pgd_t *pgd_alloc(struct mm_struct *mm) | |||
| 280 | * respect to anything walking the pgd_list, so that they | 277 | * respect to anything walking the pgd_list, so that they |
| 281 | * never see a partially populated pgd. | 278 | * never see a partially populated pgd. |
| 282 | */ | 279 | */ |
| 283 | spin_lock_irqsave(&pgd_lock, flags); | 280 | spin_lock(&pgd_lock); |
| 284 | 281 | ||
| 285 | pgd_ctor(mm, pgd); | 282 | pgd_ctor(mm, pgd); |
| 286 | pgd_prepopulate_pmd(mm, pgd, pmds); | 283 | pgd_prepopulate_pmd(mm, pgd, pmds); |
| 287 | 284 | ||
| 288 | spin_unlock_irqrestore(&pgd_lock, flags); | 285 | spin_unlock(&pgd_lock); |
| 289 | 286 | ||
| 290 | return pgd; | 287 | return pgd; |
| 291 | 288 | ||
diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c index 85b68ef5e809..9260b3eb18d4 100644 --- a/arch/x86/pci/ce4100.c +++ b/arch/x86/pci/ce4100.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
| 35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
| 36 | 36 | ||
| 37 | #include <asm/ce4100.h> | ||
| 37 | #include <asm/pci_x86.h> | 38 | #include <asm/pci_x86.h> |
| 38 | 39 | ||
| 39 | struct sim_reg { | 40 | struct sim_reg { |
| @@ -306,10 +307,10 @@ struct pci_raw_ops ce4100_pci_conf = { | |||
| 306 | .write = ce4100_conf_write, | 307 | .write = ce4100_conf_write, |
| 307 | }; | 308 | }; |
| 308 | 309 | ||
| 309 | static int __init ce4100_pci_init(void) | 310 | int __init ce4100_pci_init(void) |
| 310 | { | 311 | { |
| 311 | init_sim_regs(); | 312 | init_sim_regs(); |
| 312 | raw_pci_ops = &ce4100_pci_conf; | 313 | raw_pci_ops = &ce4100_pci_conf; |
| 313 | return 0; | 314 | /* Indicate caller that it should invoke pci_legacy_init() */ |
| 315 | return 1; | ||
| 314 | } | 316 | } |
| 315 | subsys_initcall(ce4100_pci_init); | ||
diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c index d2c0d51a7178..cd6f184c3b3f 100644 --- a/arch/x86/platform/ce4100/ce4100.c +++ b/arch/x86/platform/ce4100/ce4100.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/serial_reg.h> | 15 | #include <linux/serial_reg.h> |
| 16 | #include <linux/serial_8250.h> | 16 | #include <linux/serial_8250.h> |
| 17 | 17 | ||
| 18 | #include <asm/ce4100.h> | ||
| 18 | #include <asm/setup.h> | 19 | #include <asm/setup.h> |
| 19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
| 20 | 21 | ||
| @@ -129,4 +130,5 @@ void __init x86_ce4100_early_setup(void) | |||
| 129 | x86_init.resources.probe_roms = x86_init_noop; | 130 | x86_init.resources.probe_roms = x86_init_noop; |
| 130 | x86_init.mpparse.get_smp_config = x86_init_uint_noop; | 131 | x86_init.mpparse.get_smp_config = x86_init_uint_noop; |
| 131 | x86_init.mpparse.find_smp_config = sdv_find_smp_config; | 132 | x86_init.mpparse.find_smp_config = sdv_find_smp_config; |
| 133 | x86_init.pci.init = ce4100_pci_init; | ||
| 132 | } | 134 | } |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 5e92b61ad574..f6089421147a 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
| @@ -986,10 +986,9 @@ static void xen_pgd_pin(struct mm_struct *mm) | |||
| 986 | */ | 986 | */ |
| 987 | void xen_mm_pin_all(void) | 987 | void xen_mm_pin_all(void) |
| 988 | { | 988 | { |
| 989 | unsigned long flags; | ||
| 990 | struct page *page; | 989 | struct page *page; |
| 991 | 990 | ||
| 992 | spin_lock_irqsave(&pgd_lock, flags); | 991 | spin_lock(&pgd_lock); |
| 993 | 992 | ||
| 994 | list_for_each_entry(page, &pgd_list, lru) { | 993 | list_for_each_entry(page, &pgd_list, lru) { |
| 995 | if (!PagePinned(page)) { | 994 | if (!PagePinned(page)) { |
| @@ -998,7 +997,7 @@ void xen_mm_pin_all(void) | |||
| 998 | } | 997 | } |
| 999 | } | 998 | } |
| 1000 | 999 | ||
| 1001 | spin_unlock_irqrestore(&pgd_lock, flags); | 1000 | spin_unlock(&pgd_lock); |
| 1002 | } | 1001 | } |
| 1003 | 1002 | ||
| 1004 | /* | 1003 | /* |
| @@ -1099,10 +1098,9 @@ static void xen_pgd_unpin(struct mm_struct *mm) | |||
| 1099 | */ | 1098 | */ |
| 1100 | void xen_mm_unpin_all(void) | 1099 | void xen_mm_unpin_all(void) |
| 1101 | { | 1100 | { |
| 1102 | unsigned long flags; | ||
| 1103 | struct page *page; | 1101 | struct page *page; |
| 1104 | 1102 | ||
| 1105 | spin_lock_irqsave(&pgd_lock, flags); | 1103 | spin_lock(&pgd_lock); |
| 1106 | 1104 | ||
| 1107 | list_for_each_entry(page, &pgd_list, lru) { | 1105 | list_for_each_entry(page, &pgd_list, lru) { |
| 1108 | if (PageSavePinned(page)) { | 1106 | if (PageSavePinned(page)) { |
| @@ -1112,7 +1110,7 @@ void xen_mm_unpin_all(void) | |||
| 1112 | } | 1110 | } |
| 1113 | } | 1111 | } |
| 1114 | 1112 | ||
| 1115 | spin_unlock_irqrestore(&pgd_lock, flags); | 1113 | spin_unlock(&pgd_lock); |
| 1116 | } | 1114 | } |
| 1117 | 1115 | ||
| 1118 | void xen_activate_mm(struct mm_struct *prev, struct mm_struct *next) | 1116 | void xen_activate_mm(struct mm_struct *prev, struct mm_struct *next) |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index d270b3ff896b..6140ea1de45a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -2194,7 +2194,6 @@ int evergreen_mc_init(struct radeon_device *rdev) | |||
| 2194 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; | 2194 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; |
| 2195 | } | 2195 | } |
| 2196 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 2196 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
| 2197 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
| 2198 | r700_vram_gtt_location(rdev, &rdev->mc); | 2197 | r700_vram_gtt_location(rdev, &rdev->mc); |
| 2199 | radeon_update_bandwidth_info(rdev); | 2198 | radeon_update_bandwidth_info(rdev); |
| 2200 | 2199 | ||
| @@ -2934,7 +2933,7 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
| 2934 | /* XXX: ontario has problems blitting to gart at the moment */ | 2933 | /* XXX: ontario has problems blitting to gart at the moment */ |
| 2935 | if (rdev->family == CHIP_PALM) { | 2934 | if (rdev->family == CHIP_PALM) { |
| 2936 | rdev->asic->copy = NULL; | 2935 | rdev->asic->copy = NULL; |
| 2937 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 2936 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
| 2938 | } | 2937 | } |
| 2939 | 2938 | ||
| 2940 | /* allocate wb buffer */ | 2939 | /* allocate wb buffer */ |
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 2adfb03f479b..2be698e78ff2 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c | |||
| @@ -623,7 +623,7 @@ done: | |||
| 623 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); | 623 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); |
| 624 | return r; | 624 | return r; |
| 625 | } | 625 | } |
| 626 | rdev->mc.active_vram_size = rdev->mc.real_vram_size; | 626 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); |
| 627 | return 0; | 627 | return 0; |
| 628 | } | 628 | } |
| 629 | 629 | ||
| @@ -631,7 +631,7 @@ void evergreen_blit_fini(struct radeon_device *rdev) | |||
| 631 | { | 631 | { |
| 632 | int r; | 632 | int r; |
| 633 | 633 | ||
| 634 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 634 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
| 635 | if (rdev->r600_blit.shader_obj == NULL) | 635 | if (rdev->r600_blit.shader_obj == NULL) |
| 636 | return; | 636 | return; |
| 637 | /* If we can't reserve the bo, unref should be enough to destroy | 637 | /* If we can't reserve the bo, unref should be enough to destroy |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 79de991e1ea3..e372f9e1e5ce 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -1024,7 +1024,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
| 1024 | return r; | 1024 | return r; |
| 1025 | } | 1025 | } |
| 1026 | rdev->cp.ready = true; | 1026 | rdev->cp.ready = true; |
| 1027 | rdev->mc.active_vram_size = rdev->mc.real_vram_size; | 1027 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); |
| 1028 | return 0; | 1028 | return 0; |
| 1029 | } | 1029 | } |
| 1030 | 1030 | ||
| @@ -1042,7 +1042,7 @@ void r100_cp_fini(struct radeon_device *rdev) | |||
| 1042 | void r100_cp_disable(struct radeon_device *rdev) | 1042 | void r100_cp_disable(struct radeon_device *rdev) |
| 1043 | { | 1043 | { |
| 1044 | /* Disable ring */ | 1044 | /* Disable ring */ |
| 1045 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 1045 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
| 1046 | rdev->cp.ready = false; | 1046 | rdev->cp.ready = false; |
| 1047 | WREG32(RADEON_CP_CSQ_MODE, 0); | 1047 | WREG32(RADEON_CP_CSQ_MODE, 0); |
| 1048 | WREG32(RADEON_CP_CSQ_CNTL, 0); | 1048 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
| @@ -2312,7 +2312,6 @@ void r100_vram_init_sizes(struct radeon_device *rdev) | |||
| 2312 | /* FIXME we don't use the second aperture yet when we could use it */ | 2312 | /* FIXME we don't use the second aperture yet when we could use it */ |
| 2313 | if (rdev->mc.visible_vram_size > rdev->mc.aper_size) | 2313 | if (rdev->mc.visible_vram_size > rdev->mc.aper_size) |
| 2314 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 2314 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
| 2315 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
| 2316 | config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE); | 2315 | config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE); |
| 2317 | if (rdev->flags & RADEON_IS_IGP) { | 2316 | if (rdev->flags & RADEON_IS_IGP) { |
| 2318 | uint32_t tom; | 2317 | uint32_t tom; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index de88624d5f87..9b3fad23b76c 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -1255,7 +1255,6 @@ int r600_mc_init(struct radeon_device *rdev) | |||
| 1255 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | 1255 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
| 1256 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 1256 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
| 1257 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 1257 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
| 1258 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
| 1259 | r600_vram_gtt_location(rdev, &rdev->mc); | 1258 | r600_vram_gtt_location(rdev, &rdev->mc); |
| 1260 | 1259 | ||
| 1261 | if (rdev->flags & RADEON_IS_IGP) { | 1260 | if (rdev->flags & RADEON_IS_IGP) { |
| @@ -1937,7 +1936,7 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) | |||
| 1937 | */ | 1936 | */ |
| 1938 | void r600_cp_stop(struct radeon_device *rdev) | 1937 | void r600_cp_stop(struct radeon_device *rdev) |
| 1939 | { | 1938 | { |
| 1940 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 1939 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
| 1941 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); | 1940 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); |
| 1942 | WREG32(SCRATCH_UMSK, 0); | 1941 | WREG32(SCRATCH_UMSK, 0); |
| 1943 | } | 1942 | } |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 41f7aafc97c4..df68d91e8190 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
| @@ -558,7 +558,7 @@ done: | |||
| 558 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); | 558 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); |
| 559 | return r; | 559 | return r; |
| 560 | } | 560 | } |
| 561 | rdev->mc.active_vram_size = rdev->mc.real_vram_size; | 561 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); |
| 562 | return 0; | 562 | return 0; |
| 563 | } | 563 | } |
| 564 | 564 | ||
| @@ -566,7 +566,7 @@ void r600_blit_fini(struct radeon_device *rdev) | |||
| 566 | { | 566 | { |
| 567 | int r; | 567 | int r; |
| 568 | 568 | ||
| 569 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 569 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
| 570 | if (rdev->r600_blit.shader_obj == NULL) | 570 | if (rdev->r600_blit.shader_obj == NULL) |
| 571 | return; | 571 | return; |
| 572 | /* If we can't reserve the bo, unref should be enough to destroy | 572 | /* If we can't reserve the bo, unref should be enough to destroy |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 56c48b67ef3d..6b3429495118 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -345,7 +345,6 @@ struct radeon_mc { | |||
| 345 | * about vram size near mc fb location */ | 345 | * about vram size near mc fb location */ |
| 346 | u64 mc_vram_size; | 346 | u64 mc_vram_size; |
| 347 | u64 visible_vram_size; | 347 | u64 visible_vram_size; |
| 348 | u64 active_vram_size; | ||
| 349 | u64 gtt_size; | 348 | u64 gtt_size; |
| 350 | u64 gtt_start; | 349 | u64 gtt_start; |
| 351 | u64 gtt_end; | 350 | u64 gtt_end; |
| @@ -1448,6 +1447,7 @@ extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *m | |||
| 1448 | extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); | 1447 | extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); |
| 1449 | extern int radeon_resume_kms(struct drm_device *dev); | 1448 | extern int radeon_resume_kms(struct drm_device *dev); |
| 1450 | extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); | 1449 | extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); |
| 1450 | extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); | ||
| 1451 | 1451 | ||
| 1452 | /* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */ | 1452 | /* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */ |
| 1453 | extern bool r600_card_posted(struct radeon_device *rdev); | 1453 | extern bool r600_card_posted(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index df95eb83dac6..1fe95dfe48c9 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
| @@ -156,9 +156,12 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, | |||
| 156 | { | 156 | { |
| 157 | struct radeon_device *rdev = dev->dev_private; | 157 | struct radeon_device *rdev = dev->dev_private; |
| 158 | struct drm_radeon_gem_info *args = data; | 158 | struct drm_radeon_gem_info *args = data; |
| 159 | struct ttm_mem_type_manager *man; | ||
| 160 | |||
| 161 | man = &rdev->mman.bdev.man[TTM_PL_VRAM]; | ||
| 159 | 162 | ||
| 160 | args->vram_size = rdev->mc.real_vram_size; | 163 | args->vram_size = rdev->mc.real_vram_size; |
| 161 | args->vram_visible = rdev->mc.real_vram_size; | 164 | args->vram_visible = (u64)man->size << PAGE_SHIFT; |
| 162 | if (rdev->stollen_vga_memory) | 165 | if (rdev->stollen_vga_memory) |
| 163 | args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); | 166 | args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); |
| 164 | args->vram_visible -= radeon_fbdev_total_size(rdev); | 167 | args->vram_visible -= radeon_fbdev_total_size(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index e5b2cf10cbf4..8389b4c63d12 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
| @@ -589,6 +589,20 @@ void radeon_ttm_fini(struct radeon_device *rdev) | |||
| 589 | DRM_INFO("radeon: ttm finalized\n"); | 589 | DRM_INFO("radeon: ttm finalized\n"); |
| 590 | } | 590 | } |
| 591 | 591 | ||
| 592 | /* this should only be called at bootup or when userspace | ||
| 593 | * isn't running */ | ||
| 594 | void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size) | ||
| 595 | { | ||
| 596 | struct ttm_mem_type_manager *man; | ||
| 597 | |||
| 598 | if (!rdev->mman.initialized) | ||
| 599 | return; | ||
| 600 | |||
| 601 | man = &rdev->mman.bdev.man[TTM_PL_VRAM]; | ||
| 602 | /* this just adjusts TTM size idea, which sets lpfn to the correct value */ | ||
| 603 | man->size = size >> PAGE_SHIFT; | ||
| 604 | } | ||
| 605 | |||
| 592 | static struct vm_operations_struct radeon_ttm_vm_ops; | 606 | static struct vm_operations_struct radeon_ttm_vm_ops; |
| 593 | static const struct vm_operations_struct *ttm_vm_ops = NULL; | 607 | static const struct vm_operations_struct *ttm_vm_ops = NULL; |
| 594 | 608 | ||
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 5afe294ed51f..8af4679db23e 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
| @@ -751,7 +751,6 @@ void rs600_mc_init(struct radeon_device *rdev) | |||
| 751 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); | 751 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); |
| 752 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; | 752 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; |
| 753 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 753 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
| 754 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
| 755 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | 754 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); |
| 756 | base = RREG32_MC(R_000004_MC_FB_LOCATION); | 755 | base = RREG32_MC(R_000004_MC_FB_LOCATION); |
| 757 | base = G_000004_MC_FB_START(base) << 16; | 756 | base = G_000004_MC_FB_START(base) << 16; |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 6638c8e4c81b..66c949b7c18c 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
| @@ -157,7 +157,6 @@ void rs690_mc_init(struct radeon_device *rdev) | |||
| 157 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); | 157 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
| 158 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); | 158 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
| 159 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 159 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
| 160 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
| 161 | base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); | 160 | base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); |
| 162 | base = G_000100_MC_FB_START(base) << 16; | 161 | base = G_000100_MC_FB_START(base) << 16; |
| 163 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); | 162 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index d8ba67690656..714ad45757d0 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -307,7 +307,7 @@ static void rv770_mc_program(struct radeon_device *rdev) | |||
| 307 | */ | 307 | */ |
| 308 | void r700_cp_stop(struct radeon_device *rdev) | 308 | void r700_cp_stop(struct radeon_device *rdev) |
| 309 | { | 309 | { |
| 310 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 310 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
| 311 | WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); | 311 | WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); |
| 312 | WREG32(SCRATCH_UMSK, 0); | 312 | WREG32(SCRATCH_UMSK, 0); |
| 313 | } | 313 | } |
| @@ -1123,7 +1123,6 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
| 1123 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | 1123 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
| 1124 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 1124 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
| 1125 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 1125 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
| 1126 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | ||
| 1127 | r700_vram_gtt_location(rdev, &rdev->mc); | 1126 | r700_vram_gtt_location(rdev, &rdev->mc); |
| 1128 | radeon_update_bandwidth_info(rdev); | 1127 | radeon_update_bandwidth_info(rdev); |
| 1129 | 1128 | ||
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index eca855a55c0d..3de4ba0260a5 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c | |||
| @@ -646,7 +646,7 @@ static int __devexit cpwd_remove(struct platform_device *op) | |||
| 646 | struct cpwd *p = dev_get_drvdata(&op->dev); | 646 | struct cpwd *p = dev_get_drvdata(&op->dev); |
| 647 | int i; | 647 | int i; |
| 648 | 648 | ||
| 649 | for (i = 0; i < 4; i++) { | 649 | for (i = 0; i < WD_NUMDEVS; i++) { |
| 650 | misc_deregister(&p->devs[i].misc); | 650 | misc_deregister(&p->devs[i].misc); |
| 651 | 651 | ||
| 652 | if (!p->enabled) { | 652 | if (!p->enabled) { |
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 24b966d5061a..204a5603c4ae 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
| @@ -710,7 +710,7 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) | |||
| 710 | return 0; | 710 | return 0; |
| 711 | } | 711 | } |
| 712 | 712 | ||
| 713 | static void __devexit hpwdt_exit_nmi_decoding(void) | 713 | static void hpwdt_exit_nmi_decoding(void) |
| 714 | { | 714 | { |
| 715 | unregister_die_notifier(&die_notifier); | 715 | unregister_die_notifier(&die_notifier); |
| 716 | if (cru_rom_addr) | 716 | if (cru_rom_addr) |
| @@ -726,7 +726,7 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) | |||
| 726 | return 0; | 726 | return 0; |
| 727 | } | 727 | } |
| 728 | 728 | ||
| 729 | static void __devexit hpwdt_exit_nmi_decoding(void) | 729 | static void hpwdt_exit_nmi_decoding(void) |
| 730 | { | 730 | { |
| 731 | } | 731 | } |
| 732 | #endif /* CONFIG_HPWDT_NMI_DECODING */ | 732 | #endif /* CONFIG_HPWDT_NMI_DECODING */ |
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index 0461858e07d0..b61ab1c54293 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c | |||
| @@ -508,7 +508,7 @@ static int __init sch311x_detect(int sio_config_port, unsigned short *addr) | |||
| 508 | sch311x_sio_outb(sio_config_port, 0x07, 0x0a); | 508 | sch311x_sio_outb(sio_config_port, 0x07, 0x0a); |
| 509 | 509 | ||
| 510 | /* Check if Logical Device Register is currently active */ | 510 | /* Check if Logical Device Register is currently active */ |
| 511 | if (sch311x_sio_inb(sio_config_port, 0x30) && 0x01 == 0) | 511 | if ((sch311x_sio_inb(sio_config_port, 0x30) & 0x01) == 0) |
| 512 | printk(KERN_INFO PFX "Seems that LDN 0x0a is not active...\n"); | 512 | printk(KERN_INFO PFX "Seems that LDN 0x0a is not active...\n"); |
| 513 | 513 | ||
| 514 | /* Get the base address of the runtime registers */ | 514 | /* Get the base address of the runtime registers */ |
diff --git a/drivers/watchdog/w83697ug_wdt.c b/drivers/watchdog/w83697ug_wdt.c index a6c12dec91a1..df2a64dc9672 100644 --- a/drivers/watchdog/w83697ug_wdt.c +++ b/drivers/watchdog/w83697ug_wdt.c | |||
| @@ -109,7 +109,7 @@ static int w83697ug_select_wd_register(void) | |||
| 109 | outb_p(0x08, WDT_EFDR); /* select logical device 8 (GPIO2) */ | 109 | outb_p(0x08, WDT_EFDR); /* select logical device 8 (GPIO2) */ |
| 110 | outb_p(0x30, WDT_EFER); /* select CR30 */ | 110 | outb_p(0x30, WDT_EFER); /* select CR30 */ |
| 111 | c = inb_p(WDT_EFDR); | 111 | c = inb_p(WDT_EFDR); |
| 112 | outb_p(c || 0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ | 112 | outb_p(c | 0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ |
| 113 | 113 | ||
| 114 | return 0; | 114 | return 0; |
| 115 | } | 115 | } |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 1cc600e77bb4..2f8e61816d75 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/inet.h> | 37 | #include <linux/inet.h> |
| 38 | #include <linux/nfs_xdr.h> | 38 | #include <linux/nfs_xdr.h> |
| 39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
| 40 | #include <linux/compat.h> | ||
| 40 | 41 | ||
| 41 | #include <asm/system.h> | 42 | #include <asm/system.h> |
| 42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
| @@ -89,7 +90,11 @@ int nfs_wait_bit_killable(void *word) | |||
| 89 | */ | 90 | */ |
| 90 | u64 nfs_compat_user_ino64(u64 fileid) | 91 | u64 nfs_compat_user_ino64(u64 fileid) |
| 91 | { | 92 | { |
| 92 | int ino; | 93 | #ifdef CONFIG_COMPAT |
| 94 | compat_ulong_t ino; | ||
| 95 | #else | ||
| 96 | unsigned long ino; | ||
| 97 | #endif | ||
| 93 | 98 | ||
| 94 | if (enable_ino64) | 99 | if (enable_ino64) |
| 95 | return fileid; | 100 | return fileid; |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 7a7474073148..1be36cf65bfc 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
| @@ -298,6 +298,11 @@ struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp); | |||
| 298 | #if defined(CONFIG_NFS_V4_1) | 298 | #if defined(CONFIG_NFS_V4_1) |
| 299 | struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp); | 299 | struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp); |
| 300 | struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp); | 300 | struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp); |
| 301 | extern void nfs4_schedule_session_recovery(struct nfs4_session *); | ||
| 302 | #else | ||
| 303 | static inline void nfs4_schedule_session_recovery(struct nfs4_session *session) | ||
| 304 | { | ||
| 305 | } | ||
| 301 | #endif /* CONFIG_NFS_V4_1 */ | 306 | #endif /* CONFIG_NFS_V4_1 */ |
| 302 | 307 | ||
| 303 | extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); | 308 | extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *); |
| @@ -307,10 +312,9 @@ extern void nfs4_put_open_state(struct nfs4_state *); | |||
| 307 | extern void nfs4_close_state(struct path *, struct nfs4_state *, fmode_t); | 312 | extern void nfs4_close_state(struct path *, struct nfs4_state *, fmode_t); |
| 308 | extern void nfs4_close_sync(struct path *, struct nfs4_state *, fmode_t); | 313 | extern void nfs4_close_sync(struct path *, struct nfs4_state *, fmode_t); |
| 309 | extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t); | 314 | extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t); |
| 310 | extern void nfs4_schedule_state_recovery(struct nfs_client *); | 315 | extern void nfs4_schedule_lease_recovery(struct nfs_client *); |
| 311 | extern void nfs4_schedule_state_manager(struct nfs_client *); | 316 | extern void nfs4_schedule_state_manager(struct nfs_client *); |
| 312 | extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state); | 317 | extern void nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *); |
| 313 | extern int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state); | ||
| 314 | extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); | 318 | extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); |
| 315 | extern void nfs41_handle_recall_slot(struct nfs_client *clp); | 319 | extern void nfs41_handle_recall_slot(struct nfs_client *clp); |
| 316 | extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); | 320 | extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); |
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c index f5c9b125e8cc..b73c34375f60 100644 --- a/fs/nfs/nfs4filelayoutdev.c +++ b/fs/nfs/nfs4filelayoutdev.c | |||
| @@ -219,6 +219,10 @@ decode_and_add_ds(__be32 **pp, struct inode *inode) | |||
| 219 | goto out_err; | 219 | goto out_err; |
| 220 | } | 220 | } |
| 221 | buf = kmalloc(rlen + 1, GFP_KERNEL); | 221 | buf = kmalloc(rlen + 1, GFP_KERNEL); |
| 222 | if (!buf) { | ||
| 223 | dprintk("%s: Not enough memory\n", __func__); | ||
| 224 | goto out_err; | ||
| 225 | } | ||
| 222 | buf[rlen] = '\0'; | 226 | buf[rlen] = '\0'; |
| 223 | memcpy(buf, r_addr, rlen); | 227 | memcpy(buf, r_addr, rlen); |
| 224 | 228 | ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 1ff76acc7e98..0a07e353a961 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -51,7 +51,6 @@ | |||
| 51 | #include <linux/sunrpc/bc_xprt.h> | 51 | #include <linux/sunrpc/bc_xprt.h> |
| 52 | #include <linux/xattr.h> | 52 | #include <linux/xattr.h> |
| 53 | #include <linux/utsname.h> | 53 | #include <linux/utsname.h> |
| 54 | #include <linux/mm.h> | ||
| 55 | 54 | ||
| 56 | #include "nfs4_fs.h" | 55 | #include "nfs4_fs.h" |
| 57 | #include "delegation.h" | 56 | #include "delegation.h" |
| @@ -257,12 +256,13 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, | |||
| 257 | case -NFS4ERR_OPENMODE: | 256 | case -NFS4ERR_OPENMODE: |
| 258 | if (state == NULL) | 257 | if (state == NULL) |
| 259 | break; | 258 | break; |
| 260 | nfs4_state_mark_reclaim_nograce(clp, state); | 259 | nfs4_schedule_stateid_recovery(server, state); |
| 261 | goto do_state_recovery; | 260 | goto wait_on_recovery; |
| 262 | case -NFS4ERR_STALE_STATEID: | 261 | case -NFS4ERR_STALE_STATEID: |
| 263 | case -NFS4ERR_STALE_CLIENTID: | 262 | case -NFS4ERR_STALE_CLIENTID: |
| 264 | case -NFS4ERR_EXPIRED: | 263 | case -NFS4ERR_EXPIRED: |
| 265 | goto do_state_recovery; | 264 | nfs4_schedule_lease_recovery(clp); |
| 265 | goto wait_on_recovery; | ||
| 266 | #if defined(CONFIG_NFS_V4_1) | 266 | #if defined(CONFIG_NFS_V4_1) |
| 267 | case -NFS4ERR_BADSESSION: | 267 | case -NFS4ERR_BADSESSION: |
| 268 | case -NFS4ERR_BADSLOT: | 268 | case -NFS4ERR_BADSLOT: |
| @@ -273,7 +273,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, | |||
| 273 | case -NFS4ERR_SEQ_MISORDERED: | 273 | case -NFS4ERR_SEQ_MISORDERED: |
| 274 | dprintk("%s ERROR: %d Reset session\n", __func__, | 274 | dprintk("%s ERROR: %d Reset session\n", __func__, |
| 275 | errorcode); | 275 | errorcode); |
| 276 | nfs4_schedule_state_recovery(clp); | 276 | nfs4_schedule_session_recovery(clp->cl_session); |
| 277 | exception->retry = 1; | 277 | exception->retry = 1; |
| 278 | break; | 278 | break; |
| 279 | #endif /* defined(CONFIG_NFS_V4_1) */ | 279 | #endif /* defined(CONFIG_NFS_V4_1) */ |
| @@ -296,8 +296,7 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, | |||
| 296 | } | 296 | } |
| 297 | /* We failed to handle the error */ | 297 | /* We failed to handle the error */ |
| 298 | return nfs4_map_errors(ret); | 298 | return nfs4_map_errors(ret); |
| 299 | do_state_recovery: | 299 | wait_on_recovery: |
| 300 | nfs4_schedule_state_recovery(clp); | ||
| 301 | ret = nfs4_wait_clnt_recover(clp); | 300 | ret = nfs4_wait_clnt_recover(clp); |
| 302 | if (ret == 0) | 301 | if (ret == 0) |
| 303 | exception->retry = 1; | 302 | exception->retry = 1; |
| @@ -436,8 +435,8 @@ static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res * | |||
| 436 | clp = res->sr_session->clp; | 435 | clp = res->sr_session->clp; |
| 437 | do_renew_lease(clp, timestamp); | 436 | do_renew_lease(clp, timestamp); |
| 438 | /* Check sequence flags */ | 437 | /* Check sequence flags */ |
| 439 | if (atomic_read(&clp->cl_count) > 1) | 438 | if (res->sr_status_flags != 0) |
| 440 | nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags); | 439 | nfs4_schedule_lease_recovery(clp); |
| 441 | break; | 440 | break; |
| 442 | case -NFS4ERR_DELAY: | 441 | case -NFS4ERR_DELAY: |
| 443 | /* The server detected a resend of the RPC call and | 442 | /* The server detected a resend of the RPC call and |
| @@ -1256,14 +1255,13 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state | |||
| 1256 | case -NFS4ERR_BAD_HIGH_SLOT: | 1255 | case -NFS4ERR_BAD_HIGH_SLOT: |
| 1257 | case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: | 1256 | case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: |
| 1258 | case -NFS4ERR_DEADSESSION: | 1257 | case -NFS4ERR_DEADSESSION: |
| 1259 | nfs4_schedule_state_recovery( | 1258 | nfs4_schedule_session_recovery(server->nfs_client->cl_session); |
| 1260 | server->nfs_client); | ||
| 1261 | goto out; | 1259 | goto out; |
| 1262 | case -NFS4ERR_STALE_CLIENTID: | 1260 | case -NFS4ERR_STALE_CLIENTID: |
| 1263 | case -NFS4ERR_STALE_STATEID: | 1261 | case -NFS4ERR_STALE_STATEID: |
| 1264 | case -NFS4ERR_EXPIRED: | 1262 | case -NFS4ERR_EXPIRED: |
| 1265 | /* Don't recall a delegation if it was lost */ | 1263 | /* Don't recall a delegation if it was lost */ |
| 1266 | nfs4_schedule_state_recovery(server->nfs_client); | 1264 | nfs4_schedule_lease_recovery(server->nfs_client); |
| 1267 | goto out; | 1265 | goto out; |
| 1268 | case -ERESTARTSYS: | 1266 | case -ERESTARTSYS: |
| 1269 | /* | 1267 | /* |
| @@ -1272,7 +1270,7 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state | |||
| 1272 | */ | 1270 | */ |
| 1273 | case -NFS4ERR_ADMIN_REVOKED: | 1271 | case -NFS4ERR_ADMIN_REVOKED: |
| 1274 | case -NFS4ERR_BAD_STATEID: | 1272 | case -NFS4ERR_BAD_STATEID: |
| 1275 | nfs4_state_mark_reclaim_nograce(server->nfs_client, state); | 1273 | nfs4_schedule_stateid_recovery(server, state); |
| 1276 | case -EKEYEXPIRED: | 1274 | case -EKEYEXPIRED: |
| 1277 | /* | 1275 | /* |
| 1278 | * User RPCSEC_GSS context has expired. | 1276 | * User RPCSEC_GSS context has expired. |
| @@ -1588,7 +1586,7 @@ static int nfs4_recover_expired_lease(struct nfs_server *server) | |||
| 1588 | if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) && | 1586 | if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) && |
| 1589 | !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state)) | 1587 | !test_bit(NFS4CLNT_CHECK_LEASE,&clp->cl_state)) |
| 1590 | break; | 1588 | break; |
| 1591 | nfs4_schedule_state_recovery(clp); | 1589 | nfs4_schedule_state_manager(clp); |
| 1592 | ret = -EIO; | 1590 | ret = -EIO; |
| 1593 | } | 1591 | } |
| 1594 | return ret; | 1592 | return ret; |
| @@ -3179,7 +3177,7 @@ static void nfs4_renew_done(struct rpc_task *task, void *calldata) | |||
| 3179 | if (task->tk_status < 0) { | 3177 | if (task->tk_status < 0) { |
| 3180 | /* Unless we're shutting down, schedule state recovery! */ | 3178 | /* Unless we're shutting down, schedule state recovery! */ |
| 3181 | if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) != 0) | 3179 | if (test_bit(NFS_CS_RENEWD, &clp->cl_res_state) != 0) |
| 3182 | nfs4_schedule_state_recovery(clp); | 3180 | nfs4_schedule_lease_recovery(clp); |
| 3183 | return; | 3181 | return; |
| 3184 | } | 3182 | } |
| 3185 | do_renew_lease(clp, timestamp); | 3183 | do_renew_lease(clp, timestamp); |
| @@ -3262,7 +3260,7 @@ static int buf_to_pages_noslab(const void *buf, size_t buflen, | |||
| 3262 | spages = pages; | 3260 | spages = pages; |
| 3263 | 3261 | ||
| 3264 | do { | 3262 | do { |
| 3265 | len = min(PAGE_CACHE_SIZE, buflen); | 3263 | len = min_t(size_t, PAGE_CACHE_SIZE, buflen); |
| 3266 | newpage = alloc_page(GFP_KERNEL); | 3264 | newpage = alloc_page(GFP_KERNEL); |
| 3267 | 3265 | ||
| 3268 | if (newpage == NULL) | 3266 | if (newpage == NULL) |
| @@ -3504,12 +3502,13 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
| 3504 | case -NFS4ERR_OPENMODE: | 3502 | case -NFS4ERR_OPENMODE: |
| 3505 | if (state == NULL) | 3503 | if (state == NULL) |
| 3506 | break; | 3504 | break; |
| 3507 | nfs4_state_mark_reclaim_nograce(clp, state); | 3505 | nfs4_schedule_stateid_recovery(server, state); |
| 3508 | goto do_state_recovery; | 3506 | goto wait_on_recovery; |
| 3509 | case -NFS4ERR_STALE_STATEID: | 3507 | case -NFS4ERR_STALE_STATEID: |
| 3510 | case -NFS4ERR_STALE_CLIENTID: | 3508 | case -NFS4ERR_STALE_CLIENTID: |
| 3511 | case -NFS4ERR_EXPIRED: | 3509 | case -NFS4ERR_EXPIRED: |
| 3512 | goto do_state_recovery; | 3510 | nfs4_schedule_lease_recovery(clp); |
| 3511 | goto wait_on_recovery; | ||
| 3513 | #if defined(CONFIG_NFS_V4_1) | 3512 | #if defined(CONFIG_NFS_V4_1) |
| 3514 | case -NFS4ERR_BADSESSION: | 3513 | case -NFS4ERR_BADSESSION: |
| 3515 | case -NFS4ERR_BADSLOT: | 3514 | case -NFS4ERR_BADSLOT: |
| @@ -3520,7 +3519,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
| 3520 | case -NFS4ERR_SEQ_MISORDERED: | 3519 | case -NFS4ERR_SEQ_MISORDERED: |
| 3521 | dprintk("%s ERROR %d, Reset session\n", __func__, | 3520 | dprintk("%s ERROR %d, Reset session\n", __func__, |
| 3522 | task->tk_status); | 3521 | task->tk_status); |
| 3523 | nfs4_schedule_state_recovery(clp); | 3522 | nfs4_schedule_session_recovery(clp->cl_session); |
| 3524 | task->tk_status = 0; | 3523 | task->tk_status = 0; |
| 3525 | return -EAGAIN; | 3524 | return -EAGAIN; |
| 3526 | #endif /* CONFIG_NFS_V4_1 */ | 3525 | #endif /* CONFIG_NFS_V4_1 */ |
| @@ -3537,9 +3536,8 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
| 3537 | } | 3536 | } |
| 3538 | task->tk_status = nfs4_map_errors(task->tk_status); | 3537 | task->tk_status = nfs4_map_errors(task->tk_status); |
| 3539 | return 0; | 3538 | return 0; |
| 3540 | do_state_recovery: | 3539 | wait_on_recovery: |
| 3541 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); | 3540 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); |
| 3542 | nfs4_schedule_state_recovery(clp); | ||
| 3543 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) | 3541 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) |
| 3544 | rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); | 3542 | rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); |
| 3545 | task->tk_status = 0; | 3543 | task->tk_status = 0; |
| @@ -4150,7 +4148,7 @@ static void nfs4_lock_release(void *calldata) | |||
| 4150 | task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, | 4148 | task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, |
| 4151 | data->arg.lock_seqid); | 4149 | data->arg.lock_seqid); |
| 4152 | if (!IS_ERR(task)) | 4150 | if (!IS_ERR(task)) |
| 4153 | rpc_put_task(task); | 4151 | rpc_put_task_async(task); |
| 4154 | dprintk("%s: cancelling lock!\n", __func__); | 4152 | dprintk("%s: cancelling lock!\n", __func__); |
| 4155 | } else | 4153 | } else |
| 4156 | nfs_free_seqid(data->arg.lock_seqid); | 4154 | nfs_free_seqid(data->arg.lock_seqid); |
| @@ -4174,23 +4172,18 @@ static const struct rpc_call_ops nfs4_recover_lock_ops = { | |||
| 4174 | 4172 | ||
| 4175 | static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error) | 4173 | static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_state *lsp, int new_lock_owner, int error) |
| 4176 | { | 4174 | { |
| 4177 | struct nfs_client *clp = server->nfs_client; | ||
| 4178 | struct nfs4_state *state = lsp->ls_state; | ||
| 4179 | |||
| 4180 | switch (error) { | 4175 | switch (error) { |
| 4181 | case -NFS4ERR_ADMIN_REVOKED: | 4176 | case -NFS4ERR_ADMIN_REVOKED: |
| 4182 | case -NFS4ERR_BAD_STATEID: | 4177 | case -NFS4ERR_BAD_STATEID: |
| 4183 | case -NFS4ERR_EXPIRED: | 4178 | lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; |
| 4184 | if (new_lock_owner != 0 || | 4179 | if (new_lock_owner != 0 || |
| 4185 | (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) | 4180 | (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) |
| 4186 | nfs4_state_mark_reclaim_nograce(clp, state); | 4181 | nfs4_schedule_stateid_recovery(server, lsp->ls_state); |
| 4187 | lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; | ||
| 4188 | break; | 4182 | break; |
| 4189 | case -NFS4ERR_STALE_STATEID: | 4183 | case -NFS4ERR_STALE_STATEID: |
| 4190 | if (new_lock_owner != 0 || | ||
| 4191 | (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) | ||
| 4192 | nfs4_state_mark_reclaim_reboot(clp, state); | ||
| 4193 | lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; | 4184 | lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; |
| 4185 | case -NFS4ERR_EXPIRED: | ||
| 4186 | nfs4_schedule_lease_recovery(server->nfs_client); | ||
| 4194 | }; | 4187 | }; |
| 4195 | } | 4188 | } |
| 4196 | 4189 | ||
| @@ -4406,12 +4399,14 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) | |||
| 4406 | case -NFS4ERR_EXPIRED: | 4399 | case -NFS4ERR_EXPIRED: |
| 4407 | case -NFS4ERR_STALE_CLIENTID: | 4400 | case -NFS4ERR_STALE_CLIENTID: |
| 4408 | case -NFS4ERR_STALE_STATEID: | 4401 | case -NFS4ERR_STALE_STATEID: |
| 4402 | nfs4_schedule_lease_recovery(server->nfs_client); | ||
| 4403 | goto out; | ||
| 4409 | case -NFS4ERR_BADSESSION: | 4404 | case -NFS4ERR_BADSESSION: |
| 4410 | case -NFS4ERR_BADSLOT: | 4405 | case -NFS4ERR_BADSLOT: |
| 4411 | case -NFS4ERR_BAD_HIGH_SLOT: | 4406 | case -NFS4ERR_BAD_HIGH_SLOT: |
| 4412 | case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: | 4407 | case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: |
| 4413 | case -NFS4ERR_DEADSESSION: | 4408 | case -NFS4ERR_DEADSESSION: |
| 4414 | nfs4_schedule_state_recovery(server->nfs_client); | 4409 | nfs4_schedule_session_recovery(server->nfs_client->cl_session); |
| 4415 | goto out; | 4410 | goto out; |
| 4416 | case -ERESTARTSYS: | 4411 | case -ERESTARTSYS: |
| 4417 | /* | 4412 | /* |
| @@ -4421,7 +4416,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) | |||
| 4421 | case -NFS4ERR_ADMIN_REVOKED: | 4416 | case -NFS4ERR_ADMIN_REVOKED: |
| 4422 | case -NFS4ERR_BAD_STATEID: | 4417 | case -NFS4ERR_BAD_STATEID: |
| 4423 | case -NFS4ERR_OPENMODE: | 4418 | case -NFS4ERR_OPENMODE: |
| 4424 | nfs4_state_mark_reclaim_nograce(server->nfs_client, state); | 4419 | nfs4_schedule_stateid_recovery(server, state); |
| 4425 | err = 0; | 4420 | err = 0; |
| 4426 | goto out; | 4421 | goto out; |
| 4427 | case -EKEYEXPIRED: | 4422 | case -EKEYEXPIRED: |
| @@ -5028,10 +5023,20 @@ int nfs4_proc_create_session(struct nfs_client *clp) | |||
| 5028 | int status; | 5023 | int status; |
| 5029 | unsigned *ptr; | 5024 | unsigned *ptr; |
| 5030 | struct nfs4_session *session = clp->cl_session; | 5025 | struct nfs4_session *session = clp->cl_session; |
| 5026 | long timeout = 0; | ||
| 5027 | int err; | ||
| 5031 | 5028 | ||
| 5032 | dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); | 5029 | dprintk("--> %s clp=%p session=%p\n", __func__, clp, session); |
| 5033 | 5030 | ||
| 5034 | status = _nfs4_proc_create_session(clp); | 5031 | do { |
| 5032 | status = _nfs4_proc_create_session(clp); | ||
| 5033 | if (status == -NFS4ERR_DELAY) { | ||
| 5034 | err = nfs4_delay(clp->cl_rpcclient, &timeout); | ||
| 5035 | if (err) | ||
| 5036 | status = err; | ||
| 5037 | } | ||
| 5038 | } while (status == -NFS4ERR_DELAY); | ||
| 5039 | |||
| 5035 | if (status) | 5040 | if (status) |
| 5036 | goto out; | 5041 | goto out; |
| 5037 | 5042 | ||
| @@ -5140,7 +5145,7 @@ static int nfs41_sequence_handle_errors(struct rpc_task *task, struct nfs_client | |||
| 5140 | rpc_delay(task, NFS4_POLL_RETRY_MAX); | 5145 | rpc_delay(task, NFS4_POLL_RETRY_MAX); |
| 5141 | return -EAGAIN; | 5146 | return -EAGAIN; |
| 5142 | default: | 5147 | default: |
| 5143 | nfs4_schedule_state_recovery(clp); | 5148 | nfs4_schedule_lease_recovery(clp); |
| 5144 | } | 5149 | } |
| 5145 | return 0; | 5150 | return 0; |
| 5146 | } | 5151 | } |
| @@ -5227,7 +5232,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr | |||
| 5227 | if (IS_ERR(task)) | 5232 | if (IS_ERR(task)) |
| 5228 | ret = PTR_ERR(task); | 5233 | ret = PTR_ERR(task); |
| 5229 | else | 5234 | else |
| 5230 | rpc_put_task(task); | 5235 | rpc_put_task_async(task); |
| 5231 | dprintk("<-- %s status=%d\n", __func__, ret); | 5236 | dprintk("<-- %s status=%d\n", __func__, ret); |
| 5232 | return ret; | 5237 | return ret; |
| 5233 | } | 5238 | } |
| @@ -5243,8 +5248,13 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred) | |||
| 5243 | goto out; | 5248 | goto out; |
| 5244 | } | 5249 | } |
| 5245 | ret = rpc_wait_for_completion_task(task); | 5250 | ret = rpc_wait_for_completion_task(task); |
| 5246 | if (!ret) | 5251 | if (!ret) { |
| 5252 | struct nfs4_sequence_res *res = task->tk_msg.rpc_resp; | ||
| 5253 | |||
| 5254 | if (task->tk_status == 0) | ||
| 5255 | nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags); | ||
| 5247 | ret = task->tk_status; | 5256 | ret = task->tk_status; |
| 5257 | } | ||
| 5248 | rpc_put_task(task); | 5258 | rpc_put_task(task); |
| 5249 | out: | 5259 | out: |
| 5250 | dprintk("<-- %s status=%d\n", __func__, ret); | 5260 | dprintk("<-- %s status=%d\n", __func__, ret); |
| @@ -5281,7 +5291,7 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf | |||
| 5281 | rpc_delay(task, NFS4_POLL_RETRY_MAX); | 5291 | rpc_delay(task, NFS4_POLL_RETRY_MAX); |
| 5282 | return -EAGAIN; | 5292 | return -EAGAIN; |
| 5283 | default: | 5293 | default: |
| 5284 | nfs4_schedule_state_recovery(clp); | 5294 | nfs4_schedule_lease_recovery(clp); |
| 5285 | } | 5295 | } |
| 5286 | return 0; | 5296 | return 0; |
| 5287 | } | 5297 | } |
| @@ -5349,6 +5359,9 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp) | |||
| 5349 | status = PTR_ERR(task); | 5359 | status = PTR_ERR(task); |
| 5350 | goto out; | 5360 | goto out; |
| 5351 | } | 5361 | } |
| 5362 | status = nfs4_wait_for_completion_rpc_task(task); | ||
| 5363 | if (status == 0) | ||
| 5364 | status = task->tk_status; | ||
| 5352 | rpc_put_task(task); | 5365 | rpc_put_task(task); |
| 5353 | return 0; | 5366 | return 0; |
| 5354 | out: | 5367 | out: |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index e6742b57a04c..0592288f9f06 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
| @@ -1007,9 +1007,9 @@ void nfs4_schedule_state_manager(struct nfs_client *clp) | |||
| 1007 | } | 1007 | } |
| 1008 | 1008 | ||
| 1009 | /* | 1009 | /* |
| 1010 | * Schedule a state recovery attempt | 1010 | * Schedule a lease recovery attempt |
| 1011 | */ | 1011 | */ |
| 1012 | void nfs4_schedule_state_recovery(struct nfs_client *clp) | 1012 | void nfs4_schedule_lease_recovery(struct nfs_client *clp) |
| 1013 | { | 1013 | { |
| 1014 | if (!clp) | 1014 | if (!clp) |
| 1015 | return; | 1015 | return; |
| @@ -1018,7 +1018,7 @@ void nfs4_schedule_state_recovery(struct nfs_client *clp) | |||
| 1018 | nfs4_schedule_state_manager(clp); | 1018 | nfs4_schedule_state_manager(clp); |
| 1019 | } | 1019 | } |
| 1020 | 1020 | ||
| 1021 | int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state) | 1021 | static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state) |
| 1022 | { | 1022 | { |
| 1023 | 1023 | ||
| 1024 | set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags); | 1024 | set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags); |
| @@ -1032,7 +1032,7 @@ int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *st | |||
| 1032 | return 1; | 1032 | return 1; |
| 1033 | } | 1033 | } |
| 1034 | 1034 | ||
| 1035 | int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state) | 1035 | static int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state) |
| 1036 | { | 1036 | { |
| 1037 | set_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags); | 1037 | set_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags); |
| 1038 | clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags); | 1038 | clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags); |
| @@ -1041,6 +1041,14 @@ int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *s | |||
| 1041 | return 1; | 1041 | return 1; |
| 1042 | } | 1042 | } |
| 1043 | 1043 | ||
| 1044 | void nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4_state *state) | ||
| 1045 | { | ||
| 1046 | struct nfs_client *clp = server->nfs_client; | ||
| 1047 | |||
| 1048 | nfs4_state_mark_reclaim_nograce(clp, state); | ||
| 1049 | nfs4_schedule_state_manager(clp); | ||
| 1050 | } | ||
| 1051 | |||
| 1044 | static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops) | 1052 | static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops) |
| 1045 | { | 1053 | { |
| 1046 | struct inode *inode = state->inode; | 1054 | struct inode *inode = state->inode; |
| @@ -1436,10 +1444,15 @@ static int nfs4_reclaim_lease(struct nfs_client *clp) | |||
| 1436 | } | 1444 | } |
| 1437 | 1445 | ||
| 1438 | #ifdef CONFIG_NFS_V4_1 | 1446 | #ifdef CONFIG_NFS_V4_1 |
| 1447 | void nfs4_schedule_session_recovery(struct nfs4_session *session) | ||
| 1448 | { | ||
| 1449 | nfs4_schedule_lease_recovery(session->clp); | ||
| 1450 | } | ||
| 1451 | |||
| 1439 | void nfs41_handle_recall_slot(struct nfs_client *clp) | 1452 | void nfs41_handle_recall_slot(struct nfs_client *clp) |
| 1440 | { | 1453 | { |
| 1441 | set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); | 1454 | set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); |
| 1442 | nfs4_schedule_state_recovery(clp); | 1455 | nfs4_schedule_state_manager(clp); |
| 1443 | } | 1456 | } |
| 1444 | 1457 | ||
| 1445 | static void nfs4_reset_all_state(struct nfs_client *clp) | 1458 | static void nfs4_reset_all_state(struct nfs_client *clp) |
| @@ -1447,7 +1460,7 @@ static void nfs4_reset_all_state(struct nfs_client *clp) | |||
| 1447 | if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) { | 1460 | if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) { |
| 1448 | clp->cl_boot_time = CURRENT_TIME; | 1461 | clp->cl_boot_time = CURRENT_TIME; |
| 1449 | nfs4_state_start_reclaim_nograce(clp); | 1462 | nfs4_state_start_reclaim_nograce(clp); |
| 1450 | nfs4_schedule_state_recovery(clp); | 1463 | nfs4_schedule_state_manager(clp); |
| 1451 | } | 1464 | } |
| 1452 | } | 1465 | } |
| 1453 | 1466 | ||
| @@ -1455,7 +1468,7 @@ static void nfs41_handle_server_reboot(struct nfs_client *clp) | |||
| 1455 | { | 1468 | { |
| 1456 | if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) { | 1469 | if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) { |
| 1457 | nfs4_state_start_reclaim_reboot(clp); | 1470 | nfs4_state_start_reclaim_reboot(clp); |
| 1458 | nfs4_schedule_state_recovery(clp); | 1471 | nfs4_schedule_state_manager(clp); |
| 1459 | } | 1472 | } |
| 1460 | } | 1473 | } |
| 1461 | 1474 | ||
| @@ -1475,7 +1488,7 @@ static void nfs41_handle_cb_path_down(struct nfs_client *clp) | |||
| 1475 | { | 1488 | { |
| 1476 | nfs_expire_all_delegations(clp); | 1489 | nfs_expire_all_delegations(clp); |
| 1477 | if (test_and_set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) == 0) | 1490 | if (test_and_set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) == 0) |
| 1478 | nfs4_schedule_state_recovery(clp); | 1491 | nfs4_schedule_state_manager(clp); |
| 1479 | } | 1492 | } |
| 1480 | 1493 | ||
| 1481 | void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) | 1494 | void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 4e2c168b6ee9..94d50e86a124 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
| @@ -1660,7 +1660,7 @@ static void encode_create_session(struct xdr_stream *xdr, | |||
| 1660 | 1660 | ||
| 1661 | p = reserve_space(xdr, 20 + 2*28 + 20 + len + 12); | 1661 | p = reserve_space(xdr, 20 + 2*28 + 20 + len + 12); |
| 1662 | *p++ = cpu_to_be32(OP_CREATE_SESSION); | 1662 | *p++ = cpu_to_be32(OP_CREATE_SESSION); |
| 1663 | p = xdr_encode_hyper(p, clp->cl_ex_clid); | 1663 | p = xdr_encode_hyper(p, clp->cl_clientid); |
| 1664 | *p++ = cpu_to_be32(clp->cl_seqid); /*Sequence id */ | 1664 | *p++ = cpu_to_be32(clp->cl_seqid); /*Sequence id */ |
| 1665 | *p++ = cpu_to_be32(args->flags); /*flags */ | 1665 | *p++ = cpu_to_be32(args->flags); /*flags */ |
| 1666 | 1666 | ||
| @@ -4694,7 +4694,7 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
| 4694 | p = xdr_inline_decode(xdr, 8); | 4694 | p = xdr_inline_decode(xdr, 8); |
| 4695 | if (unlikely(!p)) | 4695 | if (unlikely(!p)) |
| 4696 | goto out_overflow; | 4696 | goto out_overflow; |
| 4697 | xdr_decode_hyper(p, &clp->cl_ex_clid); | 4697 | xdr_decode_hyper(p, &clp->cl_clientid); |
| 4698 | p = xdr_inline_decode(xdr, 12); | 4698 | p = xdr_inline_decode(xdr, 12); |
| 4699 | if (unlikely(!p)) | 4699 | if (unlikely(!p)) |
| 4700 | goto out_overflow; | 4700 | goto out_overflow; |
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 903908a20023..c541093a5bf2 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c | |||
| @@ -86,11 +86,14 @@ | |||
| 86 | /* Default path we try to mount. "%s" gets replaced by our IP address */ | 86 | /* Default path we try to mount. "%s" gets replaced by our IP address */ |
| 87 | #define NFS_ROOT "/tftpboot/%s" | 87 | #define NFS_ROOT "/tftpboot/%s" |
| 88 | 88 | ||
| 89 | /* Default NFSROOT mount options. */ | ||
| 90 | #define NFS_DEF_OPTIONS "udp" | ||
| 91 | |||
| 89 | /* Parameters passed from the kernel command line */ | 92 | /* Parameters passed from the kernel command line */ |
| 90 | static char nfs_root_parms[256] __initdata = ""; | 93 | static char nfs_root_parms[256] __initdata = ""; |
| 91 | 94 | ||
| 92 | /* Text-based mount options passed to super.c */ | 95 | /* Text-based mount options passed to super.c */ |
| 93 | static char nfs_root_options[256] __initdata = ""; | 96 | static char nfs_root_options[256] __initdata = NFS_DEF_OPTIONS; |
| 94 | 97 | ||
| 95 | /* Address of NFS server */ | 98 | /* Address of NFS server */ |
| 96 | static __be32 servaddr __initdata = htonl(INADDR_NONE); | 99 | static __be32 servaddr __initdata = htonl(INADDR_NONE); |
| @@ -160,8 +163,14 @@ static int __init root_nfs_copy(char *dest, const char *src, | |||
| 160 | } | 163 | } |
| 161 | 164 | ||
| 162 | static int __init root_nfs_cat(char *dest, const char *src, | 165 | static int __init root_nfs_cat(char *dest, const char *src, |
| 163 | const size_t destlen) | 166 | const size_t destlen) |
| 164 | { | 167 | { |
| 168 | size_t len = strlen(dest); | ||
| 169 | |||
| 170 | if (len && dest[len - 1] != ',') | ||
| 171 | if (strlcat(dest, ",", destlen) > destlen) | ||
| 172 | return -1; | ||
| 173 | |||
| 165 | if (strlcat(dest, src, destlen) > destlen) | 174 | if (strlcat(dest, src, destlen) > destlen) |
| 166 | return -1; | 175 | return -1; |
| 167 | return 0; | 176 | return 0; |
| @@ -194,16 +203,6 @@ static int __init root_nfs_parse_options(char *incoming, char *exppath, | |||
| 194 | if (root_nfs_cat(nfs_root_options, incoming, | 203 | if (root_nfs_cat(nfs_root_options, incoming, |
| 195 | sizeof(nfs_root_options))) | 204 | sizeof(nfs_root_options))) |
| 196 | return -1; | 205 | return -1; |
| 197 | |||
| 198 | /* | ||
| 199 | * Possibly prepare for more options to be appended | ||
| 200 | */ | ||
| 201 | if (nfs_root_options[0] != '\0' && | ||
| 202 | nfs_root_options[strlen(nfs_root_options)] != ',') | ||
| 203 | if (root_nfs_cat(nfs_root_options, ",", | ||
| 204 | sizeof(nfs_root_options))) | ||
| 205 | return -1; | ||
| 206 | |||
| 207 | return 0; | 206 | return 0; |
| 208 | } | 207 | } |
| 209 | 208 | ||
| @@ -217,7 +216,7 @@ static int __init root_nfs_parse_options(char *incoming, char *exppath, | |||
| 217 | */ | 216 | */ |
| 218 | static int __init root_nfs_data(char *cmdline) | 217 | static int __init root_nfs_data(char *cmdline) |
| 219 | { | 218 | { |
| 220 | char addr_option[sizeof("nolock,addr=") + INET_ADDRSTRLEN + 1]; | 219 | char mand_options[sizeof("nolock,addr=") + INET_ADDRSTRLEN + 1]; |
| 221 | int len, retval = -1; | 220 | int len, retval = -1; |
| 222 | char *tmp = NULL; | 221 | char *tmp = NULL; |
| 223 | const size_t tmplen = sizeof(nfs_export_path); | 222 | const size_t tmplen = sizeof(nfs_export_path); |
| @@ -244,9 +243,9 @@ static int __init root_nfs_data(char *cmdline) | |||
| 244 | * Append mandatory options for nfsroot so they override | 243 | * Append mandatory options for nfsroot so they override |
| 245 | * what has come before | 244 | * what has come before |
| 246 | */ | 245 | */ |
| 247 | snprintf(addr_option, sizeof(addr_option), "nolock,addr=%pI4", | 246 | snprintf(mand_options, sizeof(mand_options), "nolock,addr=%pI4", |
| 248 | &servaddr); | 247 | &servaddr); |
| 249 | if (root_nfs_cat(nfs_root_options, addr_option, | 248 | if (root_nfs_cat(nfs_root_options, mand_options, |
| 250 | sizeof(nfs_root_options))) | 249 | sizeof(nfs_root_options))) |
| 251 | goto out_optionstoolong; | 250 | goto out_optionstoolong; |
| 252 | 251 | ||
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index e313a51acdd1..6481d537d69d 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c | |||
| @@ -180,7 +180,7 @@ static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct n | |||
| 180 | task_setup_data.rpc_client = NFS_CLIENT(dir); | 180 | task_setup_data.rpc_client = NFS_CLIENT(dir); |
| 181 | task = rpc_run_task(&task_setup_data); | 181 | task = rpc_run_task(&task_setup_data); |
| 182 | if (!IS_ERR(task)) | 182 | if (!IS_ERR(task)) |
| 183 | rpc_put_task(task); | 183 | rpc_put_task_async(task); |
| 184 | return 1; | 184 | return 1; |
| 185 | } | 185 | } |
| 186 | 186 | ||
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index c8278f4046cb..42b92d7a9cc4 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
| @@ -1292,6 +1292,8 @@ static int nfs_commit_rpcsetup(struct list_head *head, | |||
| 1292 | task = rpc_run_task(&task_setup_data); | 1292 | task = rpc_run_task(&task_setup_data); |
| 1293 | if (IS_ERR(task)) | 1293 | if (IS_ERR(task)) |
| 1294 | return PTR_ERR(task); | 1294 | return PTR_ERR(task); |
| 1295 | if (how & FLUSH_SYNC) | ||
| 1296 | rpc_wait_for_completion_task(task); | ||
| 1295 | rpc_put_task(task); | 1297 | rpc_put_task(task); |
| 1296 | return 0; | 1298 | return 0; |
| 1297 | } | 1299 | } |
diff --git a/fs/partitions/osf.c b/fs/partitions/osf.c index 48cec7cbca17..be03a0b08b47 100644 --- a/fs/partitions/osf.c +++ b/fs/partitions/osf.c | |||
| @@ -10,10 +10,13 @@ | |||
| 10 | #include "check.h" | 10 | #include "check.h" |
| 11 | #include "osf.h" | 11 | #include "osf.h" |
| 12 | 12 | ||
| 13 | #define MAX_OSF_PARTITIONS 8 | ||
| 14 | |||
| 13 | int osf_partition(struct parsed_partitions *state) | 15 | int osf_partition(struct parsed_partitions *state) |
| 14 | { | 16 | { |
| 15 | int i; | 17 | int i; |
| 16 | int slot = 1; | 18 | int slot = 1; |
| 19 | unsigned int npartitions; | ||
| 17 | Sector sect; | 20 | Sector sect; |
| 18 | unsigned char *data; | 21 | unsigned char *data; |
| 19 | struct disklabel { | 22 | struct disklabel { |
| @@ -45,7 +48,7 @@ int osf_partition(struct parsed_partitions *state) | |||
| 45 | u8 p_fstype; | 48 | u8 p_fstype; |
| 46 | u8 p_frag; | 49 | u8 p_frag; |
| 47 | __le16 p_cpg; | 50 | __le16 p_cpg; |
| 48 | } d_partitions[8]; | 51 | } d_partitions[MAX_OSF_PARTITIONS]; |
| 49 | } * label; | 52 | } * label; |
| 50 | struct d_partition * partition; | 53 | struct d_partition * partition; |
| 51 | 54 | ||
| @@ -63,7 +66,12 @@ int osf_partition(struct parsed_partitions *state) | |||
| 63 | put_dev_sector(sect); | 66 | put_dev_sector(sect); |
| 64 | return 0; | 67 | return 0; |
| 65 | } | 68 | } |
| 66 | for (i = 0 ; i < le16_to_cpu(label->d_npartitions); i++, partition++) { | 69 | npartitions = le16_to_cpu(label->d_npartitions); |
| 70 | if (npartitions > MAX_OSF_PARTITIONS) { | ||
| 71 | put_dev_sector(sect); | ||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | for (i = 0 ; i < npartitions; i++, partition++) { | ||
| 67 | if (slot == state->limit) | 75 | if (slot == state->limit) |
| 68 | break; | 76 | break; |
| 69 | if (le32_to_cpu(partition->p_size)) | 77 | if (le32_to_cpu(partition->p_size)) |
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index b197563913bf..3e112de12d8d 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h | |||
| @@ -68,11 +68,7 @@ struct nfs_client { | |||
| 68 | unsigned char cl_id_uniquifier; | 68 | unsigned char cl_id_uniquifier; |
| 69 | u32 cl_cb_ident; /* v4.0 callback identifier */ | 69 | u32 cl_cb_ident; /* v4.0 callback identifier */ |
| 70 | const struct nfs4_minor_version_ops *cl_mvops; | 70 | const struct nfs4_minor_version_ops *cl_mvops; |
| 71 | #endif /* CONFIG_NFS_V4 */ | ||
| 72 | 71 | ||
| 73 | #ifdef CONFIG_NFS_V4_1 | ||
| 74 | /* clientid returned from EXCHANGE_ID, used by session operations */ | ||
| 75 | u64 cl_ex_clid; | ||
| 76 | /* The sequence id to use for the next CREATE_SESSION */ | 72 | /* The sequence id to use for the next CREATE_SESSION */ |
| 77 | u32 cl_seqid; | 73 | u32 cl_seqid; |
| 78 | /* The flags used for obtaining the clientid during EXCHANGE_ID */ | 74 | /* The flags used for obtaining the clientid during EXCHANGE_ID */ |
| @@ -80,7 +76,7 @@ struct nfs_client { | |||
| 80 | struct nfs4_session *cl_session; /* sharred session */ | 76 | struct nfs4_session *cl_session; /* sharred session */ |
| 81 | struct list_head cl_layouts; | 77 | struct list_head cl_layouts; |
| 82 | struct pnfs_deviceid_cache *cl_devid_cache; /* pNFS deviceid cache */ | 78 | struct pnfs_deviceid_cache *cl_devid_cache; /* pNFS deviceid cache */ |
| 83 | #endif /* CONFIG_NFS_V4_1 */ | 79 | #endif /* CONFIG_NFS_V4 */ |
| 84 | 80 | ||
| 85 | #ifdef CONFIG_NFS_FSCACHE | 81 | #ifdef CONFIG_NFS_FSCACHE |
| 86 | struct fscache_cookie *fscache; /* client index cache cookie */ | 82 | struct fscache_cookie *fscache; /* client index cache cookie */ |
| @@ -185,7 +181,7 @@ struct nfs_server { | |||
| 185 | /* maximum number of slots to use */ | 181 | /* maximum number of slots to use */ |
| 186 | #define NFS4_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE | 182 | #define NFS4_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE |
| 187 | 183 | ||
| 188 | #if defined(CONFIG_NFS_V4_1) | 184 | #if defined(CONFIG_NFS_V4) |
| 189 | 185 | ||
| 190 | /* Sessions */ | 186 | /* Sessions */ |
| 191 | #define SLOT_TABLE_SZ (NFS4_MAX_SLOT_TABLE/(8*sizeof(long))) | 187 | #define SLOT_TABLE_SZ (NFS4_MAX_SLOT_TABLE/(8*sizeof(long))) |
| @@ -225,5 +221,5 @@ struct nfs4_session { | |||
| 225 | struct nfs_client *clp; | 221 | struct nfs_client *clp; |
| 226 | }; | 222 | }; |
| 227 | 223 | ||
| 228 | #endif /* CONFIG_NFS_V4_1 */ | 224 | #endif /* CONFIG_NFS_V4 */ |
| 229 | #endif | 225 | #endif |
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 88513fd8e208..d81db8012c63 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h | |||
| @@ -212,6 +212,7 @@ struct rpc_task *rpc_run_task(const struct rpc_task_setup *); | |||
| 212 | struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req, | 212 | struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req, |
| 213 | const struct rpc_call_ops *ops); | 213 | const struct rpc_call_ops *ops); |
| 214 | void rpc_put_task(struct rpc_task *); | 214 | void rpc_put_task(struct rpc_task *); |
| 215 | void rpc_put_task_async(struct rpc_task *); | ||
| 215 | void rpc_exit_task(struct rpc_task *); | 216 | void rpc_exit_task(struct rpc_task *); |
| 216 | void rpc_exit(struct rpc_task *, int); | 217 | void rpc_exit(struct rpc_task *, int); |
| 217 | void rpc_release_calldata(const struct rpc_call_ops *, void *); | 218 | void rpc_release_calldata(const struct rpc_call_ops *, void *); |
diff --git a/kernel/sched.c b/kernel/sched.c index 18d38e4ec7ba..42eab5a8437d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -4213,6 +4213,7 @@ void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key) | |||
| 4213 | { | 4213 | { |
| 4214 | __wake_up_common(q, mode, 1, 0, key); | 4214 | __wake_up_common(q, mode, 1, 0, key); |
| 4215 | } | 4215 | } |
| 4216 | EXPORT_SYMBOL_GPL(__wake_up_locked_key); | ||
| 4216 | 4217 | ||
| 4217 | /** | 4218 | /** |
| 4218 | * __wake_up_sync_key - wake up threads blocked on a waitqueue. | 4219 | * __wake_up_sync_key - wake up threads blocked on a waitqueue. |
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index dbe99a5f2073..113e35c47502 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
| @@ -1762,6 +1762,10 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
| 1762 | #ifndef CONFIG_NUMA | 1762 | #ifndef CONFIG_NUMA |
| 1763 | VM_BUG_ON(!*hpage); | 1763 | VM_BUG_ON(!*hpage); |
| 1764 | new_page = *hpage; | 1764 | new_page = *hpage; |
| 1765 | if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) { | ||
| 1766 | up_read(&mm->mmap_sem); | ||
| 1767 | return; | ||
| 1768 | } | ||
| 1765 | #else | 1769 | #else |
| 1766 | VM_BUG_ON(*hpage); | 1770 | VM_BUG_ON(*hpage); |
| 1767 | /* | 1771 | /* |
| @@ -1781,12 +1785,12 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
| 1781 | *hpage = ERR_PTR(-ENOMEM); | 1785 | *hpage = ERR_PTR(-ENOMEM); |
| 1782 | return; | 1786 | return; |
| 1783 | } | 1787 | } |
| 1784 | #endif | ||
| 1785 | if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) { | 1788 | if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) { |
| 1786 | up_read(&mm->mmap_sem); | 1789 | up_read(&mm->mmap_sem); |
| 1787 | put_page(new_page); | 1790 | put_page(new_page); |
| 1788 | return; | 1791 | return; |
| 1789 | } | 1792 | } |
| 1793 | #endif | ||
| 1790 | 1794 | ||
| 1791 | /* after allocating the hugepage upgrade to mmap_sem write mode */ | 1795 | /* after allocating the hugepage upgrade to mmap_sem write mode */ |
| 1792 | up_read(&mm->mmap_sem); | 1796 | up_read(&mm->mmap_sem); |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 243fc09b164e..59e599498e37 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
| @@ -252,23 +252,37 @@ static void rpc_set_active(struct rpc_task *task) | |||
| 252 | 252 | ||
| 253 | /* | 253 | /* |
| 254 | * Mark an RPC call as having completed by clearing the 'active' bit | 254 | * Mark an RPC call as having completed by clearing the 'active' bit |
| 255 | * and then waking up all tasks that were sleeping. | ||
| 255 | */ | 256 | */ |
| 256 | static void rpc_mark_complete_task(struct rpc_task *task) | 257 | static int rpc_complete_task(struct rpc_task *task) |
| 257 | { | 258 | { |
| 258 | smp_mb__before_clear_bit(); | 259 | void *m = &task->tk_runstate; |
| 260 | wait_queue_head_t *wq = bit_waitqueue(m, RPC_TASK_ACTIVE); | ||
| 261 | struct wait_bit_key k = __WAIT_BIT_KEY_INITIALIZER(m, RPC_TASK_ACTIVE); | ||
| 262 | unsigned long flags; | ||
| 263 | int ret; | ||
| 264 | |||
| 265 | spin_lock_irqsave(&wq->lock, flags); | ||
| 259 | clear_bit(RPC_TASK_ACTIVE, &task->tk_runstate); | 266 | clear_bit(RPC_TASK_ACTIVE, &task->tk_runstate); |
| 260 | smp_mb__after_clear_bit(); | 267 | ret = atomic_dec_and_test(&task->tk_count); |
| 261 | wake_up_bit(&task->tk_runstate, RPC_TASK_ACTIVE); | 268 | if (waitqueue_active(wq)) |
| 269 | __wake_up_locked_key(wq, TASK_NORMAL, &k); | ||
| 270 | spin_unlock_irqrestore(&wq->lock, flags); | ||
| 271 | return ret; | ||
| 262 | } | 272 | } |
| 263 | 273 | ||
| 264 | /* | 274 | /* |
| 265 | * Allow callers to wait for completion of an RPC call | 275 | * Allow callers to wait for completion of an RPC call |
| 276 | * | ||
| 277 | * Note the use of out_of_line_wait_on_bit() rather than wait_on_bit() | ||
| 278 | * to enforce taking of the wq->lock and hence avoid races with | ||
| 279 | * rpc_complete_task(). | ||
| 266 | */ | 280 | */ |
| 267 | int __rpc_wait_for_completion_task(struct rpc_task *task, int (*action)(void *)) | 281 | int __rpc_wait_for_completion_task(struct rpc_task *task, int (*action)(void *)) |
| 268 | { | 282 | { |
| 269 | if (action == NULL) | 283 | if (action == NULL) |
| 270 | action = rpc_wait_bit_killable; | 284 | action = rpc_wait_bit_killable; |
| 271 | return wait_on_bit(&task->tk_runstate, RPC_TASK_ACTIVE, | 285 | return out_of_line_wait_on_bit(&task->tk_runstate, RPC_TASK_ACTIVE, |
| 272 | action, TASK_KILLABLE); | 286 | action, TASK_KILLABLE); |
| 273 | } | 287 | } |
| 274 | EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task); | 288 | EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task); |
| @@ -857,34 +871,67 @@ static void rpc_async_release(struct work_struct *work) | |||
| 857 | rpc_free_task(container_of(work, struct rpc_task, u.tk_work)); | 871 | rpc_free_task(container_of(work, struct rpc_task, u.tk_work)); |
| 858 | } | 872 | } |
| 859 | 873 | ||
| 860 | void rpc_put_task(struct rpc_task *task) | 874 | static void rpc_release_resources_task(struct rpc_task *task) |
| 861 | { | 875 | { |
| 862 | if (!atomic_dec_and_test(&task->tk_count)) | ||
| 863 | return; | ||
| 864 | /* Release resources */ | ||
| 865 | if (task->tk_rqstp) | 876 | if (task->tk_rqstp) |
| 866 | xprt_release(task); | 877 | xprt_release(task); |
| 867 | if (task->tk_msg.rpc_cred) | 878 | if (task->tk_msg.rpc_cred) |
| 868 | put_rpccred(task->tk_msg.rpc_cred); | 879 | put_rpccred(task->tk_msg.rpc_cred); |
| 869 | rpc_task_release_client(task); | 880 | rpc_task_release_client(task); |
| 870 | if (task->tk_workqueue != NULL) { | 881 | } |
| 882 | |||
| 883 | static void rpc_final_put_task(struct rpc_task *task, | ||
| 884 | struct workqueue_struct *q) | ||
| 885 | { | ||
| 886 | if (q != NULL) { | ||
| 871 | INIT_WORK(&task->u.tk_work, rpc_async_release); | 887 | INIT_WORK(&task->u.tk_work, rpc_async_release); |
| 872 | queue_work(task->tk_workqueue, &task->u.tk_work); | 888 | queue_work(q, &task->u.tk_work); |
| 873 | } else | 889 | } else |
| 874 | rpc_free_task(task); | 890 | rpc_free_task(task); |
| 875 | } | 891 | } |
| 892 | |||
| 893 | static void rpc_do_put_task(struct rpc_task *task, struct workqueue_struct *q) | ||
| 894 | { | ||
| 895 | if (atomic_dec_and_test(&task->tk_count)) { | ||
| 896 | rpc_release_resources_task(task); | ||
| 897 | rpc_final_put_task(task, q); | ||
| 898 | } | ||
| 899 | } | ||
| 900 | |||
| 901 | void rpc_put_task(struct rpc_task *task) | ||
| 902 | { | ||
| 903 | rpc_do_put_task(task, NULL); | ||
| 904 | } | ||
| 876 | EXPORT_SYMBOL_GPL(rpc_put_task); | 905 | EXPORT_SYMBOL_GPL(rpc_put_task); |
| 877 | 906 | ||
| 907 | void rpc_put_task_async(struct rpc_task *task) | ||
| 908 | { | ||
| 909 | rpc_do_put_task(task, task->tk_workqueue); | ||
| 910 | } | ||
| 911 | EXPORT_SYMBOL_GPL(rpc_put_task_async); | ||
| 912 | |||
| 878 | static void rpc_release_task(struct rpc_task *task) | 913 | static void rpc_release_task(struct rpc_task *task) |
| 879 | { | 914 | { |
| 880 | dprintk("RPC: %5u release task\n", task->tk_pid); | 915 | dprintk("RPC: %5u release task\n", task->tk_pid); |
| 881 | 916 | ||
| 882 | BUG_ON (RPC_IS_QUEUED(task)); | 917 | BUG_ON (RPC_IS_QUEUED(task)); |
| 883 | 918 | ||
| 884 | /* Wake up anyone who is waiting for task completion */ | 919 | rpc_release_resources_task(task); |
| 885 | rpc_mark_complete_task(task); | ||
| 886 | 920 | ||
| 887 | rpc_put_task(task); | 921 | /* |
| 922 | * Note: at this point we have been removed from rpc_clnt->cl_tasks, | ||
| 923 | * so it should be safe to use task->tk_count as a test for whether | ||
| 924 | * or not any other processes still hold references to our rpc_task. | ||
| 925 | */ | ||
| 926 | if (atomic_read(&task->tk_count) != 1 + !RPC_IS_ASYNC(task)) { | ||
| 927 | /* Wake up anyone who may be waiting for task completion */ | ||
| 928 | if (!rpc_complete_task(task)) | ||
| 929 | return; | ||
| 930 | } else { | ||
| 931 | if (!atomic_dec_and_test(&task->tk_count)) | ||
| 932 | return; | ||
| 933 | } | ||
| 934 | rpc_final_put_task(task, task->tk_workqueue); | ||
| 888 | } | 935 | } |
| 889 | 936 | ||
| 890 | int rpciod_up(void) | 937 | int rpciod_up(void) |
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index 9df1eadc912a..1a10dcd999ea 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c | |||
| @@ -1335,6 +1335,7 @@ void svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp, | |||
| 1335 | p, 0, length, DMA_FROM_DEVICE); | 1335 | p, 0, length, DMA_FROM_DEVICE); |
| 1336 | if (ib_dma_mapping_error(xprt->sc_cm_id->device, ctxt->sge[0].addr)) { | 1336 | if (ib_dma_mapping_error(xprt->sc_cm_id->device, ctxt->sge[0].addr)) { |
| 1337 | put_page(p); | 1337 | put_page(p); |
| 1338 | svc_rdma_put_context(ctxt, 1); | ||
| 1338 | return; | 1339 | return; |
| 1339 | } | 1340 | } |
| 1340 | atomic_inc(&xprt->sc_dma_used); | 1341 | atomic_inc(&xprt->sc_dma_used); |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index c431f5a57960..be96d429b475 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -1631,7 +1631,8 @@ static struct socket *xs_create_sock(struct rpc_xprt *xprt, | |||
| 1631 | } | 1631 | } |
| 1632 | xs_reclassify_socket(family, sock); | 1632 | xs_reclassify_socket(family, sock); |
| 1633 | 1633 | ||
| 1634 | if (xs_bind(transport, sock)) { | 1634 | err = xs_bind(transport, sock); |
| 1635 | if (err) { | ||
| 1635 | sock_release(sock); | 1636 | sock_release(sock); |
| 1636 | goto out; | 1637 | goto out; |
| 1637 | } | 1638 | } |
