diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-09-22 12:45:01 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-09-22 12:45:01 -0400 |
commit | 90edf27fb89241917e91155bfdcc7c8e5a587222 (patch) | |
tree | a2d1841cfe382f426a3b6ccb306b0665ad455885 | |
parent | 41945f6ccf1e86f87fddf6b32db9cf431c05fb54 (diff) | |
parent | 8b15575cae7a93a784c3005c42b069edd9ba64dd (diff) |
Merge branch 'linus' into perf/core
Conflicts:
kernel/hw_breakpoint.c
Merge reason: resolve the conflict.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/Kconfig | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/hw_breakpoint.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/hw_breakpoint.c | 40 | ||||
-rw-r--r-- | arch/x86/lguest/boot.c | 13 | ||||
-rw-r--r-- | arch/x86/oprofile/nmi_int.c | 4 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 2 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.h | 2 | ||||
-rw-r--r-- | drivers/char/virtio_console.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_evict.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_suspend.c | 36 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 8 | ||||
-rw-r--r-- | fs/ceph/Kconfig | 1 | ||||
-rw-r--r-- | fs/ceph/addr.c | 7 | ||||
-rw-r--r-- | fs/ceph/caps.c | 27 | ||||
-rw-r--r-- | fs/ceph/dir.c | 10 | ||||
-rw-r--r-- | fs/ceph/inode.c | 11 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 2 | ||||
-rw-r--r-- | fs/ceph/pagelist.c | 12 | ||||
-rw-r--r-- | fs/ceph/snap.c | 92 | ||||
-rw-r--r-- | fs/ceph/super.h | 5 | ||||
-rw-r--r-- | include/linux/fs.h | 4 | ||||
-rw-r--r-- | kernel/sched.c | 8 | ||||
-rw-r--r-- | kernel/sched_fair.c | 2 |
26 files changed, 204 insertions, 145 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 4877a8c8ee16..fe48fc7a3eba 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -32,8 +32,9 @@ config HAVE_OPROFILE | |||
32 | 32 | ||
33 | config KPROBES | 33 | config KPROBES |
34 | bool "Kprobes" | 34 | bool "Kprobes" |
35 | depends on KALLSYMS && MODULES | 35 | depends on MODULES |
36 | depends on HAVE_KPROBES | 36 | depends on HAVE_KPROBES |
37 | select KALLSYMS | ||
37 | help | 38 | help |
38 | Kprobes allows you to trap at almost any kernel address and | 39 | Kprobes allows you to trap at almost any kernel address and |
39 | execute a callback function. register_kprobe() establishes | 40 | execute a callback function. register_kprobe() establishes |
@@ -45,7 +46,6 @@ config OPTPROBES | |||
45 | def_bool y | 46 | def_bool y |
46 | depends on KPROBES && HAVE_OPTPROBES | 47 | depends on KPROBES && HAVE_OPTPROBES |
47 | depends on !PREEMPT | 48 | depends on !PREEMPT |
48 | select KALLSYMS_ALL | ||
49 | 49 | ||
50 | config HAVE_EFFICIENT_UNALIGNED_ACCESS | 50 | config HAVE_EFFICIENT_UNALIGNED_ACCESS |
51 | bool | 51 | bool |
diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h index 528a11e8d3e3..824ca07860d0 100644 --- a/arch/x86/include/asm/hw_breakpoint.h +++ b/arch/x86/include/asm/hw_breakpoint.h | |||
@@ -20,7 +20,7 @@ struct arch_hw_breakpoint { | |||
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | 21 | ||
22 | /* Available HW breakpoint length encodings */ | 22 | /* Available HW breakpoint length encodings */ |
23 | #define X86_BREAKPOINT_LEN_X 0x00 | 23 | #define X86_BREAKPOINT_LEN_X 0x40 |
24 | #define X86_BREAKPOINT_LEN_1 0x40 | 24 | #define X86_BREAKPOINT_LEN_1 0x40 |
25 | #define X86_BREAKPOINT_LEN_2 0x44 | 25 | #define X86_BREAKPOINT_LEN_2 0x44 |
26 | #define X86_BREAKPOINT_LEN_4 0x4c | 26 | #define X86_BREAKPOINT_LEN_4 0x4c |
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index a474ec37c32f..ff15c9dcc25d 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c | |||
@@ -206,11 +206,27 @@ int arch_check_bp_in_kernelspace(struct perf_event *bp) | |||
206 | int arch_bp_generic_fields(int x86_len, int x86_type, | 206 | int arch_bp_generic_fields(int x86_len, int x86_type, |
207 | int *gen_len, int *gen_type) | 207 | int *gen_len, int *gen_type) |
208 | { | 208 | { |
209 | /* Len */ | 209 | /* Type */ |
210 | switch (x86_len) { | 210 | switch (x86_type) { |
211 | case X86_BREAKPOINT_LEN_X: | 211 | case X86_BREAKPOINT_EXECUTE: |
212 | if (x86_len != X86_BREAKPOINT_LEN_X) | ||
213 | return -EINVAL; | ||
214 | |||
215 | *gen_type = HW_BREAKPOINT_X; | ||
212 | *gen_len = sizeof(long); | 216 | *gen_len = sizeof(long); |
217 | return 0; | ||
218 | case X86_BREAKPOINT_WRITE: | ||
219 | *gen_type = HW_BREAKPOINT_W; | ||
213 | break; | 220 | break; |
221 | case X86_BREAKPOINT_RW: | ||
222 | *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; | ||
223 | break; | ||
224 | default: | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | |||
228 | /* Len */ | ||
229 | switch (x86_len) { | ||
214 | case X86_BREAKPOINT_LEN_1: | 230 | case X86_BREAKPOINT_LEN_1: |
215 | *gen_len = HW_BREAKPOINT_LEN_1; | 231 | *gen_len = HW_BREAKPOINT_LEN_1; |
216 | break; | 232 | break; |
@@ -229,21 +245,6 @@ int arch_bp_generic_fields(int x86_len, int x86_type, | |||
229 | return -EINVAL; | 245 | return -EINVAL; |
230 | } | 246 | } |
231 | 247 | ||
232 | /* Type */ | ||
233 | switch (x86_type) { | ||
234 | case X86_BREAKPOINT_EXECUTE: | ||
235 | *gen_type = HW_BREAKPOINT_X; | ||
236 | break; | ||
237 | case X86_BREAKPOINT_WRITE: | ||
238 | *gen_type = HW_BREAKPOINT_W; | ||
239 | break; | ||
240 | case X86_BREAKPOINT_RW: | ||
241 | *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; | ||
242 | break; | ||
243 | default: | ||
244 | return -EINVAL; | ||
245 | } | ||
246 | |||
247 | return 0; | 248 | return 0; |
248 | } | 249 | } |
249 | 250 | ||
@@ -316,9 +317,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
316 | ret = -EINVAL; | 317 | ret = -EINVAL; |
317 | 318 | ||
318 | switch (info->len) { | 319 | switch (info->len) { |
319 | case X86_BREAKPOINT_LEN_X: | ||
320 | align = sizeof(long) -1; | ||
321 | break; | ||
322 | case X86_BREAKPOINT_LEN_1: | 320 | case X86_BREAKPOINT_LEN_1: |
323 | align = 0; | 321 | align = 0; |
324 | break; | 322 | break; |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 9257510b4836..9d5f55848455 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -324,9 +324,8 @@ static void lguest_load_gdt(const struct desc_ptr *desc) | |||
324 | } | 324 | } |
325 | 325 | ||
326 | /* | 326 | /* |
327 | * For a single GDT entry which changes, we do the lazy thing: alter our GDT, | 327 | * For a single GDT entry which changes, we simply change our copy and |
328 | * then tell the Host to reload the entire thing. This operation is so rare | 328 | * then tell the host about it. |
329 | * that this naive implementation is reasonable. | ||
330 | */ | 329 | */ |
331 | static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, | 330 | static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, |
332 | const void *desc, int type) | 331 | const void *desc, int type) |
@@ -338,9 +337,13 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, | |||
338 | } | 337 | } |
339 | 338 | ||
340 | /* | 339 | /* |
341 | * OK, I lied. There are three "thread local storage" GDT entries which change | 340 | * There are three "thread local storage" GDT entries which change |
342 | * on every context switch (these three entries are how glibc implements | 341 | * on every context switch (these three entries are how glibc implements |
343 | * __thread variables). So we have a hypercall specifically for this case. | 342 | * __thread variables). As an optimization, we have a hypercall |
343 | * specifically for this case. | ||
344 | * | ||
345 | * Wouldn't it be nicer to have a general LOAD_GDT_ENTRIES hypercall | ||
346 | * which took a range of entries? | ||
344 | */ | 347 | */ |
345 | static void lguest_load_tls(struct thread_struct *t, unsigned int cpu) | 348 | static void lguest_load_tls(struct thread_struct *t, unsigned int cpu) |
346 | { | 349 | { |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index cfe4faabb0f6..009b819f48d0 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
@@ -671,7 +671,9 @@ static int __init ppro_init(char **cpu_type) | |||
671 | case 14: | 671 | case 14: |
672 | *cpu_type = "i386/core"; | 672 | *cpu_type = "i386/core"; |
673 | break; | 673 | break; |
674 | case 15: case 23: | 674 | case 0x0f: |
675 | case 0x16: | ||
676 | case 0x17: | ||
675 | *cpu_type = "i386/core_2"; | 677 | *cpu_type = "i386/core_2"; |
676 | break; | 678 | break; |
677 | case 0x1a: | 679 | case 0x1a: |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index eab58db5f91c..cd18493c9527 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -806,6 +806,8 @@ static const struct intel_driver_description { | |||
806 | "G45/G43", NULL, &intel_i965_driver }, | 806 | "G45/G43", NULL, &intel_i965_driver }, |
807 | { PCI_DEVICE_ID_INTEL_B43_HB, PCI_DEVICE_ID_INTEL_B43_IG, | 807 | { PCI_DEVICE_ID_INTEL_B43_HB, PCI_DEVICE_ID_INTEL_B43_IG, |
808 | "B43", NULL, &intel_i965_driver }, | 808 | "B43", NULL, &intel_i965_driver }, |
809 | { PCI_DEVICE_ID_INTEL_B43_1_HB, PCI_DEVICE_ID_INTEL_B43_1_IG, | ||
810 | "B43", NULL, &intel_i965_driver }, | ||
809 | { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, | 811 | { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, |
810 | "G41", NULL, &intel_i965_driver }, | 812 | "G41", NULL, &intel_i965_driver }, |
811 | { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, | 813 | { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, |
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index ee189c74d345..d09b1ab7e8ab 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h | |||
@@ -186,6 +186,8 @@ | |||
186 | #define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 | 186 | #define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 |
187 | #define PCI_DEVICE_ID_INTEL_B43_HB 0x2E40 | 187 | #define PCI_DEVICE_ID_INTEL_B43_HB 0x2E40 |
188 | #define PCI_DEVICE_ID_INTEL_B43_IG 0x2E42 | 188 | #define PCI_DEVICE_ID_INTEL_B43_IG 0x2E42 |
189 | #define PCI_DEVICE_ID_INTEL_B43_1_HB 0x2E90 | ||
190 | #define PCI_DEVICE_ID_INTEL_B43_1_IG 0x2E92 | ||
189 | #define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40 | 191 | #define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40 |
190 | #define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42 | 192 | #define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42 |
191 | #define PCI_DEVICE_ID_INTEL_EAGLELAKE_HB 0x2E00 | 193 | #define PCI_DEVICE_ID_INTEL_EAGLELAKE_HB 0x2E00 |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 942a9826bd23..c810481a5bc2 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -596,6 +596,10 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, | |||
596 | ssize_t ret; | 596 | ssize_t ret; |
597 | bool nonblock; | 597 | bool nonblock; |
598 | 598 | ||
599 | /* Userspace could be out to fool us */ | ||
600 | if (!count) | ||
601 | return 0; | ||
602 | |||
599 | port = filp->private_data; | 603 | port = filp->private_data; |
600 | 604 | ||
601 | nonblock = filp->f_flags & O_NONBLOCK; | 605 | nonblock = filp->f_flags & O_NONBLOCK; |
@@ -642,7 +646,7 @@ static unsigned int port_fops_poll(struct file *filp, poll_table *wait) | |||
642 | poll_wait(filp, &port->waitqueue, wait); | 646 | poll_wait(filp, &port->waitqueue, wait); |
643 | 647 | ||
644 | ret = 0; | 648 | ret = 0; |
645 | if (port->inbuf) | 649 | if (!will_read_block(port)) |
646 | ret |= POLLIN | POLLRDNORM; | 650 | ret |= POLLIN | POLLRDNORM; |
647 | if (!will_write_block(port)) | 651 | if (!will_write_block(port)) |
648 | ret |= POLLOUT; | 652 | ret |= POLLOUT; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 216deb579785..6dbe14cc4f74 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -170,6 +170,7 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
170 | INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ | 170 | INTEL_VGA_DEVICE(0x2e22, &intel_g45_info), /* G45_G */ |
171 | INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ | 171 | INTEL_VGA_DEVICE(0x2e32, &intel_g45_info), /* G41_G */ |
172 | INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ | 172 | INTEL_VGA_DEVICE(0x2e42, &intel_g45_info), /* B43_G */ |
173 | INTEL_VGA_DEVICE(0x2e92, &intel_g45_info), /* B43_G.1 */ | ||
173 | INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), | 174 | INTEL_VGA_DEVICE(0xa001, &intel_pineview_info), |
174 | INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), | 175 | INTEL_VGA_DEVICE(0xa011, &intel_pineview_info), |
175 | INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), | 176 | INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info), |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 16fca1d1799a..cf4ffbee1c00 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2351,14 +2351,21 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) | |||
2351 | 2351 | ||
2352 | reg->obj = obj; | 2352 | reg->obj = obj; |
2353 | 2353 | ||
2354 | if (IS_GEN6(dev)) | 2354 | switch (INTEL_INFO(dev)->gen) { |
2355 | case 6: | ||
2355 | sandybridge_write_fence_reg(reg); | 2356 | sandybridge_write_fence_reg(reg); |
2356 | else if (IS_I965G(dev)) | 2357 | break; |
2358 | case 5: | ||
2359 | case 4: | ||
2357 | i965_write_fence_reg(reg); | 2360 | i965_write_fence_reg(reg); |
2358 | else if (IS_I9XX(dev)) | 2361 | break; |
2362 | case 3: | ||
2359 | i915_write_fence_reg(reg); | 2363 | i915_write_fence_reg(reg); |
2360 | else | 2364 | break; |
2365 | case 2: | ||
2361 | i830_write_fence_reg(reg); | 2366 | i830_write_fence_reg(reg); |
2367 | break; | ||
2368 | } | ||
2362 | 2369 | ||
2363 | trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, | 2370 | trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, |
2364 | obj_priv->tiling_mode); | 2371 | obj_priv->tiling_mode); |
@@ -2381,22 +2388,26 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
2381 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2388 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
2382 | struct drm_i915_fence_reg *reg = | 2389 | struct drm_i915_fence_reg *reg = |
2383 | &dev_priv->fence_regs[obj_priv->fence_reg]; | 2390 | &dev_priv->fence_regs[obj_priv->fence_reg]; |
2391 | uint32_t fence_reg; | ||
2384 | 2392 | ||
2385 | if (IS_GEN6(dev)) { | 2393 | switch (INTEL_INFO(dev)->gen) { |
2394 | case 6: | ||
2386 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + | 2395 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + |
2387 | (obj_priv->fence_reg * 8), 0); | 2396 | (obj_priv->fence_reg * 8), 0); |
2388 | } else if (IS_I965G(dev)) { | 2397 | break; |
2398 | case 5: | ||
2399 | case 4: | ||
2389 | I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); | 2400 | I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); |
2390 | } else { | 2401 | break; |
2391 | uint32_t fence_reg; | 2402 | case 3: |
2392 | 2403 | if (obj_priv->fence_reg > 8) | |
2393 | if (obj_priv->fence_reg < 8) | 2404 | fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4; |
2394 | fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4; | ||
2395 | else | 2405 | else |
2396 | fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - | 2406 | case 2: |
2397 | 8) * 4; | 2407 | fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4; |
2398 | 2408 | ||
2399 | I915_WRITE(fence_reg, 0); | 2409 | I915_WRITE(fence_reg, 0); |
2410 | break; | ||
2400 | } | 2411 | } |
2401 | 2412 | ||
2402 | reg->obj = NULL; | 2413 | reg->obj = NULL; |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 72cae3cccad8..e85246ef691c 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -79,6 +79,7 @@ mark_free(struct drm_i915_gem_object *obj_priv, | |||
79 | struct list_head *unwind) | 79 | struct list_head *unwind) |
80 | { | 80 | { |
81 | list_add(&obj_priv->evict_list, unwind); | 81 | list_add(&obj_priv->evict_list, unwind); |
82 | drm_gem_object_reference(&obj_priv->base); | ||
82 | return drm_mm_scan_add_block(obj_priv->gtt_space); | 83 | return drm_mm_scan_add_block(obj_priv->gtt_space); |
83 | } | 84 | } |
84 | 85 | ||
@@ -165,6 +166,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen | |||
165 | list_for_each_entry(obj_priv, &unwind_list, evict_list) { | 166 | list_for_each_entry(obj_priv, &unwind_list, evict_list) { |
166 | ret = drm_mm_scan_remove_block(obj_priv->gtt_space); | 167 | ret = drm_mm_scan_remove_block(obj_priv->gtt_space); |
167 | BUG_ON(ret); | 168 | BUG_ON(ret); |
169 | drm_gem_object_unreference(&obj_priv->base); | ||
168 | } | 170 | } |
169 | 171 | ||
170 | /* We expect the caller to unpin, evict all and try again, or give up. | 172 | /* We expect the caller to unpin, evict all and try again, or give up. |
@@ -181,18 +183,21 @@ found: | |||
181 | * scanning, therefore store to be evicted objects on a | 183 | * scanning, therefore store to be evicted objects on a |
182 | * temporary list. */ | 184 | * temporary list. */ |
183 | list_move(&obj_priv->evict_list, &eviction_list); | 185 | list_move(&obj_priv->evict_list, &eviction_list); |
184 | } | 186 | } else |
187 | drm_gem_object_unreference(&obj_priv->base); | ||
185 | } | 188 | } |
186 | 189 | ||
187 | /* Unbinding will emit any required flushes */ | 190 | /* Unbinding will emit any required flushes */ |
188 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | 191 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, |
189 | &eviction_list, evict_list) { | 192 | &eviction_list, evict_list) { |
190 | #if WATCH_LRU | 193 | #if WATCH_LRU |
191 | DRM_INFO("%s: evicting %p\n", __func__, obj); | 194 | DRM_INFO("%s: evicting %p\n", __func__, &obj_priv->base); |
192 | #endif | 195 | #endif |
193 | ret = i915_gem_object_unbind(&obj_priv->base); | 196 | ret = i915_gem_object_unbind(&obj_priv->base); |
194 | if (ret) | 197 | if (ret) |
195 | return ret; | 198 | return ret; |
199 | |||
200 | drm_gem_object_unreference(&obj_priv->base); | ||
196 | } | 201 | } |
197 | 202 | ||
198 | /* The just created free hole should be on the top of the free stack | 203 | /* The just created free hole should be on the top of the free stack |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 2c6b98f2440e..31f08581e93a 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -789,16 +789,25 @@ int i915_save_state(struct drm_device *dev) | |||
789 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); | 789 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); |
790 | 790 | ||
791 | /* Fences */ | 791 | /* Fences */ |
792 | if (IS_I965G(dev)) { | 792 | switch (INTEL_INFO(dev)->gen) { |
793 | case 6: | ||
794 | for (i = 0; i < 16; i++) | ||
795 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); | ||
796 | break; | ||
797 | case 5: | ||
798 | case 4: | ||
793 | for (i = 0; i < 16; i++) | 799 | for (i = 0; i < 16; i++) |
794 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); | 800 | dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); |
795 | } else { | 801 | break; |
796 | for (i = 0; i < 8; i++) | 802 | case 3: |
797 | dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); | ||
798 | |||
799 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | 803 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
800 | for (i = 0; i < 8; i++) | 804 | for (i = 0; i < 8; i++) |
801 | dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); | 805 | dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); |
806 | case 2: | ||
807 | for (i = 0; i < 8; i++) | ||
808 | dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); | ||
809 | break; | ||
810 | |||
802 | } | 811 | } |
803 | 812 | ||
804 | return 0; | 813 | return 0; |
@@ -815,15 +824,24 @@ int i915_restore_state(struct drm_device *dev) | |||
815 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); | 824 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); |
816 | 825 | ||
817 | /* Fences */ | 826 | /* Fences */ |
818 | if (IS_I965G(dev)) { | 827 | switch (INTEL_INFO(dev)->gen) { |
828 | case 6: | ||
829 | for (i = 0; i < 16; i++) | ||
830 | I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); | ||
831 | break; | ||
832 | case 5: | ||
833 | case 4: | ||
819 | for (i = 0; i < 16; i++) | 834 | for (i = 0; i < 16; i++) |
820 | I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); | 835 | I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); |
821 | } else { | 836 | break; |
822 | for (i = 0; i < 8; i++) | 837 | case 3: |
823 | I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); | 838 | case 2: |
824 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | 839 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) |
825 | for (i = 0; i < 8; i++) | 840 | for (i = 0; i < 8; i++) |
826 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); | 841 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); |
842 | for (i = 0; i < 8; i++) | ||
843 | I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); | ||
844 | break; | ||
827 | } | 845 | } |
828 | 846 | ||
829 | i915_restore_display(dev); | 847 | i915_restore_display(dev); |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index a02a8df73727..197d4f32585a 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -188,7 +188,7 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
188 | 188 | ||
189 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, | 189 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
190 | 1000, 1)) | 190 | 1000, 1)) |
191 | DRM_ERROR("timed out waiting for FORCE_TRIGGER"); | 191 | DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); |
192 | 192 | ||
193 | if (turn_off_dac) { | 193 | if (turn_off_dac) { |
194 | I915_WRITE(PCH_ADPA, temp); | 194 | I915_WRITE(PCH_ADPA, temp); |
@@ -245,7 +245,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
245 | if (wait_for((I915_READ(PORT_HOTPLUG_EN) & | 245 | if (wait_for((I915_READ(PORT_HOTPLUG_EN) & |
246 | CRT_HOTPLUG_FORCE_DETECT) == 0, | 246 | CRT_HOTPLUG_FORCE_DETECT) == 0, |
247 | 1000, 1)) | 247 | 1000, 1)) |
248 | DRM_ERROR("timed out waiting for FORCE_DETECT to go off"); | 248 | DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off"); |
249 | } | 249 | } |
250 | 250 | ||
251 | stat = I915_READ(PORT_HOTPLUG_STAT); | 251 | stat = I915_READ(PORT_HOTPLUG_STAT); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 19daead5b525..b5bf51a4502d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -2463,11 +2463,19 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | |||
2463 | struct drm_display_mode *adjusted_mode) | 2463 | struct drm_display_mode *adjusted_mode) |
2464 | { | 2464 | { |
2465 | struct drm_device *dev = crtc->dev; | 2465 | struct drm_device *dev = crtc->dev; |
2466 | |||
2466 | if (HAS_PCH_SPLIT(dev)) { | 2467 | if (HAS_PCH_SPLIT(dev)) { |
2467 | /* FDI link clock is fixed at 2.7G */ | 2468 | /* FDI link clock is fixed at 2.7G */ |
2468 | if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) | 2469 | if (mode->clock * 3 > IRONLAKE_FDI_FREQ * 4) |
2469 | return false; | 2470 | return false; |
2470 | } | 2471 | } |
2472 | |||
2473 | /* XXX some encoders set the crtcinfo, others don't. | ||
2474 | * Obviously we need some form of conflict resolution here... | ||
2475 | */ | ||
2476 | if (adjusted_mode->crtc_htotal == 0) | ||
2477 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
2478 | |||
2471 | return true; | 2479 | return true; |
2472 | } | 2480 | } |
2473 | 2481 | ||
diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig index bc87b9c1d27e..0fcd2640c23f 100644 --- a/fs/ceph/Kconfig +++ b/fs/ceph/Kconfig | |||
@@ -3,6 +3,7 @@ config CEPH_FS | |||
3 | depends on INET && EXPERIMENTAL | 3 | depends on INET && EXPERIMENTAL |
4 | select LIBCRC32C | 4 | select LIBCRC32C |
5 | select CRYPTO_AES | 5 | select CRYPTO_AES |
6 | select CRYPTO | ||
6 | help | 7 | help |
7 | Choose Y or M here to include support for mounting the | 8 | Choose Y or M here to include support for mounting the |
8 | experimental Ceph distributed file system. Ceph is an extremely | 9 | experimental Ceph distributed file system. Ceph is an extremely |
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 4cfce1ee31fa..efbc604001c8 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -411,8 +411,8 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) | |||
411 | if (i_size < page_off + len) | 411 | if (i_size < page_off + len) |
412 | len = i_size - page_off; | 412 | len = i_size - page_off; |
413 | 413 | ||
414 | dout("writepage %p page %p index %lu on %llu~%u\n", | 414 | dout("writepage %p page %p index %lu on %llu~%u snapc %p\n", |
415 | inode, page, page->index, page_off, len); | 415 | inode, page, page->index, page_off, len, snapc); |
416 | 416 | ||
417 | writeback_stat = atomic_long_inc_return(&client->writeback_count); | 417 | writeback_stat = atomic_long_inc_return(&client->writeback_count); |
418 | if (writeback_stat > | 418 | if (writeback_stat > |
@@ -766,7 +766,8 @@ get_more_pages: | |||
766 | /* ok */ | 766 | /* ok */ |
767 | if (locked_pages == 0) { | 767 | if (locked_pages == 0) { |
768 | /* prepare async write request */ | 768 | /* prepare async write request */ |
769 | offset = page->index << PAGE_CACHE_SHIFT; | 769 | offset = (unsigned long long)page->index |
770 | << PAGE_CACHE_SHIFT; | ||
770 | len = wsize; | 771 | len = wsize; |
771 | req = ceph_osdc_new_request(&client->osdc, | 772 | req = ceph_osdc_new_request(&client->osdc, |
772 | &ci->i_layout, | 773 | &ci->i_layout, |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index a2069b6680ae..73c153092f72 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -814,7 +814,7 @@ int __ceph_caps_used(struct ceph_inode_info *ci) | |||
814 | used |= CEPH_CAP_PIN; | 814 | used |= CEPH_CAP_PIN; |
815 | if (ci->i_rd_ref) | 815 | if (ci->i_rd_ref) |
816 | used |= CEPH_CAP_FILE_RD; | 816 | used |= CEPH_CAP_FILE_RD; |
817 | if (ci->i_rdcache_ref || ci->i_rdcache_gen) | 817 | if (ci->i_rdcache_ref || ci->vfs_inode.i_data.nrpages) |
818 | used |= CEPH_CAP_FILE_CACHE; | 818 | used |= CEPH_CAP_FILE_CACHE; |
819 | if (ci->i_wr_ref) | 819 | if (ci->i_wr_ref) |
820 | used |= CEPH_CAP_FILE_WR; | 820 | used |= CEPH_CAP_FILE_WR; |
@@ -1195,10 +1195,14 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1195 | * asynchronously back to the MDS once sync writes complete and dirty | 1195 | * asynchronously back to the MDS once sync writes complete and dirty |
1196 | * data is written out. | 1196 | * data is written out. |
1197 | * | 1197 | * |
1198 | * Unless @again is true, skip cap_snaps that were already sent to | ||
1199 | * the MDS (i.e., during this session). | ||
1200 | * | ||
1198 | * Called under i_lock. Takes s_mutex as needed. | 1201 | * Called under i_lock. Takes s_mutex as needed. |
1199 | */ | 1202 | */ |
1200 | void __ceph_flush_snaps(struct ceph_inode_info *ci, | 1203 | void __ceph_flush_snaps(struct ceph_inode_info *ci, |
1201 | struct ceph_mds_session **psession) | 1204 | struct ceph_mds_session **psession, |
1205 | int again) | ||
1202 | __releases(ci->vfs_inode->i_lock) | 1206 | __releases(ci->vfs_inode->i_lock) |
1203 | __acquires(ci->vfs_inode->i_lock) | 1207 | __acquires(ci->vfs_inode->i_lock) |
1204 | { | 1208 | { |
@@ -1227,7 +1231,7 @@ retry: | |||
1227 | * pages to be written out. | 1231 | * pages to be written out. |
1228 | */ | 1232 | */ |
1229 | if (capsnap->dirty_pages || capsnap->writing) | 1233 | if (capsnap->dirty_pages || capsnap->writing) |
1230 | continue; | 1234 | break; |
1231 | 1235 | ||
1232 | /* | 1236 | /* |
1233 | * if cap writeback already occurred, we should have dropped | 1237 | * if cap writeback already occurred, we should have dropped |
@@ -1240,6 +1244,13 @@ retry: | |||
1240 | dout("no auth cap (migrating?), doing nothing\n"); | 1244 | dout("no auth cap (migrating?), doing nothing\n"); |
1241 | goto out; | 1245 | goto out; |
1242 | } | 1246 | } |
1247 | |||
1248 | /* only flush each capsnap once */ | ||
1249 | if (!again && !list_empty(&capsnap->flushing_item)) { | ||
1250 | dout("already flushed %p, skipping\n", capsnap); | ||
1251 | continue; | ||
1252 | } | ||
1253 | |||
1243 | mds = ci->i_auth_cap->session->s_mds; | 1254 | mds = ci->i_auth_cap->session->s_mds; |
1244 | mseq = ci->i_auth_cap->mseq; | 1255 | mseq = ci->i_auth_cap->mseq; |
1245 | 1256 | ||
@@ -1276,8 +1287,8 @@ retry: | |||
1276 | &session->s_cap_snaps_flushing); | 1287 | &session->s_cap_snaps_flushing); |
1277 | spin_unlock(&inode->i_lock); | 1288 | spin_unlock(&inode->i_lock); |
1278 | 1289 | ||
1279 | dout("flush_snaps %p cap_snap %p follows %lld size %llu\n", | 1290 | dout("flush_snaps %p cap_snap %p follows %lld tid %llu\n", |
1280 | inode, capsnap, next_follows, capsnap->size); | 1291 | inode, capsnap, capsnap->follows, capsnap->flush_tid); |
1281 | send_cap_msg(session, ceph_vino(inode).ino, 0, | 1292 | send_cap_msg(session, ceph_vino(inode).ino, 0, |
1282 | CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0, | 1293 | CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0, |
1283 | capsnap->dirty, 0, capsnap->flush_tid, 0, mseq, | 1294 | capsnap->dirty, 0, capsnap->flush_tid, 0, mseq, |
@@ -1314,7 +1325,7 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci) | |||
1314 | struct inode *inode = &ci->vfs_inode; | 1325 | struct inode *inode = &ci->vfs_inode; |
1315 | 1326 | ||
1316 | spin_lock(&inode->i_lock); | 1327 | spin_lock(&inode->i_lock); |
1317 | __ceph_flush_snaps(ci, NULL); | 1328 | __ceph_flush_snaps(ci, NULL, 0); |
1318 | spin_unlock(&inode->i_lock); | 1329 | spin_unlock(&inode->i_lock); |
1319 | } | 1330 | } |
1320 | 1331 | ||
@@ -1477,7 +1488,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, | |||
1477 | 1488 | ||
1478 | /* flush snaps first time around only */ | 1489 | /* flush snaps first time around only */ |
1479 | if (!list_empty(&ci->i_cap_snaps)) | 1490 | if (!list_empty(&ci->i_cap_snaps)) |
1480 | __ceph_flush_snaps(ci, &session); | 1491 | __ceph_flush_snaps(ci, &session, 0); |
1481 | goto retry_locked; | 1492 | goto retry_locked; |
1482 | retry: | 1493 | retry: |
1483 | spin_lock(&inode->i_lock); | 1494 | spin_lock(&inode->i_lock); |
@@ -1894,7 +1905,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc, | |||
1894 | if (cap && cap->session == session) { | 1905 | if (cap && cap->session == session) { |
1895 | dout("kick_flushing_caps %p cap %p capsnap %p\n", inode, | 1906 | dout("kick_flushing_caps %p cap %p capsnap %p\n", inode, |
1896 | cap, capsnap); | 1907 | cap, capsnap); |
1897 | __ceph_flush_snaps(ci, &session); | 1908 | __ceph_flush_snaps(ci, &session, 1); |
1898 | } else { | 1909 | } else { |
1899 | pr_err("%p auth cap %p not mds%d ???\n", inode, | 1910 | pr_err("%p auth cap %p not mds%d ???\n", inode, |
1900 | cap, session->s_mds); | 1911 | cap, session->s_mds); |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 6e4f43ff23ec..a1986eb52045 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -1021,11 +1021,15 @@ out_touch: | |||
1021 | static void ceph_dentry_release(struct dentry *dentry) | 1021 | static void ceph_dentry_release(struct dentry *dentry) |
1022 | { | 1022 | { |
1023 | struct ceph_dentry_info *di = ceph_dentry(dentry); | 1023 | struct ceph_dentry_info *di = ceph_dentry(dentry); |
1024 | struct inode *parent_inode = dentry->d_parent->d_inode; | 1024 | struct inode *parent_inode = NULL; |
1025 | u64 snapid = ceph_snap(parent_inode); | 1025 | u64 snapid = CEPH_NOSNAP; |
1026 | 1026 | ||
1027 | if (!IS_ROOT(dentry)) { | ||
1028 | parent_inode = dentry->d_parent->d_inode; | ||
1029 | if (parent_inode) | ||
1030 | snapid = ceph_snap(parent_inode); | ||
1031 | } | ||
1027 | dout("dentry_release %p parent %p\n", dentry, parent_inode); | 1032 | dout("dentry_release %p parent %p\n", dentry, parent_inode); |
1028 | |||
1029 | if (parent_inode && snapid != CEPH_SNAPDIR) { | 1033 | if (parent_inode && snapid != CEPH_SNAPDIR) { |
1030 | struct ceph_inode_info *ci = ceph_inode(parent_inode); | 1034 | struct ceph_inode_info *ci = ceph_inode(parent_inode); |
1031 | 1035 | ||
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index e7cca414da03..62377ec37edf 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -845,7 +845,7 @@ static void ceph_set_dentry_offset(struct dentry *dn) | |||
845 | * the caller) if we fail. | 845 | * the caller) if we fail. |
846 | */ | 846 | */ |
847 | static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | 847 | static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, |
848 | bool *prehash) | 848 | bool *prehash, bool set_offset) |
849 | { | 849 | { |
850 | struct dentry *realdn; | 850 | struct dentry *realdn; |
851 | 851 | ||
@@ -877,7 +877,8 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | |||
877 | } | 877 | } |
878 | if ((!prehash || *prehash) && d_unhashed(dn)) | 878 | if ((!prehash || *prehash) && d_unhashed(dn)) |
879 | d_rehash(dn); | 879 | d_rehash(dn); |
880 | ceph_set_dentry_offset(dn); | 880 | if (set_offset) |
881 | ceph_set_dentry_offset(dn); | ||
881 | out: | 882 | out: |
882 | return dn; | 883 | return dn; |
883 | } | 884 | } |
@@ -1062,7 +1063,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
1062 | d_delete(dn); | 1063 | d_delete(dn); |
1063 | goto done; | 1064 | goto done; |
1064 | } | 1065 | } |
1065 | dn = splice_dentry(dn, in, &have_lease); | 1066 | dn = splice_dentry(dn, in, &have_lease, true); |
1066 | if (IS_ERR(dn)) { | 1067 | if (IS_ERR(dn)) { |
1067 | err = PTR_ERR(dn); | 1068 | err = PTR_ERR(dn); |
1068 | goto done; | 1069 | goto done; |
@@ -1105,7 +1106,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
1105 | goto done; | 1106 | goto done; |
1106 | } | 1107 | } |
1107 | dout(" linking snapped dir %p to dn %p\n", in, dn); | 1108 | dout(" linking snapped dir %p to dn %p\n", in, dn); |
1108 | dn = splice_dentry(dn, in, NULL); | 1109 | dn = splice_dentry(dn, in, NULL, true); |
1109 | if (IS_ERR(dn)) { | 1110 | if (IS_ERR(dn)) { |
1110 | err = PTR_ERR(dn); | 1111 | err = PTR_ERR(dn); |
1111 | goto done; | 1112 | goto done; |
@@ -1237,7 +1238,7 @@ retry_lookup: | |||
1237 | err = PTR_ERR(in); | 1238 | err = PTR_ERR(in); |
1238 | goto out; | 1239 | goto out; |
1239 | } | 1240 | } |
1240 | dn = splice_dentry(dn, in, NULL); | 1241 | dn = splice_dentry(dn, in, NULL, false); |
1241 | if (IS_ERR(dn)) | 1242 | if (IS_ERR(dn)) |
1242 | dn = NULL; | 1243 | dn = NULL; |
1243 | } | 1244 | } |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index f091b1351786..fad95f8f2608 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -2374,6 +2374,8 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
2374 | num_fcntl_locks, | 2374 | num_fcntl_locks, |
2375 | num_flock_locks); | 2375 | num_flock_locks); |
2376 | unlock_kernel(); | 2376 | unlock_kernel(); |
2377 | } else { | ||
2378 | err = ceph_pagelist_append(pagelist, &rec, reclen); | ||
2377 | } | 2379 | } |
2378 | 2380 | ||
2379 | out_free: | 2381 | out_free: |
diff --git a/fs/ceph/pagelist.c b/fs/ceph/pagelist.c index b6859f47d364..46a368b6dce5 100644 --- a/fs/ceph/pagelist.c +++ b/fs/ceph/pagelist.c | |||
@@ -5,10 +5,18 @@ | |||
5 | 5 | ||
6 | #include "pagelist.h" | 6 | #include "pagelist.h" |
7 | 7 | ||
8 | static void ceph_pagelist_unmap_tail(struct ceph_pagelist *pl) | ||
9 | { | ||
10 | struct page *page = list_entry(pl->head.prev, struct page, | ||
11 | lru); | ||
12 | kunmap(page); | ||
13 | } | ||
14 | |||
8 | int ceph_pagelist_release(struct ceph_pagelist *pl) | 15 | int ceph_pagelist_release(struct ceph_pagelist *pl) |
9 | { | 16 | { |
10 | if (pl->mapped_tail) | 17 | if (pl->mapped_tail) |
11 | kunmap(pl->mapped_tail); | 18 | ceph_pagelist_unmap_tail(pl); |
19 | |||
12 | while (!list_empty(&pl->head)) { | 20 | while (!list_empty(&pl->head)) { |
13 | struct page *page = list_first_entry(&pl->head, struct page, | 21 | struct page *page = list_first_entry(&pl->head, struct page, |
14 | lru); | 22 | lru); |
@@ -26,7 +34,7 @@ static int ceph_pagelist_addpage(struct ceph_pagelist *pl) | |||
26 | pl->room += PAGE_SIZE; | 34 | pl->room += PAGE_SIZE; |
27 | list_add_tail(&page->lru, &pl->head); | 35 | list_add_tail(&page->lru, &pl->head); |
28 | if (pl->mapped_tail) | 36 | if (pl->mapped_tail) |
29 | kunmap(pl->mapped_tail); | 37 | ceph_pagelist_unmap_tail(pl); |
30 | pl->mapped_tail = kmap(page); | 38 | pl->mapped_tail = kmap(page); |
31 | return 0; | 39 | return 0; |
32 | } | 40 | } |
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 4868b9dcac5a..190b6c4a6f2b 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
@@ -119,6 +119,7 @@ static struct ceph_snap_realm *ceph_create_snap_realm( | |||
119 | INIT_LIST_HEAD(&realm->children); | 119 | INIT_LIST_HEAD(&realm->children); |
120 | INIT_LIST_HEAD(&realm->child_item); | 120 | INIT_LIST_HEAD(&realm->child_item); |
121 | INIT_LIST_HEAD(&realm->empty_item); | 121 | INIT_LIST_HEAD(&realm->empty_item); |
122 | INIT_LIST_HEAD(&realm->dirty_item); | ||
122 | INIT_LIST_HEAD(&realm->inodes_with_caps); | 123 | INIT_LIST_HEAD(&realm->inodes_with_caps); |
123 | spin_lock_init(&realm->inodes_with_caps_lock); | 124 | spin_lock_init(&realm->inodes_with_caps_lock); |
124 | __insert_snap_realm(&mdsc->snap_realms, realm); | 125 | __insert_snap_realm(&mdsc->snap_realms, realm); |
@@ -467,7 +468,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
467 | INIT_LIST_HEAD(&capsnap->ci_item); | 468 | INIT_LIST_HEAD(&capsnap->ci_item); |
468 | INIT_LIST_HEAD(&capsnap->flushing_item); | 469 | INIT_LIST_HEAD(&capsnap->flushing_item); |
469 | 470 | ||
470 | capsnap->follows = snapc->seq - 1; | 471 | capsnap->follows = snapc->seq; |
471 | capsnap->issued = __ceph_caps_issued(ci, NULL); | 472 | capsnap->issued = __ceph_caps_issued(ci, NULL); |
472 | capsnap->dirty = dirty; | 473 | capsnap->dirty = dirty; |
473 | 474 | ||
@@ -604,6 +605,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, | |||
604 | struct ceph_snap_realm *realm; | 605 | struct ceph_snap_realm *realm; |
605 | int invalidate = 0; | 606 | int invalidate = 0; |
606 | int err = -ENOMEM; | 607 | int err = -ENOMEM; |
608 | LIST_HEAD(dirty_realms); | ||
607 | 609 | ||
608 | dout("update_snap_trace deletion=%d\n", deletion); | 610 | dout("update_snap_trace deletion=%d\n", deletion); |
609 | more: | 611 | more: |
@@ -626,24 +628,6 @@ more: | |||
626 | } | 628 | } |
627 | } | 629 | } |
628 | 630 | ||
629 | if (le64_to_cpu(ri->seq) > realm->seq) { | ||
630 | dout("update_snap_trace updating %llx %p %lld -> %lld\n", | ||
631 | realm->ino, realm, realm->seq, le64_to_cpu(ri->seq)); | ||
632 | /* | ||
633 | * if the realm seq has changed, queue a cap_snap for every | ||
634 | * inode with open caps. we do this _before_ we update | ||
635 | * the realm info so that we prepare for writeback under the | ||
636 | * _previous_ snap context. | ||
637 | * | ||
638 | * ...unless it's a snap deletion! | ||
639 | */ | ||
640 | if (!deletion) | ||
641 | queue_realm_cap_snaps(realm); | ||
642 | } else { | ||
643 | dout("update_snap_trace %llx %p seq %lld unchanged\n", | ||
644 | realm->ino, realm, realm->seq); | ||
645 | } | ||
646 | |||
647 | /* ensure the parent is correct */ | 631 | /* ensure the parent is correct */ |
648 | err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent)); | 632 | err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent)); |
649 | if (err < 0) | 633 | if (err < 0) |
@@ -651,6 +635,8 @@ more: | |||
651 | invalidate += err; | 635 | invalidate += err; |
652 | 636 | ||
653 | if (le64_to_cpu(ri->seq) > realm->seq) { | 637 | if (le64_to_cpu(ri->seq) > realm->seq) { |
638 | dout("update_snap_trace updating %llx %p %lld -> %lld\n", | ||
639 | realm->ino, realm, realm->seq, le64_to_cpu(ri->seq)); | ||
654 | /* update realm parameters, snap lists */ | 640 | /* update realm parameters, snap lists */ |
655 | realm->seq = le64_to_cpu(ri->seq); | 641 | realm->seq = le64_to_cpu(ri->seq); |
656 | realm->created = le64_to_cpu(ri->created); | 642 | realm->created = le64_to_cpu(ri->created); |
@@ -668,9 +654,17 @@ more: | |||
668 | if (err < 0) | 654 | if (err < 0) |
669 | goto fail; | 655 | goto fail; |
670 | 656 | ||
657 | /* queue realm for cap_snap creation */ | ||
658 | list_add(&realm->dirty_item, &dirty_realms); | ||
659 | |||
671 | invalidate = 1; | 660 | invalidate = 1; |
672 | } else if (!realm->cached_context) { | 661 | } else if (!realm->cached_context) { |
662 | dout("update_snap_trace %llx %p seq %lld new\n", | ||
663 | realm->ino, realm, realm->seq); | ||
673 | invalidate = 1; | 664 | invalidate = 1; |
665 | } else { | ||
666 | dout("update_snap_trace %llx %p seq %lld unchanged\n", | ||
667 | realm->ino, realm, realm->seq); | ||
674 | } | 668 | } |
675 | 669 | ||
676 | dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino, | 670 | dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino, |
@@ -683,6 +677,14 @@ more: | |||
683 | if (invalidate) | 677 | if (invalidate) |
684 | rebuild_snap_realms(realm); | 678 | rebuild_snap_realms(realm); |
685 | 679 | ||
680 | /* | ||
681 | * queue cap snaps _after_ we've built the new snap contexts, | ||
682 | * so that i_head_snapc can be set appropriately. | ||
683 | */ | ||
684 | list_for_each_entry(realm, &dirty_realms, dirty_item) { | ||
685 | queue_realm_cap_snaps(realm); | ||
686 | } | ||
687 | |||
686 | __cleanup_empty_realms(mdsc); | 688 | __cleanup_empty_realms(mdsc); |
687 | return 0; | 689 | return 0; |
688 | 690 | ||
@@ -715,7 +717,7 @@ static void flush_snaps(struct ceph_mds_client *mdsc) | |||
715 | igrab(inode); | 717 | igrab(inode); |
716 | spin_unlock(&mdsc->snap_flush_lock); | 718 | spin_unlock(&mdsc->snap_flush_lock); |
717 | spin_lock(&inode->i_lock); | 719 | spin_lock(&inode->i_lock); |
718 | __ceph_flush_snaps(ci, &session); | 720 | __ceph_flush_snaps(ci, &session, 0); |
719 | spin_unlock(&inode->i_lock); | 721 | spin_unlock(&inode->i_lock); |
720 | iput(inode); | 722 | iput(inode); |
721 | spin_lock(&mdsc->snap_flush_lock); | 723 | spin_lock(&mdsc->snap_flush_lock); |
@@ -816,6 +818,7 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, | |||
816 | }; | 818 | }; |
817 | struct inode *inode = ceph_find_inode(sb, vino); | 819 | struct inode *inode = ceph_find_inode(sb, vino); |
818 | struct ceph_inode_info *ci; | 820 | struct ceph_inode_info *ci; |
821 | struct ceph_snap_realm *oldrealm; | ||
819 | 822 | ||
820 | if (!inode) | 823 | if (!inode) |
821 | continue; | 824 | continue; |
@@ -841,18 +844,19 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, | |||
841 | dout(" will move %p to split realm %llx %p\n", | 844 | dout(" will move %p to split realm %llx %p\n", |
842 | inode, realm->ino, realm); | 845 | inode, realm->ino, realm); |
843 | /* | 846 | /* |
844 | * Remove the inode from the realm's inode | 847 | * Move the inode to the new realm |
845 | * list, but don't add it to the new realm | ||
846 | * yet. We don't want the cap_snap to be | ||
847 | * queued (again) by ceph_update_snap_trace() | ||
848 | * below. Queue it _now_, under the old context. | ||
849 | */ | 848 | */ |
850 | spin_lock(&realm->inodes_with_caps_lock); | 849 | spin_lock(&realm->inodes_with_caps_lock); |
851 | list_del_init(&ci->i_snap_realm_item); | 850 | list_del_init(&ci->i_snap_realm_item); |
851 | list_add(&ci->i_snap_realm_item, | ||
852 | &realm->inodes_with_caps); | ||
853 | oldrealm = ci->i_snap_realm; | ||
854 | ci->i_snap_realm = realm; | ||
852 | spin_unlock(&realm->inodes_with_caps_lock); | 855 | spin_unlock(&realm->inodes_with_caps_lock); |
853 | spin_unlock(&inode->i_lock); | 856 | spin_unlock(&inode->i_lock); |
854 | 857 | ||
855 | ceph_queue_cap_snap(ci); | 858 | ceph_get_snap_realm(mdsc, realm); |
859 | ceph_put_snap_realm(mdsc, oldrealm); | ||
856 | 860 | ||
857 | iput(inode); | 861 | iput(inode); |
858 | continue; | 862 | continue; |
@@ -880,43 +884,9 @@ skip_inode: | |||
880 | ceph_update_snap_trace(mdsc, p, e, | 884 | ceph_update_snap_trace(mdsc, p, e, |
881 | op == CEPH_SNAP_OP_DESTROY); | 885 | op == CEPH_SNAP_OP_DESTROY); |
882 | 886 | ||
883 | if (op == CEPH_SNAP_OP_SPLIT) { | 887 | if (op == CEPH_SNAP_OP_SPLIT) |
884 | /* | ||
885 | * ok, _now_ add the inodes into the new realm. | ||
886 | */ | ||
887 | for (i = 0; i < num_split_inos; i++) { | ||
888 | struct ceph_vino vino = { | ||
889 | .ino = le64_to_cpu(split_inos[i]), | ||
890 | .snap = CEPH_NOSNAP, | ||
891 | }; | ||
892 | struct inode *inode = ceph_find_inode(sb, vino); | ||
893 | struct ceph_inode_info *ci; | ||
894 | |||
895 | if (!inode) | ||
896 | continue; | ||
897 | ci = ceph_inode(inode); | ||
898 | spin_lock(&inode->i_lock); | ||
899 | if (list_empty(&ci->i_snap_realm_item)) { | ||
900 | struct ceph_snap_realm *oldrealm = | ||
901 | ci->i_snap_realm; | ||
902 | |||
903 | dout(" moving %p to split realm %llx %p\n", | ||
904 | inode, realm->ino, realm); | ||
905 | spin_lock(&realm->inodes_with_caps_lock); | ||
906 | list_add(&ci->i_snap_realm_item, | ||
907 | &realm->inodes_with_caps); | ||
908 | ci->i_snap_realm = realm; | ||
909 | spin_unlock(&realm->inodes_with_caps_lock); | ||
910 | ceph_get_snap_realm(mdsc, realm); | ||
911 | ceph_put_snap_realm(mdsc, oldrealm); | ||
912 | } | ||
913 | spin_unlock(&inode->i_lock); | ||
914 | iput(inode); | ||
915 | } | ||
916 | |||
917 | /* we took a reference when we created the realm, above */ | 888 | /* we took a reference when we created the realm, above */ |
918 | ceph_put_snap_realm(mdsc, realm); | 889 | ceph_put_snap_realm(mdsc, realm); |
919 | } | ||
920 | 890 | ||
921 | __cleanup_empty_realms(mdsc); | 891 | __cleanup_empty_realms(mdsc); |
922 | 892 | ||
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index c33897ae5725..b87638e84c4b 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -690,6 +690,8 @@ struct ceph_snap_realm { | |||
690 | 690 | ||
691 | struct list_head empty_item; /* if i have ref==0 */ | 691 | struct list_head empty_item; /* if i have ref==0 */ |
692 | 692 | ||
693 | struct list_head dirty_item; /* if realm needs new context */ | ||
694 | |||
693 | /* the current set of snaps for this realm */ | 695 | /* the current set of snaps for this realm */ |
694 | struct ceph_snap_context *cached_context; | 696 | struct ceph_snap_context *cached_context; |
695 | 697 | ||
@@ -826,7 +828,8 @@ extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had); | |||
826 | extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | 828 | extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, |
827 | struct ceph_snap_context *snapc); | 829 | struct ceph_snap_context *snapc); |
828 | extern void __ceph_flush_snaps(struct ceph_inode_info *ci, | 830 | extern void __ceph_flush_snaps(struct ceph_inode_info *ci, |
829 | struct ceph_mds_session **psession); | 831 | struct ceph_mds_session **psession, |
832 | int again); | ||
830 | extern void ceph_check_caps(struct ceph_inode_info *ci, int flags, | 833 | extern void ceph_check_caps(struct ceph_inode_info *ci, int flags, |
831 | struct ceph_mds_session *session); | 834 | struct ceph_mds_session *session); |
832 | extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc); | 835 | extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 76041b614758..63d069bd80b7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1093,6 +1093,10 @@ struct file_lock { | |||
1093 | 1093 | ||
1094 | #include <linux/fcntl.h> | 1094 | #include <linux/fcntl.h> |
1095 | 1095 | ||
1096 | /* temporary stubs for BKL removal */ | ||
1097 | #define lock_flocks() lock_kernel() | ||
1098 | #define unlock_flocks() unlock_kernel() | ||
1099 | |||
1096 | extern void send_sigio(struct fown_struct *fown, int fd, int band); | 1100 | extern void send_sigio(struct fown_struct *fown, int fd, int band); |
1097 | 1101 | ||
1098 | #ifdef CONFIG_FILE_LOCKING | 1102 | #ifdef CONFIG_FILE_LOCKING |
diff --git a/kernel/sched.c b/kernel/sched.c index 794819eab9ca..c0d2067f3e0d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -3513,9 +3513,9 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | |||
3513 | rtime = nsecs_to_cputime(p->se.sum_exec_runtime); | 3513 | rtime = nsecs_to_cputime(p->se.sum_exec_runtime); |
3514 | 3514 | ||
3515 | if (total) { | 3515 | if (total) { |
3516 | u64 temp; | 3516 | u64 temp = rtime; |
3517 | 3517 | ||
3518 | temp = (u64)(rtime * utime); | 3518 | temp *= utime; |
3519 | do_div(temp, total); | 3519 | do_div(temp, total); |
3520 | utime = (cputime_t)temp; | 3520 | utime = (cputime_t)temp; |
3521 | } else | 3521 | } else |
@@ -3546,9 +3546,9 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | |||
3546 | rtime = nsecs_to_cputime(cputime.sum_exec_runtime); | 3546 | rtime = nsecs_to_cputime(cputime.sum_exec_runtime); |
3547 | 3547 | ||
3548 | if (total) { | 3548 | if (total) { |
3549 | u64 temp; | 3549 | u64 temp = rtime; |
3550 | 3550 | ||
3551 | temp = (u64)(rtime * cputime.utime); | 3551 | temp *= cputime.utime; |
3552 | do_div(temp, total); | 3552 | do_div(temp, total); |
3553 | utime = (cputime_t)temp; | 3553 | utime = (cputime_t)temp; |
3554 | } else | 3554 | } else |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index a171138a9402..db3f674ca49d 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -3630,7 +3630,7 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu) | |||
3630 | if (time_before(now, nohz.next_balance)) | 3630 | if (time_before(now, nohz.next_balance)) |
3631 | return 0; | 3631 | return 0; |
3632 | 3632 | ||
3633 | if (!rq->nr_running) | 3633 | if (rq->idle_at_tick) |
3634 | return 0; | 3634 | return 0; |
3635 | 3635 | ||
3636 | first_pick_cpu = atomic_read(&nohz.first_pick_cpu); | 3636 | first_pick_cpu = atomic_read(&nohz.first_pick_cpu); |