From 422785b416bdfa438770ef3d3de4eeb542e7e7cb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Sep 2013 21:36:52 +0100 Subject: [PATCH 2/2] drm/i915; Preallocate the lazy request It is possible for us to be forced to perform an allocation for the lazy request whilst running the shrinker. This request will be emiited from inside i915_vma_unbind(), and may itself invoke direct-reclaim, recursing into the shrinker, and recursing into i915_vma_unbind(). i915_vma_unbind() never expected to be reentrant, and so OOPS when it finds that the pages it thought it had pinned and bound, are now NULL. Sep 3 00:12:19 x-hswu33 kernel: [22027.290905] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 Sep 3 00:12:19 x-hswu33 kernel: [22027.290971] IP: [] i915_gem_gtt_finish_object+0x68/0xbd [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.291047] PGD 758d3067 PUD ac0d6067 PMD 0 Sep 3 00:12:19 x-hswu33 kernel: [22027.291085] Oops: 0000 [#1] SMP Sep 3 00:12:19 x-hswu33 kernel: [22027.291110] Modules linked in: dm_mod snd_hda_codec_realtek iTCO_wdt iTCO_vendor_support pcspkr snd_hda_intel i2c_i801 snd_hda_codec snd_hwdep snd_pcm snd_page_alloc snd_timer snd lpc_ich mfd_core soundcore battery ac option usb_wwan usbserial uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_core videodev i915 video button drm_kms_helper drm acpi_cpufreq mperf freq_table Sep 3 00:12:19 x-hswu33 kernel: [22027.291392] CPU: 1 PID: 16835 Comm: fbo-maxsize Not tainted 3.11.0-rc7_nightlytop_8fdad4_20130902_+ #7977 Sep 3 00:12:19 x-hswu33 kernel: [22027.291460] task: ffff8800712106d0 ti: ffff880028e4a000 task.ti: ffff880028e4a000 Sep 3 00:12:19 x-hswu33 kernel: [22027.291518] RIP: 0010:[] [] i915_gem_gtt_finish_object+0x68/0xbd [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.291602] RSP: 0018:ffff880028e4b9e8 EFLAGS: 00010246 Sep 3 00:12:19 x-hswu33 kernel: [22027.291640] RAX: 0000000000000000 RBX: ffff880145734000 RCX: ffff880145735328 Sep 3 00:12:19 x-hswu33 kernel: [22027.291689] RDX: ffff8801457353fc RSI: 0000000000000000 RDI: ffff88007597cc00 Sep 3 00:12:19 x-hswu33 kernel: [22027.291738] RBP: ffff88007597cc00 R08: 0000000000000001 R09: ffff88014f257f00 Sep 3 00:12:19 x-hswu33 kernel: [22027.291787] R10: ffffea0001d65f00 R11: 0000000000bba60b R12: ffff880149e5b000 Sep 3 00:12:19 x-hswu33 kernel: [22027.291837] R13: ffff880145734001 R14: ffff88007597ccc8 R15: ffff88007597cc00 Sep 3 00:12:19 x-hswu33 kernel: [22027.291887] FS: 00007ff5bc919740(0000) GS:ffff88014f240000(0000) knlGS:0000000000000000 Sep 3 00:12:19 x-hswu33 kernel: [22027.291943] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 Sep 3 00:12:19 x-hswu33 kernel: [22027.291983] CR2: 0000000000000008 CR3: 0000000028f4c000 CR4: 00000000001407e0 Sep 3 00:12:19 x-hswu33 kernel: [22027.292032] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 Sep 3 00:12:19 x-hswu33 kernel: [22027.292081] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Sep 3 00:12:19 x-hswu33 kernel: [22027.292130] Stack: Sep 3 00:12:19 x-hswu33 kernel: [22027.292145] 0000000000000000 ffff88007597cc00 ffff8801440d6840 0000000000000000 Sep 3 00:12:19 x-hswu33 kernel: [22027.292202] ffff880145734000 ffffffffa007c854 0000000000000010 ffff88007597c900 Sep 3 00:12:19 x-hswu33 kernel: [22027.292261] 0000000000018000 00000000004a1201 ffff88007597cc60 ffffffffa007d183 Sep 3 00:12:19 x-hswu33 kernel: [22027.292317] Call Trace: Sep 3 00:12:19 x-hswu33 kernel: [22027.292350] [] ? i915_vma_unbind+0xe2/0x1d1 [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.292410] [] ? __i915_gem_shrink+0xf1/0x162 [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.292464] [] ? i915_gem_object_get_pages_gtt+0xfa/0x303 [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.292527] [] ? i915_gem_object_get_pages+0x54/0x89 [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.292586] [] ? i915_gem_object_pin+0x238/0x5ce [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.292638] [] ? __sg_page_iter_next+0x2b/0x58 Sep 3 00:12:19 x-hswu33 kernel: [22027.292694] [] ? gen6_ppgtt_insert_entries+0xf2/0x114 [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.292754] [] ? i915_gem_execbuffer_reserve_vma.isra.13+0x79/0x18d [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.292820] [] ? i915_gem_execbuffer_reserve+0x21d/0x347 [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.292881] [] ? i915_gem_do_execbuffer.isra.17+0x4f3/0xe61 [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.292943] [] ? i915_gem_object_get_pages+0x54/0x89 [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.293002] [] ? i915_gem_pwrite_ioctl+0x743/0x7a5 [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.293060] [] ? i915_gem_execbuffer2+0x15e/0x1e4 [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.293123] [] ? drm_ioctl+0x2a5/0x3c4 [drm] Sep 3 00:12:19 x-hswu33 kernel: [22027.293173] [] ? i915_gem_execbuffer+0x37f/0x37f [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.293224] [] ? __do_page_fault+0x3ab/0x449 Sep 3 00:12:19 x-hswu33 kernel: [22027.293269] [] ? do_mmap_pgoff+0x2b2/0x341 Sep 3 00:12:19 x-hswu33 kernel: [22027.293317] [] ? vfs_ioctl+0x1e/0x31 Sep 3 00:12:19 x-hswu33 kernel: [22027.293354] [] ? do_vfs_ioctl+0x3ad/0x3ef Sep 3 00:12:19 x-hswu33 kernel: [22027.293396] [] ? SyS_ioctl+0x4e/0x7e Sep 3 00:12:19 x-hswu33 kernel: [22027.293435] [] ? system_call_fastpath+0x16/0x1b Sep 3 00:12:19 x-hswu33 kernel: [22027.293478] Code: 52 0c a0 48 c7 c6 22 30 0d a0 31 c0 e8 ef 00 f9 ff bf c6 a7 00 00 e8 90 5d 24 e1 f6 85 13 01 00 00 10 75 44 48 8b 85 18 01 00 00 <8b> 50 08 48 8b 30 49 8b 84 24 88 02 00 00 48 89 c7 48 81 c7 98 Sep 3 00:12:19 x-hswu33 kernel: [22027.293678] RIP [] i915_gem_gtt_finish_object+0x68/0xbd [i915] Sep 3 00:12:19 x-hswu33 kernel: [22027.293746] RSP Sep 3 00:12:19 x-hswu33 kernel: [22027.293773] CR2: 0000000000000008 Sep 3 00:12:20 x-hswu33 sh[3486]: abrt-dump-oops: Found oopses: 1 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68171 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 10 ++++------ drivers/gpu/drm/i915/intel_ringbuffer.c | 10 ++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0bca205..970f672 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2191,9 +2191,8 @@ int __i915_add_request(struct intel_ring_buffer *ring, if (ret) return ret; - request = kmalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) - return -ENOMEM; + request = ring->preallocated_lazy_request; + BUG_ON(request == NULL); /* Record the position of the start of the request so that * should we detect the updated seqno part-way through the @@ -2203,10 +2202,8 @@ int __i915_add_request(struct intel_ring_buffer *ring, request_ring_position = intel_ring_get_tail(ring); ret = ring->add_request(ring); - if (ret) { - kfree(request); + if (ret) return ret; - } request->seqno = intel_ring_get_seqno(ring); request->ring = ring; @@ -2245,6 +2242,7 @@ int __i915_add_request(struct intel_ring_buffer *ring, trace_i915_gem_request_add(ring, request->seqno); ring->outstanding_lazy_seqno = 0; + ring->preallocated_lazy_request = NULL; if (!dev_priv->ums.mm_suspended) { i915_queue_hangcheck(ring->dev); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 9aef08d..5864340 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1509,6 +1509,16 @@ intel_ring_alloc_seqno(struct intel_ring_buffer *ring) if (ring->outstanding_lazy_seqno) return 0; + if (ring->preallocated_lazy_request == NULL) { + struct drm_i915_gem_request *request; + + request = kmalloc(sizeof(*request), GFP_KERNEL); + if (request == NULL) + return -ENOMEM; + + ring->preallocated_lazy_request = request; + } + return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 3447c43..58d2e5e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -140,6 +140,7 @@ struct intel_ring_buffer { /** * Do we have some not yet emitted requests outstanding? */ + struct drm_i915_gem_request *preallocated_lazy_request; u32 outstanding_lazy_seqno; bool gpu_caches_dirty; bool fbc_dirty; -- 1.7.10.4