Skip to contentSkip to conversation

drm/omap: Misc fixes

PATCH In review Archit Taneja 3 participants 15 messages Apr 11, 2014 – Apr 16, 2014

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover drm/omap: Misc fixes

These are based over Tomi's 3.15/omapdrm-fixes branch.

Archit Taneja (5):
drm/omap: gem sync: wait on correct events
drm/omap: Fix crash when using LCD3 overlay manager drm/omap: Allow allocation of larger buffers
drm/omap: Use old_fb to synchronize between successive page flips drm/omap: protect omap_crtc's event with event_lock spinlock

Subhajit Paul (1):
drm/omap: Fix memory leak in omap_gem_op_async

 drivers/gpu/drm/omapdrm/omap_crtc.c |  7 ++++++-
 drivers/gpu/drm/omapdrm/omap_drv.c  | 10 ++++++----
 drivers/gpu/drm/omapdrm/omap_gem.c  |  6 ++++--
 drivers/video/omap2/dss/dispc.c     | 12 ++++++++++++
 include/video/omapdss.h             |  2 ++
 5 files changed, 30 insertions(+), 7 deletions(-)
Signature · 1 line
1.8.3.2
#1 lore raw

PATCH 1/6 drm/omap: Fix memory leak in omap_gem_op_async

From: Subhajit Paul <[email protected]>

In omap_gem_op_async(), if a waiter is not added to the wait list, it needs to be free'd in the function itself.

Make sure we free the waiter for this case.

---
 drivers/gpu/drm/omapdrm/omap_gem.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/gpu/drm/omapdrm/omap_gem.c +2 -0
index 5aec3e8..3199e3f 100644
@@ -1229,6 +1229,8 @@ int omap_gem_op_async(struct drm_gem_object *obj, enum omap_gem_op op,
 		}
 
 		spin_unlock(&sync_lock);
+
+		kfree(waiter);
 	}
 
 	/* no waiting.. */
Signature · 1 line
1.8.3.2
#2 lore raw

PATCH 2/6 drm/omap: gem sync: wait on correct events

In reply to Archit Taneja

A waiter of the type OMAP_GEM_READ should wait for a buffer to be completely written, and only then proceed with reading it. A similar logic applies for waiters with OMAP_GEM_WRITE flag.

Currently the function is_waiting() waits on the read_complete/read_target counts in the sync object.

This should be the other way round, as a reader should wait for users who are 'writing' to this buffer, and vice versa.

Make readers of the buffer(OMAP_GEM_READ) wait on the write counters, and writers to the buffer(OMAP_GEM_WRITE) wait on the read counters in is_waiting()

---
 drivers/gpu/drm/omapdrm/omap_gem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/omapdrm/omap_gem.c +2 -2
index 3199e3f..002b89d7 100644
@@ -1050,10 +1050,10 @@ static inline bool is_waiting(struct omap_gem_sync_waiter *waiter)
 {
 	struct omap_gem_object *omap_obj = waiter->omap_obj;
 	if ((waiter->op & OMAP_GEM_READ) &&
-			(omap_obj->sync->read_complete < waiter->read_target))
+			(omap_obj->sync->write_complete < waiter->write_target))
 		return true;
 	if ((waiter->op & OMAP_GEM_WRITE) &&
-			(omap_obj->sync->write_complete < waiter->write_target))
+			(omap_obj->sync->read_complete < waiter->read_target))
 		return true;
 	return false;
 }
Signature · 1 line
1.8.3.2
#3 lore raw

PATCH 3/6 drm/omap: Fix crash when using LCD3 overlay manager

In reply to Archit Taneja

The channel_names list didn't have a string populated for LCD3 manager, this results in a crash when the display's output is connected to LCD3. Add an entry for LCD3.

---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 1 +
 1 file changed, 1 insertion(+)
drivers/gpu/drm/omapdrm/omap_crtc.c +1 -0
index 90916ab..62f28df 100644
@@ -654,6 +654,7 @@ static const char *channel_names[] = {
 		[OMAP_DSS_CHANNEL_LCD] = "lcd",
 		[OMAP_DSS_CHANNEL_DIGIT] = "tv",
 		[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
+		[OMAP_DSS_CHANNEL_LCD3] = "lcd3",
 };
 
 void omap_crtc_pre_init(void)
Signature · 1 line
1.8.3.2
#4 lore raw

PATCH 4/6 drm/omap: Allow allocation of larger buffers

In reply to Archit Taneja

The drm ioctl DRM_IOCTL_MODE_ADDFB2 doesn't let us allocate buffers which are greater than what is specified in the driver through dev->mode_config.

Create helpers for DISPC which return the max manager width and height supported by the device. The maximum width for a framebuffer is set to the combined width of the all the crtcs, assuming they are arranged horizontally.

---
 drivers/gpu/drm/omapdrm/omap_drv.c | 10 ++++++----
 drivers/video/omap2/dss/dispc.c    | 12 ++++++++++++
 include/video/omapdss.h            |  2 ++
 3 files changed, 20 insertions(+), 4 deletions(-)
drivers/gpu/drm/omapdrm/omap_drv.c +6 -4
index c8270e4..55ec575 100644
@@ -306,11 +306,13 @@ static int omap_modeset_init(struct drm_device *dev)
 	dev->mode_config.min_width = 32;
 	dev->mode_config.min_height = 32;
 
-	/* note: eventually will need some cpu_is_omapXYZ() type stuff here
-	 * to fill in these limits properly on different OMAP generations..
+	/*
+	 * Note: the maximum width is set to the combined width of all the
+	 * crtcs. We could assume the same for the maximum height too, but
+	 * we generally don't use such a configuration.
 	 */
-	dev->mode_config.max_width = 2048;
-	dev->mode_config.max_height = 2048;
+	dev->mode_config.max_width = num_crtcs * dispc_mgr_max_width();
+	dev->mode_config.max_height = dispc_mgr_max_height();
 
 	dev->mode_config.funcs = &omap_mode_config_funcs;
 
drivers/video/omap2/dss/dispc.c +12 -0
index 77d6221..47f9829 100644
@@ -2999,6 +2999,18 @@ void dispc_mgr_set_timings(enum omap_channel channel,
 }
 EXPORT_SYMBOL(dispc_mgr_set_timings);
 
+u16 dispc_mgr_max_width(void)
+{
+	return dispc.feat->mgr_width_max;
+}
+EXPORT_SYMBOL(dispc_mgr_max_width);
+
+u16 dispc_mgr_max_height(void)
+{
+	return dispc.feat->mgr_height_max;
+}
+EXPORT_SYMBOL(dispc_mgr_max_height);
+
 static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
 		u16 pck_div)
 {
include/video/omapdss.h +2 -0
index 3d7c51a..53637ac 100644
@@ -949,6 +949,8 @@ void dispc_mgr_set_lcd_config(enum omap_channel channel,
 		const struct dss_lcd_mgr_config *config);
 void dispc_mgr_set_timings(enum omap_channel channel,
 		const struct omap_video_timings *timings);
+u16 dispc_mgr_max_width(void);
+u16 dispc_mgr_max_height(void);
 void dispc_mgr_setup(enum omap_channel channel,
 		const struct omap_overlay_manager_info *info);
 
Signature · 1 line
1.8.3.2
#5 lore raw

Re: [PATCH 4/6] drm/omap: Allow allocation of larger buffers

Quoted 23 lines · Archit Taneja

The drm ioctl DRM_IOCTL_MODE_ADDFB2 doesn't let us allocate buffers which are greater than what is specified in the driver through dev->mode_config.

Create helpers for DISPC which return the max manager width and height supported by the device. The maximum width for a framebuffer is set to the combined width of the all the crtcs, assuming they are arranged horizontally.

---
 drivers/gpu/drm/omapdrm/omap_drv.c | 10 ++++++----
 drivers/video/omap2/dss/dispc.c    | 12 ++++++++++++
 include/video/omapdss.h            |  2 ++
 3 files changed, 20 insertions(+), 4 deletions(-)
drivers/gpu/drm/omapdrm/omap_drv.c +0 -1
index c8270e4..55ec575 100644
@@ -306,11 +306,13 @@ static int omap_modeset_init(struct drm_device *dev)
 	dev->mode_config.min_width = 32;
 	dev->mode_config.min_height = 32;
 
-	/* note: eventually will need some cpu_is_omapXYZ() type stuff here

drivers/gpu/drm/omapdrm/omap_drv.c static int omap_modeset_init(struct drm_device *dev) · line 315

Quoted 10 lines
drivers/gpu/drm/omapdrm/omap_drv.c +6 -3
-	 * to fill in these limits properly on different OMAP generations..
+	/*
+	 * Note: the maximum width is set to the combined width of all the
+	 * crtcs. We could assume the same for the maximum height too, but
+	 * we generally don't use such a configuration.
 	 */
-	dev->mode_config.max_width = 2048;
-	dev->mode_config.max_height = 2048;
+	dev->mode_config.max_width = num_crtcs * dispc_mgr_max_width();
+	dev->mode_config.max_height = dispc_mgr_max_height();

This looks very strange.

If the max size is supposed to be the maximum output size we support, then multiplying with num_crtcs doesn't make sense.

If, on the other hand, it tells the possible maximum size of the framebuffer in the memory, of which only small part is shown (where's the max size of that "part" defined, then?), then there should be no limits as the only limit is the size of the memory.

Tomi

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

#6 lore raw

Re: [PATCH 4/6] drm/omap: Allow allocation of larger buffers

Quoted 37 lines · Tomi Valkeinen
Quoted 23 lines · Archit Taneja

The drm ioctl DRM_IOCTL_MODE_ADDFB2 doesn't let us allocate buffers which are greater than what is specified in the driver through dev->mode_config.

Create helpers for DISPC which return the max manager width and height supported by the device. The maximum width for a framebuffer is set to the combined width of the all the crtcs, assuming they are arranged horizontally.

---
  drivers/gpu/drm/omapdrm/omap_drv.c | 10 ++++++----
  drivers/video/omap2/dss/dispc.c    | 12 ++++++++++++
  include/video/omapdss.h            |  2 ++
  3 files changed, 20 insertions(+), 4 deletions(-)
drivers/gpu/drm/omapdrm/omap_drv.c +0 -1
index c8270e4..55ec575 100644
@@ -306,11 +306,13 @@ static int omap_modeset_init(struct drm_device *dev)
  	dev->mode_config.min_width = 32;
  	dev->mode_config.min_height = 32;
 
-	/* note: eventually will need some cpu_is_omapXYZ() type stuff here

drivers/gpu/drm/omapdrm/omap_drv.c static int omap_modeset_init(struct drm_device *dev) · line 315

Quoted 10 lines
drivers/gpu/drm/omapdrm/omap_drv.c +6 -3
-	 * to fill in these limits properly on different OMAP generations..
+	/*
+	 * Note: the maximum width is set to the combined width of all the
+	 * crtcs. We could assume the same for the maximum height too, but
+	 * we generally don't use such a configuration.
  	 */
-	dev->mode_config.max_width = 2048;
-	dev->mode_config.max_height = 2048;
+	dev->mode_config.max_width = num_crtcs * dispc_mgr_max_width();
+	dev->mode_config.max_height = dispc_mgr_max_height();

This looks very strange.

Quoted 7 lines

If the max size is supposed to be the maximum output size we support, then multiplying with num_crtcs doesn't make sense.

If, on the other hand, it tells the possible maximum size of the framebuffer in the memory, of which only small part is shown (where's the max size of that "part" defined, then?), then there should be no limits as the only limit is the size of the memory.

These parameters are used to tell the max size of framebuffer we can allocate in memory.

I'm not sure why there is a limit in the first place, but if we have a really low minimum(like 2048 pixels right now), we can't have multiple displays showing different regions of the same buffer.

Archit

#7 lore raw

Re: [PATCH 4/6] drm/omap: Allow allocation of larger buffers

Quoted 51 lines · Archit Taneja
Quoted 42 lines · Tomi Valkeinen
Quoted 28 lines · Archit Taneja

The drm ioctl DRM_IOCTL_MODE_ADDFB2 doesn't let us allocate buffers which are
greater than what is specified in the driver through dev->mode_config.

Create helpers for DISPC which return the max manager width and height supported
by the device. The maximum width for a framebuffer is set to the combined width
of the all the crtcs, assuming they are arranged horizontally.

---
  drivers/gpu/drm/omapdrm/omap_drv.c | 10 ++++++----
  drivers/video/omap2/dss/dispc.c    | 12 ++++++++++++
  include/video/omapdss.h            |  2 ++
  3 files changed, 20 insertions(+), 4 deletions(-)
drivers/gpu/drm/omapdrm/omap_drv.c +0 -1
index c8270e4..55ec575 100644
@@ -306,11 +306,13 @@ static int omap_modeset_init(struct drm_device
 *dev)
      dev->mode_config.min_width = 32;
      dev->mode_config.min_height = 32;
 
-    /* note: eventually will need some cpu_is_omapXYZ() type stuff here

drivers/gpu/drm/omapdrm/omap_drv.c static int omap_modeset_init(struct drm_device · line 316

Quoted 10 lines
drivers/gpu/drm/omapdrm/omap_drv.c +6 -3
-     * to fill in these limits properly on different OMAP generations..
+    /*
+     * Note: the maximum width is set to the combined width of all the
+     * crtcs. We could assume the same for the maximum height too, but
+     * we generally don't use such a configuration.
       */
-    dev->mode_config.max_width = 2048;
-    dev->mode_config.max_height = 2048;
+    dev->mode_config.max_width = num_crtcs * dispc_mgr_max_width();
+    dev->mode_config.max_height = dispc_mgr_max_height();

This looks very strange.

Quoted 7 lines

If the max size is supposed to be the maximum output size we support, then multiplying with num_crtcs doesn't make sense.

If, on the other hand, it tells the possible maximum size of the framebuffer in the memory, of which only small part is shown (where's the max size of that "part" defined, then?), then there should be no limits as the only limit is the size of the memory.

Quoted 6 lines

These parameters are used to tell the max size of framebuffer we can allocate in memory.

I'm not sure why there is a limit in the first place, but if we have a really low minimum(like 2048 pixels right now), we can't have multiple displays showing different regions of the same buffer.

In that case shouldn't the limit be 0 (if that's allowed) or some surely high enough value, say, 32767. Why calculate it at all based on the dispc's maximum, if it has no relevance?

Tomi

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

#8 lore raw

Re: [PATCH 4/6] drm/omap: Allow allocation of larger buffers

Quoted 55 lines · Tomi Valkeinen
Quoted 54 lines · Archit Taneja
Quoted 42 lines · Tomi Valkeinen
Quoted 28 lines · Archit Taneja

The drm ioctl DRM_IOCTL_MODE_ADDFB2 doesn't let us allocate buffers which are
greater than what is specified in the driver through dev->mode_config.

Create helpers for DISPC which return the max manager width and height supported
by the device. The maximum width for a framebuffer is set to the combined width
of the all the crtcs, assuming they are arranged horizontally.

---
   drivers/gpu/drm/omapdrm/omap_drv.c | 10 ++++++----
   drivers/video/omap2/dss/dispc.c    | 12 ++++++++++++
   include/video/omapdss.h            |  2 ++
   3 files changed, 20 insertions(+), 4 deletions(-)
drivers/gpu/drm/omapdrm/omap_drv.c +0 -1
index c8270e4..55ec575 100644
@@ -306,11 +306,13 @@ static int omap_modeset_init(struct drm_device
 *dev)
       dev->mode_config.min_width = 32;
       dev->mode_config.min_height = 32;
 
-    /* note: eventually will need some cpu_is_omapXYZ() type stuff here

drivers/gpu/drm/omapdrm/omap_drv.c static int omap_modeset_init(struct drm_device · line 316

Quoted 10 lines
drivers/gpu/drm/omapdrm/omap_drv.c +6 -3
-     * to fill in these limits properly on different OMAP generations..
+    /*
+     * Note: the maximum width is set to the combined width of all the
+     * crtcs. We could assume the same for the maximum height too, but
+     * we generally don't use such a configuration.
        */
-    dev->mode_config.max_width = 2048;
-    dev->mode_config.max_height = 2048;
+    dev->mode_config.max_width = num_crtcs * dispc_mgr_max_width();
+    dev->mode_config.max_height = dispc_mgr_max_height();

This looks very strange.

Quoted 7 lines

If the max size is supposed to be the maximum output size we support, then multiplying with num_crtcs doesn't make sense.

If, on the other hand, it tells the possible maximum size of the framebuffer in the memory, of which only small part is shown (where's the max size of that "part" defined, then?), then there should be no limits as the only limit is the size of the memory.

These parameters are used to tell the max size of framebuffer we can allocate in memory.

Quoted 7 lines
Quoted 3 lines

I'm not sure why there is a limit in the first place, but if we have a really low minimum(like 2048 pixels right now), we can't have multiple displays showing different regions of the same buffer.

In that case shouldn't the limit be 0 (if that's allowed) or some surely high enough value, say, 32767. Why calculate it at all based on the dispc's maximum, if it has no relevance?

I understand your point. When I wrote the patch, I thought more like: "I have 3 displays arranged horizontally, if I want a buffer large enough to fill the 3 displays, what should be it's width/height?"

Archit

#9 lore raw

Re: [PATCH 4/6] drm/omap: Allow allocation of larger buffers

In reply to Archit Taneja
Quoted 23 lines · Archit Taneja

The drm ioctl DRM_IOCTL_MODE_ADDFB2 doesn't let us allocate buffers which are greater than what is specified in the driver through dev->mode_config.

Create helpers for DISPC which return the max manager width and height supported by the device. The maximum width for a framebuffer is set to the combined width of the all the crtcs, assuming they are arranged horizontally.

---
 drivers/gpu/drm/omapdrm/omap_drv.c | 10 ++++++----
 drivers/video/omap2/dss/dispc.c    | 12 ++++++++++++
 include/video/omapdss.h            |  2 ++
 3 files changed, 20 insertions(+), 4 deletions(-)
drivers/gpu/drm/omapdrm/omap_drv.c +0 -1
index c8270e4..55ec575 100644
@@ -306,11 +306,13 @@ static int omap_modeset_init(struct drm_device *dev)
        dev->mode_config.min_width = 32;
        dev->mode_config.min_height = 32;
 
-       /* note: eventually will need some cpu_is_omapXYZ() type stuff here

drivers/gpu/drm/omapdrm/omap_drv.c static int omap_modeset_init(struct drm_device *dev) · line 315

Quoted 10 lines
drivers/gpu/drm/omapdrm/omap_drv.c +6 -3
-        * to fill in these limits properly on different OMAP generations..
+       /*
+        * Note: the maximum width is set to the combined width of all the
+        * crtcs. We could assume the same for the maximum height too, but
+        * we generally don't use such a configuration.
         */
-       dev->mode_config.max_width = 2048;
-       dev->mode_config.max_height = 2048;
+       dev->mode_config.max_width = num_crtcs * dispc_mgr_max_width();
+       dev->mode_config.max_height = dispc_mgr_max_height();

the max_width should probably actually be the max_pitch..

BR,
-R

Quoted 41 lines
drivers/gpu/drm/omapdrm/omap_drv.c +0 -0
        dev->mode_config.funcs = &omap_mode_config_funcs;
 
drivers/video/omap2/dss/dispc.c +12 -0
index 77d6221..47f9829 100644
@@ -2999,6 +2999,18 @@ void dispc_mgr_set_timings(enum omap_channel channel,
 }
 EXPORT_SYMBOL(dispc_mgr_set_timings);
 
+u16 dispc_mgr_max_width(void)
+{
+       return dispc.feat->mgr_width_max;
+}
+EXPORT_SYMBOL(dispc_mgr_max_width);
+
+u16 dispc_mgr_max_height(void)
+{
+       return dispc.feat->mgr_height_max;
+}
+EXPORT_SYMBOL(dispc_mgr_max_height);
+
 static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
                u16 pck_div)
 {
include/video/omapdss.h +2 -1
index 3d7c51a..53637ac 100644
@@ -949,6 +949,8 @@ void dispc_mgr_set_lcd_config(enum omap_channel channel,
                const struct dss_lcd_mgr_config *config);
 void dispc_mgr_set_timings(enum omap_channel channel,
                const struct omap_video_timings *timings);
+u16 dispc_mgr_max_width(void);
+u16 dispc_mgr_max_height(void);
 void dispc_mgr_setup(enum omap_channel channel,
                const struct omap_overlay_manager_info *info);
 
--

1.8.3.2

#10 lore raw

PATCH 5/6 drm/omap: Use old_fb to synchronize between successive page flips

In reply to Archit Taneja

omap_crtc->old_fb is used to check whether the previous page flip has completed or not. However, it's never initialized to anything, so it's always NULL. This results in the check to always succeed, and the page_flip to proceed.

Initialize old_fb to the fb that we intend to flip to through page_flip, and therefore prevent a future page flip to proceed if the last one didn't complete.

---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/omapdrm/omap_crtc.c +1 -1
index 62f28df..d74c72c 100644
@@ -360,7 +360,7 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
 	}
 
 	omap_crtc->event = event;
-	crtc->fb = fb;
+	omap_crtc->old_fb = crtc->fb = fb;
 
 	/*
 	 * Hold a reference temporarily until the crtc is updated
Signature · 1 line
1.8.3.2
#11 lore raw

PATCH 6/6 drm/omap: protect omap_crtc's event with event_lock spinlock

In reply to Archit Taneja

The vblank_cb callback and the page_flip ioctl can occur together in different CPU contexts. vblank_cb uses takes tje drm device's event_lock spinlock when sending the vblank event and updating omap_crtc->event and omap_crtc->od_fb.

Use the same spinlock in page_flip, to make sure the above omap_crtc parameters are configured sequentially.

---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/gpu/drm/omapdrm/omap_crtc.c +4 -0
index d74c72c..9c7af42 100644
@@ -350,6 +350,7 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 	struct drm_gem_object *bo;
+	unsigned long flags;
 
 	DBG("%d -> %d (event=%p)", crtc->fb ? crtc->fb->base.id : -1,
 			fb->base.id, event);
@@ -359,9 +360,12 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
 		return -EINVAL;
 	}
 
+	spin_lock_irqsave(&dev->event_lock, flags);
+
 	omap_crtc->event = event;
 	omap_crtc->old_fb = crtc->fb = fb;
 
+	spin_unlock_irqrestore(&dev->event_lock, flags);
 	/*
 	 * Hold a reference temporarily until the crtc is updated
 	 * and takes the reference to the bo.  This avoids it
Signature · 1 line
1.8.3.2
#12 lore raw

Re: [PATCH 6/6] drm/omap: protect omap_crtc's event with event_lock spinlock

Quoted 25 lines · Archit Taneja

The vblank_cb callback and the page_flip ioctl can occur together in different CPU contexts. vblank_cb uses takes tje drm device's event_lock spinlock when sending the vblank event and updating omap_crtc->event and omap_crtc->od_fb.

Use the same spinlock in page_flip, to make sure the above omap_crtc parameters are configured sequentially.

---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/gpu/drm/omapdrm/omap_crtc.c +1 -0
index d74c72c..9c7af42 100644
@@ -350,6 +350,7 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
 	struct drm_device *dev = crtc->dev;
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 	struct drm_gem_object *bo;
+	unsigned long flags;
 
 	DBG("%d -> %d (event=%p)", crtc->fb ? crtc->fb->base.id : -1,
 			fb->base.id, event);

drivers/gpu/drm/omapdrm/omap_crtc.c static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, · line 368

Quoted 9 lines
drivers/gpu/drm/omapdrm/omap_crtc.c +3 -0
@@ -359,9 +360,12 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
 		return -EINVAL;
 	}
 
+	spin_lock_irqsave(&dev->event_lock, flags);
+
 	omap_crtc->event = event;
 	omap_crtc->old_fb = crtc->fb = fb;
 
+	spin_unlock_irqrestore(&dev->event_lock, flags);

There's

if (omap_crtc->old_fb)

just above the code you changed. Shouldn't that also be inside the spinlock?

Also, the description contains a few typos.

Tomi

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel

#13 lore raw

Re: [PATCH 6/6] drm/omap: protect omap_crtc's event with event_lock spinlock

Hi,

Quoted 34 lines · Tomi Valkeinen
Quoted 33 lines · Archit Taneja

The vblank_cb callback and the page_flip ioctl can occur together in different CPU contexts. vblank_cb uses takes tje drm device's event_lock spinlock when sending the vblank event and updating omap_crtc->event and omap_crtc->od_fb.

Use the same spinlock in page_flip, to make sure the above omap_crtc parameters are configured sequentially.

---
  drivers/gpu/drm/omapdrm/omap_crtc.c | 4 ++++
  1 file changed, 4 insertions(+)
drivers/gpu/drm/omapdrm/omap_crtc.c +3 -0
index d74c72c..9c7af42 100644
@@ -350,6 +350,7 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
  	struct drm_device *dev = crtc->dev;
  	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
  	struct drm_gem_object *bo;
+	unsigned long flags;
 
  	DBG("%d -> %d (event=%p)", crtc->fb ? crtc->fb->base.id : -1,
  			fb->base.id, event);
@@ -359,9 +360,12 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
  		return -EINVAL;
  	}
 
+	spin_lock_irqsave(&dev->event_lock, flags);
+
  	omap_crtc->event = event;
  	omap_crtc->old_fb = crtc->fb = fb;
 
Quoted 7 lines

drivers/gpu/drm/omapdrm/omap_crtc.c static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, · line 368

Quoted 1 line
drivers/gpu/drm/omapdrm/omap_crtc.c +1 -0
+	spin_unlock_irqrestore(&dev->event_lock, flags);

There's

if (omap_crtc->old_fb)

just above the code you changed. Shouldn't that also be inside the spinlock?

Yes, that should come within the spinlock too.

On a related note, the mdp5_crtc->event in mdp5_crtc_page_flip(and for mdp4 crtc) should also be inside the spinlock.

Quoted 2 lines

Also, the description contains a few typos.

I'll fix these.

Thanks,
Archit

#14 lore raw
In reply to Archit Taneja

Hi,

Quoted 11 lines · Archit Taneja

These are based over Tomi's 3.15/omapdrm-fixes branch.

Archit Taneja (5):
drm/omap: gem sync: wait on correct events
drm/omap: Fix crash when using LCD3 overlay manager drm/omap: Allow allocation of larger buffers
drm/omap: Use old_fb to synchronize between successive page flips drm/omap: protect omap_crtc's event with event_lock spinlock

Subhajit Paul (1):
drm/omap: Fix memory leak in omap_gem_op_async

I've added all of these except "Allow allocation of larger buffers" to my omapdrm-fixes branch. I needed to do some small changes for the last two, but quite minor.

Tomi

_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel