* Re: [PATCH] drm/i915: Disallow preallocation of requests
2012-09-26 12:35 [PATCH] drm/i915: Disallow preallocation of requests Chris Wilson
@ 2012-09-26 12:41 ` Chris Wilson
2012-09-26 12:42 ` Chris Wilson
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Chris Wilson @ 2012-09-26 12:41 UTC (permalink / raw)
To: intel-gfx
On Wed, 26 Sep 2012 13:35:33 +0100, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> The intention was to allow the caller to avoid a failure to queue a
> request having already written commands to the ring. However, this is a
> moot point as the i915_add_request() can fail for other reasons than a
> mere allocation failure and those failure cases are more likely than
> ENOMEM. So the overlay code already had to handle i915_add_request()
> failures, and due to
>
> commit 3bb73aba1ed5198a2c1dfaac4f3c95459930d84a
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date: Fri Jul 20 12:40:59 2012 +0100
>
> drm/i915: Allow late allocation of request for i915_add_request()
>
> the error handling code in intel_overlay.c was subject to causing
> double-frees.
>
> Rather than further complicate i915_add_request() and callers, realise
> the battle is lost and adapt intel_overlay.c to take advantage of the
> late allocation of requests.
Ah crap. Compile tested, obviously not run.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH] drm/i915: Disallow preallocation of requests
2012-09-26 12:35 [PATCH] drm/i915: Disallow preallocation of requests Chris Wilson
2012-09-26 12:41 ` Chris Wilson
@ 2012-09-26 12:42 ` Chris Wilson
2012-09-26 12:44 ` Chris Wilson
2012-09-26 12:47 ` Chris Wilson
3 siblings, 0 replies; 7+ messages in thread
From: Chris Wilson @ 2012-09-26 12:42 UTC (permalink / raw)
To: intel-gfx
The intention was to allow the caller to avoid a failure to queue a
request having already written commands to the ring. However, this is a
moot point as the i915_add_request() can fail for other reasons than a
mere allocation failure and those failure cases are more likely than
ENOMEM. So the overlay code already had to handle i915_add_request()
failures, and due to
commit 3bb73aba1ed5198a2c1dfaac4f3c95459930d84a
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date: Fri Jul 20 12:40:59 2012 +0100
drm/i915: Allow late allocation of request for i915_add_request()
the error handling code in intel_overlay.c was subject to causing
double-frees.
Rather than further complicate i915_add_request() and callers, realise
the battle is lost and adapt intel_overlay.c to take advantage of the
late allocation of requests.
v2: handle callers passing in a NULL seqno
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_drv.h | 2 +-
drivers/gpu/drm/i915/i915_gem.c | 14 +++----
drivers/gpu/drm/i915/intel_overlay.c | 72 +++++++---------------------------
3 files changed, 23 insertions(+), 65 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index dddc3dc..d8d4736 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1468,7 +1468,7 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
int __must_check i915_gem_idle(struct drm_device *dev);
int i915_add_request(struct intel_ring_buffer *ring,
struct drm_file *file,
- struct drm_i915_gem_request *request);
+ u32 *seqno);
int __must_check i915_wait_seqno(struct intel_ring_buffer *ring,
uint32_t seqno);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b2effab..489d32d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2087,11 +2087,12 @@ i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
int
i915_add_request(struct intel_ring_buffer *ring,
struct drm_file *file,
- struct drm_i915_gem_request *request)
+ u32 *out_seqno)
{
drm_i915_private_t *dev_priv = ring->dev->dev_private;
- uint32_t seqno;
+ struct drm_i915_gem_request *request;
u32 request_ring_position;
+ u32 seqno;
int was_empty;
int ret;
@@ -2106,11 +2107,9 @@ i915_add_request(struct intel_ring_buffer *ring,
if (ret)
return ret;
- if (request == NULL) {
- request = kmalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
- }
+ request = kmalloc(sizeof(*request), GFP_KERNEL);
+ if (request == NULL)
+ return -ENOMEM;
seqno = i915_gem_next_request_seqno(ring);
@@ -2162,6 +2161,7 @@ i915_add_request(struct intel_ring_buffer *ring,
}
}
+ *out_seqno = seqno;
return 0;
}
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 2fa20a4..ebcbf48 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -210,7 +210,6 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
}
static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
- struct drm_i915_gem_request *request,
void (*tail)(struct intel_overlay *))
{
struct drm_device *dev = overlay->dev;
@@ -219,12 +218,10 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
int ret;
BUG_ON(overlay->last_flip_req);
- ret = i915_add_request(ring, NULL, request);
- if (ret) {
- kfree(request);
- return ret;
- }
- overlay->last_flip_req = request->seqno;
+ ret = i915_add_request(ring, NULL, &overlay->last_flip_req);
+ if (ret)
+ return ret;
+
overlay->flip_tail = tail;
ret = i915_wait_seqno(ring, overlay->last_flip_req);
if (ret)
@@ -241,7 +238,6 @@ static int intel_overlay_on(struct intel_overlay *overlay)
struct drm_device *dev = overlay->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
- struct drm_i915_gem_request *request;
int ret;
BUG_ON(overlay->active);
@@ -249,17 +245,9 @@ static int intel_overlay_on(struct intel_overlay *overlay)
WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
ret = intel_ring_begin(ring, 4);
- if (ret) {
- kfree(request);
- goto out;
- }
+ if (ret)
+ return ret;
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
@@ -267,9 +255,7 @@ static int intel_overlay_on(struct intel_overlay *overlay)
intel_ring_emit(ring, MI_NOOP);
intel_ring_advance(ring);
- ret = intel_overlay_do_wait_request(overlay, request, NULL);
-out:
- return ret;
+ return intel_overlay_do_wait_request(overlay, NULL);
}
/* overlay needs to be enabled in OCMD reg */
@@ -279,17 +265,12 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
struct drm_device *dev = overlay->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
- struct drm_i915_gem_request *request;
u32 flip_addr = overlay->flip_addr;
u32 tmp;
int ret;
BUG_ON(!overlay->active);
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
if (load_polyphase_filter)
flip_addr |= OFC_UPDATE;
@@ -299,22 +280,14 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
ret = intel_ring_begin(ring, 2);
- if (ret) {
- kfree(request);
+ if (ret)
return ret;
- }
+
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
intel_ring_emit(ring, flip_addr);
intel_ring_advance(ring);
- ret = i915_add_request(ring, NULL, request);
- if (ret) {
- kfree(request);
- return ret;
- }
-
- overlay->last_flip_req = request->seqno;
- return 0;
+ return i915_add_request(ring, NULL, &overlay->last_flip_req);
}
static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
@@ -350,15 +323,10 @@ static int intel_overlay_off(struct intel_overlay *overlay)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
u32 flip_addr = overlay->flip_addr;
- struct drm_i915_gem_request *request;
int ret;
BUG_ON(!overlay->active);
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
/* According to intel docs the overlay hw may hang (when switching
* off) without loading the filter coeffs. It is however unclear whether
* this applies to the disabling of the overlay or to the switching off
@@ -366,10 +334,9 @@ static int intel_overlay_off(struct intel_overlay *overlay)
flip_addr |= OFC_UPDATE;
ret = intel_ring_begin(ring, 6);
- if (ret) {
- kfree(request);
+ if (ret)
return ret;
- }
+
/* wait for overlay to go idle */
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
intel_ring_emit(ring, flip_addr);
@@ -380,8 +347,7 @@ static int intel_overlay_off(struct intel_overlay *overlay)
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
intel_ring_advance(ring);
- return intel_overlay_do_wait_request(overlay, request,
- intel_overlay_off_tail);
+ return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
}
/* recover from an interruption due to a signal
@@ -426,24 +392,16 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
return 0;
if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
- struct drm_i915_gem_request *request;
-
/* synchronous slowpath */
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
ret = intel_ring_begin(ring, 2);
- if (ret) {
- kfree(request);
+ if (ret)
return ret;
- }
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
intel_ring_emit(ring, MI_NOOP);
intel_ring_advance(ring);
- ret = intel_overlay_do_wait_request(overlay, request,
+ ret = intel_overlay_do_wait_request(overlay,
intel_overlay_release_old_vid_tail);
if (ret)
return ret;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH] drm/i915: Disallow preallocation of requests
2012-09-26 12:35 [PATCH] drm/i915: Disallow preallocation of requests Chris Wilson
2012-09-26 12:41 ` Chris Wilson
2012-09-26 12:42 ` Chris Wilson
@ 2012-09-26 12:44 ` Chris Wilson
2012-09-26 12:47 ` Chris Wilson
3 siblings, 0 replies; 7+ messages in thread
From: Chris Wilson @ 2012-09-26 12:44 UTC (permalink / raw)
To: intel-gfx
The intention was to allow the caller to avoid a failure to queue a
request having already written commands to the ring. However, this is a
moot point as the i915_add_request() can fail for other reasons than a
mere allocation failure and those failure cases are more likely than
ENOMEM. So the overlay code already had to handle i915_add_request()
failures, and due to
commit 3bb73aba1ed5198a2c1dfaac4f3c95459930d84a
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date: Fri Jul 20 12:40:59 2012 +0100
drm/i915: Allow late allocation of request for i915_add_request()
the error handling code in intel_overlay.c was subject to causing
double-frees, as found by coverity.
Rather than further complicate i915_add_request() and callers, realise
the battle is lost and adapt intel_overlay.c to take advantage of the
late allocation of requests.
v2: handle callers passing in a NULL seqno
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_drv.h | 2 +-
drivers/gpu/drm/i915/i915_gem.c | 14 +++----
drivers/gpu/drm/i915/intel_overlay.c | 72 +++++++---------------------------
3 files changed, 23 insertions(+), 65 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index dddc3dc..d8d4736 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1468,7 +1468,7 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
int __must_check i915_gem_idle(struct drm_device *dev);
int i915_add_request(struct intel_ring_buffer *ring,
struct drm_file *file,
- struct drm_i915_gem_request *request);
+ u32 *seqno);
int __must_check i915_wait_seqno(struct intel_ring_buffer *ring,
uint32_t seqno);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b2effab..489d32d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2087,11 +2087,12 @@ i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
int
i915_add_request(struct intel_ring_buffer *ring,
struct drm_file *file,
- struct drm_i915_gem_request *request)
+ u32 *out_seqno)
{
drm_i915_private_t *dev_priv = ring->dev->dev_private;
- uint32_t seqno;
+ struct drm_i915_gem_request *request;
u32 request_ring_position;
+ u32 seqno;
int was_empty;
int ret;
@@ -2106,11 +2107,9 @@ i915_add_request(struct intel_ring_buffer *ring,
if (ret)
return ret;
- if (request == NULL) {
- request = kmalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
- }
+ request = kmalloc(sizeof(*request), GFP_KERNEL);
+ if (request == NULL)
+ return -ENOMEM;
seqno = i915_gem_next_request_seqno(ring);
@@ -2162,6 +2161,7 @@ i915_add_request(struct intel_ring_buffer *ring,
}
}
+ *out_seqno = seqno;
return 0;
}
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 2fa20a4..ebcbf48 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -210,7 +210,6 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
}
static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
- struct drm_i915_gem_request *request,
void (*tail)(struct intel_overlay *))
{
struct drm_device *dev = overlay->dev;
@@ -219,12 +218,10 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
int ret;
BUG_ON(overlay->last_flip_req);
- ret = i915_add_request(ring, NULL, request);
- if (ret) {
- kfree(request);
- return ret;
- }
- overlay->last_flip_req = request->seqno;
+ ret = i915_add_request(ring, NULL, &overlay->last_flip_req);
+ if (ret)
+ return ret;
+
overlay->flip_tail = tail;
ret = i915_wait_seqno(ring, overlay->last_flip_req);
if (ret)
@@ -241,7 +238,6 @@ static int intel_overlay_on(struct intel_overlay *overlay)
struct drm_device *dev = overlay->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
- struct drm_i915_gem_request *request;
int ret;
BUG_ON(overlay->active);
@@ -249,17 +245,9 @@ static int intel_overlay_on(struct intel_overlay *overlay)
WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
ret = intel_ring_begin(ring, 4);
- if (ret) {
- kfree(request);
- goto out;
- }
+ if (ret)
+ return ret;
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
@@ -267,9 +255,7 @@ static int intel_overlay_on(struct intel_overlay *overlay)
intel_ring_emit(ring, MI_NOOP);
intel_ring_advance(ring);
- ret = intel_overlay_do_wait_request(overlay, request, NULL);
-out:
- return ret;
+ return intel_overlay_do_wait_request(overlay, NULL);
}
/* overlay needs to be enabled in OCMD reg */
@@ -279,17 +265,12 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
struct drm_device *dev = overlay->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
- struct drm_i915_gem_request *request;
u32 flip_addr = overlay->flip_addr;
u32 tmp;
int ret;
BUG_ON(!overlay->active);
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
if (load_polyphase_filter)
flip_addr |= OFC_UPDATE;
@@ -299,22 +280,14 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
ret = intel_ring_begin(ring, 2);
- if (ret) {
- kfree(request);
+ if (ret)
return ret;
- }
+
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
intel_ring_emit(ring, flip_addr);
intel_ring_advance(ring);
- ret = i915_add_request(ring, NULL, request);
- if (ret) {
- kfree(request);
- return ret;
- }
-
- overlay->last_flip_req = request->seqno;
- return 0;
+ return i915_add_request(ring, NULL, &overlay->last_flip_req);
}
static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
@@ -350,15 +323,10 @@ static int intel_overlay_off(struct intel_overlay *overlay)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
u32 flip_addr = overlay->flip_addr;
- struct drm_i915_gem_request *request;
int ret;
BUG_ON(!overlay->active);
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
/* According to intel docs the overlay hw may hang (when switching
* off) without loading the filter coeffs. It is however unclear whether
* this applies to the disabling of the overlay or to the switching off
@@ -366,10 +334,9 @@ static int intel_overlay_off(struct intel_overlay *overlay)
flip_addr |= OFC_UPDATE;
ret = intel_ring_begin(ring, 6);
- if (ret) {
- kfree(request);
+ if (ret)
return ret;
- }
+
/* wait for overlay to go idle */
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
intel_ring_emit(ring, flip_addr);
@@ -380,8 +347,7 @@ static int intel_overlay_off(struct intel_overlay *overlay)
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
intel_ring_advance(ring);
- return intel_overlay_do_wait_request(overlay, request,
- intel_overlay_off_tail);
+ return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
}
/* recover from an interruption due to a signal
@@ -426,24 +392,16 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
return 0;
if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
- struct drm_i915_gem_request *request;
-
/* synchronous slowpath */
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
ret = intel_ring_begin(ring, 2);
- if (ret) {
- kfree(request);
+ if (ret)
return ret;
- }
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
intel_ring_emit(ring, MI_NOOP);
intel_ring_advance(ring);
- ret = intel_overlay_do_wait_request(overlay, request,
+ ret = intel_overlay_do_wait_request(overlay,
intel_overlay_release_old_vid_tail);
if (ret)
return ret;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH] drm/i915: Disallow preallocation of requests
2012-09-26 12:35 [PATCH] drm/i915: Disallow preallocation of requests Chris Wilson
` (2 preceding siblings ...)
2012-09-26 12:44 ` Chris Wilson
@ 2012-09-26 12:47 ` Chris Wilson
2012-09-27 7:39 ` Jani Nikula
3 siblings, 1 reply; 7+ messages in thread
From: Chris Wilson @ 2012-09-26 12:47 UTC (permalink / raw)
To: intel-gfx
The intention was to allow the caller to avoid a failure to queue a
request having already written commands to the ring. However, this is a
moot point as the i915_add_request() can fail for other reasons than a
mere allocation failure and those failure cases are more likely than
ENOMEM. So the overlay code already had to handle i915_add_request()
failures, and due to
commit 3bb73aba1ed5198a2c1dfaac4f3c95459930d84a
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date: Fri Jul 20 12:40:59 2012 +0100
drm/i915: Allow late allocation of request for i915_add_request()
the error handling code in intel_overlay.c was subject to causing
double-frees, as found by coverity.
Rather than further complicate i915_add_request() and callers, realise
the battle is lost and adapt intel_overlay.c to take advantage of the
late allocation of requests.
v2: Handle callers passing in a NULL seqno.
v3: Ditto. This time for sure.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_drv.h | 2 +-
drivers/gpu/drm/i915/i915_gem.c | 15 +++----
drivers/gpu/drm/i915/intel_overlay.c | 72 +++++++---------------------------
3 files changed, 24 insertions(+), 65 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index dddc3dc..d8d4736 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1468,7 +1468,7 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
int __must_check i915_gem_idle(struct drm_device *dev);
int i915_add_request(struct intel_ring_buffer *ring,
struct drm_file *file,
- struct drm_i915_gem_request *request);
+ u32 *seqno);
int __must_check i915_wait_seqno(struct intel_ring_buffer *ring,
uint32_t seqno);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b2effab..014b95e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2087,11 +2087,12 @@ i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
int
i915_add_request(struct intel_ring_buffer *ring,
struct drm_file *file,
- struct drm_i915_gem_request *request)
+ u32 *out_seqno)
{
drm_i915_private_t *dev_priv = ring->dev->dev_private;
- uint32_t seqno;
+ struct drm_i915_gem_request *request;
u32 request_ring_position;
+ u32 seqno;
int was_empty;
int ret;
@@ -2106,11 +2107,9 @@ i915_add_request(struct intel_ring_buffer *ring,
if (ret)
return ret;
- if (request == NULL) {
- request = kmalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
- }
+ request = kmalloc(sizeof(*request), GFP_KERNEL);
+ if (request == NULL)
+ return -ENOMEM;
seqno = i915_gem_next_request_seqno(ring);
@@ -2162,6 +2161,8 @@ i915_add_request(struct intel_ring_buffer *ring,
}
}
+ if (out_seqno)
+ *out_seqno = seqno;
return 0;
}
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 2fa20a4..ebcbf48 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -210,7 +210,6 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
}
static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
- struct drm_i915_gem_request *request,
void (*tail)(struct intel_overlay *))
{
struct drm_device *dev = overlay->dev;
@@ -219,12 +218,10 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
int ret;
BUG_ON(overlay->last_flip_req);
- ret = i915_add_request(ring, NULL, request);
- if (ret) {
- kfree(request);
- return ret;
- }
- overlay->last_flip_req = request->seqno;
+ ret = i915_add_request(ring, NULL, &overlay->last_flip_req);
+ if (ret)
+ return ret;
+
overlay->flip_tail = tail;
ret = i915_wait_seqno(ring, overlay->last_flip_req);
if (ret)
@@ -241,7 +238,6 @@ static int intel_overlay_on(struct intel_overlay *overlay)
struct drm_device *dev = overlay->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
- struct drm_i915_gem_request *request;
int ret;
BUG_ON(overlay->active);
@@ -249,17 +245,9 @@ static int intel_overlay_on(struct intel_overlay *overlay)
WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
ret = intel_ring_begin(ring, 4);
- if (ret) {
- kfree(request);
- goto out;
- }
+ if (ret)
+ return ret;
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
@@ -267,9 +255,7 @@ static int intel_overlay_on(struct intel_overlay *overlay)
intel_ring_emit(ring, MI_NOOP);
intel_ring_advance(ring);
- ret = intel_overlay_do_wait_request(overlay, request, NULL);
-out:
- return ret;
+ return intel_overlay_do_wait_request(overlay, NULL);
}
/* overlay needs to be enabled in OCMD reg */
@@ -279,17 +265,12 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
struct drm_device *dev = overlay->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
- struct drm_i915_gem_request *request;
u32 flip_addr = overlay->flip_addr;
u32 tmp;
int ret;
BUG_ON(!overlay->active);
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
if (load_polyphase_filter)
flip_addr |= OFC_UPDATE;
@@ -299,22 +280,14 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
ret = intel_ring_begin(ring, 2);
- if (ret) {
- kfree(request);
+ if (ret)
return ret;
- }
+
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
intel_ring_emit(ring, flip_addr);
intel_ring_advance(ring);
- ret = i915_add_request(ring, NULL, request);
- if (ret) {
- kfree(request);
- return ret;
- }
-
- overlay->last_flip_req = request->seqno;
- return 0;
+ return i915_add_request(ring, NULL, &overlay->last_flip_req);
}
static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
@@ -350,15 +323,10 @@ static int intel_overlay_off(struct intel_overlay *overlay)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
u32 flip_addr = overlay->flip_addr;
- struct drm_i915_gem_request *request;
int ret;
BUG_ON(!overlay->active);
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
/* According to intel docs the overlay hw may hang (when switching
* off) without loading the filter coeffs. It is however unclear whether
* this applies to the disabling of the overlay or to the switching off
@@ -366,10 +334,9 @@ static int intel_overlay_off(struct intel_overlay *overlay)
flip_addr |= OFC_UPDATE;
ret = intel_ring_begin(ring, 6);
- if (ret) {
- kfree(request);
+ if (ret)
return ret;
- }
+
/* wait for overlay to go idle */
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
intel_ring_emit(ring, flip_addr);
@@ -380,8 +347,7 @@ static int intel_overlay_off(struct intel_overlay *overlay)
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
intel_ring_advance(ring);
- return intel_overlay_do_wait_request(overlay, request,
- intel_overlay_off_tail);
+ return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
}
/* recover from an interruption due to a signal
@@ -426,24 +392,16 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
return 0;
if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
- struct drm_i915_gem_request *request;
-
/* synchronous slowpath */
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (request == NULL)
- return -ENOMEM;
-
ret = intel_ring_begin(ring, 2);
- if (ret) {
- kfree(request);
+ if (ret)
return ret;
- }
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
intel_ring_emit(ring, MI_NOOP);
intel_ring_advance(ring);
- ret = intel_overlay_do_wait_request(overlay, request,
+ ret = intel_overlay_do_wait_request(overlay,
intel_overlay_release_old_vid_tail);
if (ret)
return ret;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH] drm/i915: Disallow preallocation of requests
2012-09-26 12:47 ` Chris Wilson
@ 2012-09-27 7:39 ` Jani Nikula
2012-09-27 11:46 ` Daniel Vetter
0 siblings, 1 reply; 7+ messages in thread
From: Jani Nikula @ 2012-09-27 7:39 UTC (permalink / raw)
To: Chris Wilson, intel-gfx
On Wed, 26 Sep 2012, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> The intention was to allow the caller to avoid a failure to queue a
> request having already written commands to the ring. However, this is a
> moot point as the i915_add_request() can fail for other reasons than a
> mere allocation failure and those failure cases are more likely than
> ENOMEM. So the overlay code already had to handle i915_add_request()
> failures, and due to
>
> commit 3bb73aba1ed5198a2c1dfaac4f3c95459930d84a
> Author: Chris Wilson <chris@chris-wilson.co.uk>
> Date: Fri Jul 20 12:40:59 2012 +0100
>
> drm/i915: Allow late allocation of request for i915_add_request()
>
> the error handling code in intel_overlay.c was subject to causing
> double-frees, as found by coverity.
>
> Rather than further complicate i915_add_request() and callers, realise
> the battle is lost and adapt intel_overlay.c to take advantage of the
> late allocation of requests.
>
> v2: Handle callers passing in a NULL seqno.
> v3: Ditto. This time for sure.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 2 +-
> drivers/gpu/drm/i915/i915_gem.c | 15 +++----
> drivers/gpu/drm/i915/intel_overlay.c | 72 +++++++---------------------------
> 3 files changed, 24 insertions(+), 65 deletions(-)
Looks good, and I also like the diffstat.
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index dddc3dc..d8d4736 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1468,7 +1468,7 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
> int __must_check i915_gem_idle(struct drm_device *dev);
> int i915_add_request(struct intel_ring_buffer *ring,
> struct drm_file *file,
> - struct drm_i915_gem_request *request);
> + u32 *seqno);
> int __must_check i915_wait_seqno(struct intel_ring_buffer *ring,
> uint32_t seqno);
> int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index b2effab..014b95e 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2087,11 +2087,12 @@ i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
> int
> i915_add_request(struct intel_ring_buffer *ring,
> struct drm_file *file,
> - struct drm_i915_gem_request *request)
> + u32 *out_seqno)
> {
> drm_i915_private_t *dev_priv = ring->dev->dev_private;
> - uint32_t seqno;
> + struct drm_i915_gem_request *request;
> u32 request_ring_position;
> + u32 seqno;
> int was_empty;
> int ret;
>
> @@ -2106,11 +2107,9 @@ i915_add_request(struct intel_ring_buffer *ring,
> if (ret)
> return ret;
>
> - if (request == NULL) {
> - request = kmalloc(sizeof(*request), GFP_KERNEL);
> - if (request == NULL)
> - return -ENOMEM;
> - }
> + request = kmalloc(sizeof(*request), GFP_KERNEL);
> + if (request == NULL)
> + return -ENOMEM;
>
> seqno = i915_gem_next_request_seqno(ring);
>
> @@ -2162,6 +2161,8 @@ i915_add_request(struct intel_ring_buffer *ring,
> }
> }
>
> + if (out_seqno)
> + *out_seqno = seqno;
> return 0;
> }
>
> diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
> index 2fa20a4..ebcbf48 100644
> --- a/drivers/gpu/drm/i915/intel_overlay.c
> +++ b/drivers/gpu/drm/i915/intel_overlay.c
> @@ -210,7 +210,6 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
> }
>
> static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
> - struct drm_i915_gem_request *request,
> void (*tail)(struct intel_overlay *))
> {
> struct drm_device *dev = overlay->dev;
> @@ -219,12 +218,10 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
> int ret;
>
> BUG_ON(overlay->last_flip_req);
> - ret = i915_add_request(ring, NULL, request);
> - if (ret) {
> - kfree(request);
> - return ret;
> - }
> - overlay->last_flip_req = request->seqno;
> + ret = i915_add_request(ring, NULL, &overlay->last_flip_req);
> + if (ret)
> + return ret;
> +
> overlay->flip_tail = tail;
> ret = i915_wait_seqno(ring, overlay->last_flip_req);
> if (ret)
> @@ -241,7 +238,6 @@ static int intel_overlay_on(struct intel_overlay *overlay)
> struct drm_device *dev = overlay->dev;
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
> - struct drm_i915_gem_request *request;
> int ret;
>
> BUG_ON(overlay->active);
> @@ -249,17 +245,9 @@ static int intel_overlay_on(struct intel_overlay *overlay)
>
> WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
>
> - request = kzalloc(sizeof(*request), GFP_KERNEL);
> - if (request == NULL) {
> - ret = -ENOMEM;
> - goto out;
> - }
> -
> ret = intel_ring_begin(ring, 4);
> - if (ret) {
> - kfree(request);
> - goto out;
> - }
> + if (ret)
> + return ret;
>
> intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
> intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
> @@ -267,9 +255,7 @@ static int intel_overlay_on(struct intel_overlay *overlay)
> intel_ring_emit(ring, MI_NOOP);
> intel_ring_advance(ring);
>
> - ret = intel_overlay_do_wait_request(overlay, request, NULL);
> -out:
> - return ret;
> + return intel_overlay_do_wait_request(overlay, NULL);
> }
>
> /* overlay needs to be enabled in OCMD reg */
> @@ -279,17 +265,12 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
> struct drm_device *dev = overlay->dev;
> drm_i915_private_t *dev_priv = dev->dev_private;
> struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
> - struct drm_i915_gem_request *request;
> u32 flip_addr = overlay->flip_addr;
> u32 tmp;
> int ret;
>
> BUG_ON(!overlay->active);
>
> - request = kzalloc(sizeof(*request), GFP_KERNEL);
> - if (request == NULL)
> - return -ENOMEM;
> -
> if (load_polyphase_filter)
> flip_addr |= OFC_UPDATE;
>
> @@ -299,22 +280,14 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
> DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
>
> ret = intel_ring_begin(ring, 2);
> - if (ret) {
> - kfree(request);
> + if (ret)
> return ret;
> - }
> +
> intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
> intel_ring_emit(ring, flip_addr);
> intel_ring_advance(ring);
>
> - ret = i915_add_request(ring, NULL, request);
> - if (ret) {
> - kfree(request);
> - return ret;
> - }
> -
> - overlay->last_flip_req = request->seqno;
> - return 0;
> + return i915_add_request(ring, NULL, &overlay->last_flip_req);
> }
>
> static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
> @@ -350,15 +323,10 @@ static int intel_overlay_off(struct intel_overlay *overlay)
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
> u32 flip_addr = overlay->flip_addr;
> - struct drm_i915_gem_request *request;
> int ret;
>
> BUG_ON(!overlay->active);
>
> - request = kzalloc(sizeof(*request), GFP_KERNEL);
> - if (request == NULL)
> - return -ENOMEM;
> -
> /* According to intel docs the overlay hw may hang (when switching
> * off) without loading the filter coeffs. It is however unclear whether
> * this applies to the disabling of the overlay or to the switching off
> @@ -366,10 +334,9 @@ static int intel_overlay_off(struct intel_overlay *overlay)
> flip_addr |= OFC_UPDATE;
>
> ret = intel_ring_begin(ring, 6);
> - if (ret) {
> - kfree(request);
> + if (ret)
> return ret;
> - }
> +
> /* wait for overlay to go idle */
> intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
> intel_ring_emit(ring, flip_addr);
> @@ -380,8 +347,7 @@ static int intel_overlay_off(struct intel_overlay *overlay)
> intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
> intel_ring_advance(ring);
>
> - return intel_overlay_do_wait_request(overlay, request,
> - intel_overlay_off_tail);
> + return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
> }
>
> /* recover from an interruption due to a signal
> @@ -426,24 +392,16 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
> return 0;
>
> if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
> - struct drm_i915_gem_request *request;
> -
> /* synchronous slowpath */
> - request = kzalloc(sizeof(*request), GFP_KERNEL);
> - if (request == NULL)
> - return -ENOMEM;
> -
> ret = intel_ring_begin(ring, 2);
> - if (ret) {
> - kfree(request);
> + if (ret)
> return ret;
> - }
>
> intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
> intel_ring_emit(ring, MI_NOOP);
> intel_ring_advance(ring);
>
> - ret = intel_overlay_do_wait_request(overlay, request,
> + ret = intel_overlay_do_wait_request(overlay,
> intel_overlay_release_old_vid_tail);
> if (ret)
> return ret;
> --
> 1.7.10.4
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] drm/i915: Disallow preallocation of requests
2012-09-27 7:39 ` Jani Nikula
@ 2012-09-27 11:46 ` Daniel Vetter
0 siblings, 0 replies; 7+ messages in thread
From: Daniel Vetter @ 2012-09-27 11:46 UTC (permalink / raw)
To: Jani Nikula; +Cc: intel-gfx
On Thu, Sep 27, 2012 at 10:39:53AM +0300, Jani Nikula wrote:
> On Wed, 26 Sep 2012, Chris Wilson <chris@chris-wilson.co.uk> wrote:
> > The intention was to allow the caller to avoid a failure to queue a
> > request having already written commands to the ring. However, this is a
> > moot point as the i915_add_request() can fail for other reasons than a
> > mere allocation failure and those failure cases are more likely than
> > ENOMEM. So the overlay code already had to handle i915_add_request()
> > failures, and due to
> >
> > commit 3bb73aba1ed5198a2c1dfaac4f3c95459930d84a
> > Author: Chris Wilson <chris@chris-wilson.co.uk>
> > Date: Fri Jul 20 12:40:59 2012 +0100
> >
> > drm/i915: Allow late allocation of request for i915_add_request()
> >
> > the error handling code in intel_overlay.c was subject to causing
> > double-frees, as found by coverity.
> >
> > Rather than further complicate i915_add_request() and callers, realise
> > the battle is lost and adapt intel_overlay.c to take advantage of the
> > late allocation of requests.
> >
> > v2: Handle callers passing in a NULL seqno.
> > v3: Ditto. This time for sure.
> >
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > ---
> > drivers/gpu/drm/i915/i915_drv.h | 2 +-
> > drivers/gpu/drm/i915/i915_gem.c | 15 +++----
> > drivers/gpu/drm/i915/intel_overlay.c | 72 +++++++---------------------------
> > 3 files changed, 24 insertions(+), 65 deletions(-)
>
> Looks good, and I also like the diffstat.
>
> Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Picked up for -fixes, thanks for the patch.
-Daniel
>
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index dddc3dc..d8d4736 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1468,7 +1468,7 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
> > int __must_check i915_gem_idle(struct drm_device *dev);
> > int i915_add_request(struct intel_ring_buffer *ring,
> > struct drm_file *file,
> > - struct drm_i915_gem_request *request);
> > + u32 *seqno);
> > int __must_check i915_wait_seqno(struct intel_ring_buffer *ring,
> > uint32_t seqno);
> > int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
> > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> > index b2effab..014b95e 100644
> > --- a/drivers/gpu/drm/i915/i915_gem.c
> > +++ b/drivers/gpu/drm/i915/i915_gem.c
> > @@ -2087,11 +2087,12 @@ i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
> > int
> > i915_add_request(struct intel_ring_buffer *ring,
> > struct drm_file *file,
> > - struct drm_i915_gem_request *request)
> > + u32 *out_seqno)
> > {
> > drm_i915_private_t *dev_priv = ring->dev->dev_private;
> > - uint32_t seqno;
> > + struct drm_i915_gem_request *request;
> > u32 request_ring_position;
> > + u32 seqno;
> > int was_empty;
> > int ret;
> >
> > @@ -2106,11 +2107,9 @@ i915_add_request(struct intel_ring_buffer *ring,
> > if (ret)
> > return ret;
> >
> > - if (request == NULL) {
> > - request = kmalloc(sizeof(*request), GFP_KERNEL);
> > - if (request == NULL)
> > - return -ENOMEM;
> > - }
> > + request = kmalloc(sizeof(*request), GFP_KERNEL);
> > + if (request == NULL)
> > + return -ENOMEM;
> >
> > seqno = i915_gem_next_request_seqno(ring);
> >
> > @@ -2162,6 +2161,8 @@ i915_add_request(struct intel_ring_buffer *ring,
> > }
> > }
> >
> > + if (out_seqno)
> > + *out_seqno = seqno;
> > return 0;
> > }
> >
> > diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
> > index 2fa20a4..ebcbf48 100644
> > --- a/drivers/gpu/drm/i915/intel_overlay.c
> > +++ b/drivers/gpu/drm/i915/intel_overlay.c
> > @@ -210,7 +210,6 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
> > }
> >
> > static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
> > - struct drm_i915_gem_request *request,
> > void (*tail)(struct intel_overlay *))
> > {
> > struct drm_device *dev = overlay->dev;
> > @@ -219,12 +218,10 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
> > int ret;
> >
> > BUG_ON(overlay->last_flip_req);
> > - ret = i915_add_request(ring, NULL, request);
> > - if (ret) {
> > - kfree(request);
> > - return ret;
> > - }
> > - overlay->last_flip_req = request->seqno;
> > + ret = i915_add_request(ring, NULL, &overlay->last_flip_req);
> > + if (ret)
> > + return ret;
> > +
> > overlay->flip_tail = tail;
> > ret = i915_wait_seqno(ring, overlay->last_flip_req);
> > if (ret)
> > @@ -241,7 +238,6 @@ static int intel_overlay_on(struct intel_overlay *overlay)
> > struct drm_device *dev = overlay->dev;
> > struct drm_i915_private *dev_priv = dev->dev_private;
> > struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
> > - struct drm_i915_gem_request *request;
> > int ret;
> >
> > BUG_ON(overlay->active);
> > @@ -249,17 +245,9 @@ static int intel_overlay_on(struct intel_overlay *overlay)
> >
> > WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
> >
> > - request = kzalloc(sizeof(*request), GFP_KERNEL);
> > - if (request == NULL) {
> > - ret = -ENOMEM;
> > - goto out;
> > - }
> > -
> > ret = intel_ring_begin(ring, 4);
> > - if (ret) {
> > - kfree(request);
> > - goto out;
> > - }
> > + if (ret)
> > + return ret;
> >
> > intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
> > intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
> > @@ -267,9 +255,7 @@ static int intel_overlay_on(struct intel_overlay *overlay)
> > intel_ring_emit(ring, MI_NOOP);
> > intel_ring_advance(ring);
> >
> > - ret = intel_overlay_do_wait_request(overlay, request, NULL);
> > -out:
> > - return ret;
> > + return intel_overlay_do_wait_request(overlay, NULL);
> > }
> >
> > /* overlay needs to be enabled in OCMD reg */
> > @@ -279,17 +265,12 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
> > struct drm_device *dev = overlay->dev;
> > drm_i915_private_t *dev_priv = dev->dev_private;
> > struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
> > - struct drm_i915_gem_request *request;
> > u32 flip_addr = overlay->flip_addr;
> > u32 tmp;
> > int ret;
> >
> > BUG_ON(!overlay->active);
> >
> > - request = kzalloc(sizeof(*request), GFP_KERNEL);
> > - if (request == NULL)
> > - return -ENOMEM;
> > -
> > if (load_polyphase_filter)
> > flip_addr |= OFC_UPDATE;
> >
> > @@ -299,22 +280,14 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
> > DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
> >
> > ret = intel_ring_begin(ring, 2);
> > - if (ret) {
> > - kfree(request);
> > + if (ret)
> > return ret;
> > - }
> > +
> > intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
> > intel_ring_emit(ring, flip_addr);
> > intel_ring_advance(ring);
> >
> > - ret = i915_add_request(ring, NULL, request);
> > - if (ret) {
> > - kfree(request);
> > - return ret;
> > - }
> > -
> > - overlay->last_flip_req = request->seqno;
> > - return 0;
> > + return i915_add_request(ring, NULL, &overlay->last_flip_req);
> > }
> >
> > static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
> > @@ -350,15 +323,10 @@ static int intel_overlay_off(struct intel_overlay *overlay)
> > struct drm_i915_private *dev_priv = dev->dev_private;
> > struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
> > u32 flip_addr = overlay->flip_addr;
> > - struct drm_i915_gem_request *request;
> > int ret;
> >
> > BUG_ON(!overlay->active);
> >
> > - request = kzalloc(sizeof(*request), GFP_KERNEL);
> > - if (request == NULL)
> > - return -ENOMEM;
> > -
> > /* According to intel docs the overlay hw may hang (when switching
> > * off) without loading the filter coeffs. It is however unclear whether
> > * this applies to the disabling of the overlay or to the switching off
> > @@ -366,10 +334,9 @@ static int intel_overlay_off(struct intel_overlay *overlay)
> > flip_addr |= OFC_UPDATE;
> >
> > ret = intel_ring_begin(ring, 6);
> > - if (ret) {
> > - kfree(request);
> > + if (ret)
> > return ret;
> > - }
> > +
> > /* wait for overlay to go idle */
> > intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
> > intel_ring_emit(ring, flip_addr);
> > @@ -380,8 +347,7 @@ static int intel_overlay_off(struct intel_overlay *overlay)
> > intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
> > intel_ring_advance(ring);
> >
> > - return intel_overlay_do_wait_request(overlay, request,
> > - intel_overlay_off_tail);
> > + return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
> > }
> >
> > /* recover from an interruption due to a signal
> > @@ -426,24 +392,16 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
> > return 0;
> >
> > if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
> > - struct drm_i915_gem_request *request;
> > -
> > /* synchronous slowpath */
> > - request = kzalloc(sizeof(*request), GFP_KERNEL);
> > - if (request == NULL)
> > - return -ENOMEM;
> > -
> > ret = intel_ring_begin(ring, 2);
> > - if (ret) {
> > - kfree(request);
> > + if (ret)
> > return ret;
> > - }
> >
> > intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
> > intel_ring_emit(ring, MI_NOOP);
> > intel_ring_advance(ring);
> >
> > - ret = intel_overlay_do_wait_request(overlay, request,
> > + ret = intel_overlay_do_wait_request(overlay,
> > intel_overlay_release_old_vid_tail);
> > if (ret)
> > return ret;
> > --
> > 1.7.10.4
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 7+ messages in thread