Re: [PATCH v2 1/4] media i.MX27 camera: migrate driver to videobuf2
Hi Guennadi, thank you for your time. On 27 January 2012 16:25, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: A general question for mx2-camera: does it now after removal of legacy i.MX27 support only support i.MX25 (state: unknown) and i.MX27 in eMMA mode? I understand so. I'll send a v3 of this patch fixing what you've pointed out. Regards. -- Javier Martin Vista Silicon S.L. CDTUC - FASE C - Oficina S-345 Avda de los Castros s/n 39005- Santander. Cantabria. Spain +34 942 25 32 60 www.vista-silicon.com -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/4] media i.MX27 camera: add start_stream and stop_stream callbacks.
Hi, On 27 January 2012 16:53, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: On Thu, 26 Jan 2012, Javier Martin wrote: Add start_stream and stop_stream callback in order to enable and disable the eMMa-PrP properly and save CPU usage avoiding IRQs when the device is not streaming. This also makes the driver return 0 as the sequence number of the first frame. Signed-off-by: Javier Martin javier.mar...@vista-silicon.com --- Merge media i.MX27 camera: properly detect frame loss --- drivers/media/video/mx2_camera.c | 104 +- 1 files changed, 79 insertions(+), 25 deletions(-) diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 898f98f..045c018 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -377,7 +377,7 @@ static int mx2_camera_add_device(struct soc_camera_device *icd) writel(pcdev-csicr1, pcdev-base_csi + CSICR1); pcdev-icd = icd; - pcdev-frame_count = 0; + pcdev-frame_count = -1; dev_info(icd-parent, Camera driver attached to camera %d\n, icd-devnum); @@ -647,11 +647,83 @@ static void mx2_videobuf_release(struct vb2_buffer *vb) spin_unlock_irqrestore(pcdev-lock, flags); } +static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct soc_camera_device *icd = soc_camera_from_vb2q(q); + struct soc_camera_host *ici = + to_soc_camera_host(icd-parent); + struct mx2_camera_dev *pcdev = ici-priv; + struct mx2_fmt_cfg *prp = pcdev-emma_prp; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(pcdev-lock, flags); + if (mx27_camera_emma(pcdev)) { + if (count 2) { + ret = -EINVAL; + goto err; + } How about: if (mx27_camera_emma(pcdev)) { unsigned long flags; if (count 2) return -EINVAL; spin_lock_irqsave(pcdev-lock, flags); ... spin_unlock_irqrestore(pcdev-lock, flags); } return 0; OK, this is definitely cleaner. I'll do it for v3. Another point: in v1 of this patch you also removed goto out from mx2_videobuf_queue(). I understand this is probably unrelated to this patch now. Anyway, if you don't find a patch out of your 4 now, where it logically would fit, you could either make an additional patch, or I could do it myself, if I don't forget:-) Don't worry, I'll send a new series including that patch after this one gets merged. Regards. -- Javier Martin Vista Silicon S.L. CDTUC - FASE C - Oficina S-345 Avda de los Castros s/n 39005- Santander. Cantabria. Spain +34 942 25 32 60 www.vista-silicon.com -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Linaro-mm-sig] [PATCH 12/15] drivers: add Contiguous Memory Allocator
Hi Marek, On Mon, Jan 30, 2012 at 9:43 AM, Marek Szyprowski m.szyprow...@samsung.com wrote: Did you managed to fix this issue? Yes -- the recent increase in the vmalloc region triggered a bigger truncation in the system RAM than we had before, and therefore conflicted with the previous hardcoded region we were using. Long term, our plan is to get rid of those hardcoded values, but for the moment our remote RTOS still needs to know the physical address in advance. Right, thanks for spotting it, I will squash it to the next release. Thanks. With that hunk squashed in, feel free to add my Tested-by tag to the patches. Thanks! Ohad. -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH][media] s5p-g2d: Add HFLIP and VFLIP support
This patch adds support for flipping the image horizontally and vertically. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org --- drivers/media/video/s5p-g2d/g2d-hw.c |5 +++ drivers/media/video/s5p-g2d/g2d.c| 47 +++-- drivers/media/video/s5p-g2d/g2d.h|3 ++ 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/drivers/media/video/s5p-g2d/g2d-hw.c b/drivers/media/video/s5p-g2d/g2d-hw.c index 39937cf..5b86cbe 100644 --- a/drivers/media/video/s5p-g2d/g2d-hw.c +++ b/drivers/media/video/s5p-g2d/g2d-hw.c @@ -77,6 +77,11 @@ void g2d_set_rop4(struct g2d_dev *d, u32 r) w(r, ROP4_REG); } +void g2d_set_flip(struct g2d_dev *d, u32 r) +{ + w(r, SRC_MSK_DIRECT_REG); +} + u32 g2d_cmd_stretch(u32 e) { e = 1; diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c index febaa67..dea9701 100644 --- a/drivers/media/video/s5p-g2d/g2d.c +++ b/drivers/media/video/s5p-g2d/g2d.c @@ -178,6 +178,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) { struct g2d_ctx *ctx = container_of(ctrl-handler, struct g2d_ctx, ctrl_handler); + switch (ctrl-id) { case V4L2_CID_COLORFX: if (ctrl-val == V4L2_COLORFX_NEGATIVE) @@ -185,6 +186,21 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) else ctx-rop = ROP4_COPY; break; + + case V4L2_CID_HFLIP: + if (ctrl-val == 1) + ctx-hflip = 1; + else + ctx-hflip = 0; + break; + + case V4L2_CID_VFLIP: + if (ctrl-val == 1) + ctx-vflip = (1 1); + else + ctx-vflip = 0; + break; + default: v4l2_err(ctx-dev-v4l2_dev, unknown control\n); return -EINVAL; @@ -200,11 +216,9 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx) { struct g2d_dev *dev = ctx-dev; - v4l2_ctrl_handler_init(ctx-ctrl_handler, 1); - if (ctx-ctrl_handler.error) { - v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); - return ctx-ctrl_handler.error; - } + v4l2_ctrl_handler_init(ctx-ctrl_handler, 3); + if (ctx-ctrl_handler.error) + goto error; v4l2_ctrl_new_std_menu( ctx-ctrl_handler, @@ -214,12 +228,25 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx) ~((1 V4L2_COLORFX_NONE) | (1 V4L2_COLORFX_NEGATIVE)), V4L2_COLORFX_NONE); - if (ctx-ctrl_handler.error) { - v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); - return ctx-ctrl_handler.error; - } + if (ctx-ctrl_handler.error) + goto error; + + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + if (ctx-ctrl_handler.error) + goto error; + + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + if (ctx-ctrl_handler.error) + goto error; return 0; + +error: + v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); + return ctx-ctrl_handler.error; + } static int g2d_open(struct file *file) @@ -564,6 +591,8 @@ static void device_run(void *prv) g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); g2d_set_rop4(dev, ctx-rop); + g2d_set_flip(dev, ctx-hflip | ctx-vflip); + if (ctx-in.c_width != ctx-out.c_width || ctx-in.c_height != ctx-out.c_height) cmd |= g2d_cmd_stretch(1); diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/video/s5p-g2d/g2d.h index 5eae901..b3be3c8 100644 --- a/drivers/media/video/s5p-g2d/g2d.h +++ b/drivers/media/video/s5p-g2d/g2d.h @@ -59,6 +59,8 @@ struct g2d_ctx { struct g2d_frameout; struct v4l2_ctrl_handler ctrl_handler; u32 rop; + u32 hflip; + u32 vflip; }; struct g2d_fmt { @@ -77,6 +79,7 @@ void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a); void g2d_start(struct g2d_dev *d); void g2d_clear_int(struct g2d_dev *d); void g2d_set_rop4(struct g2d_dev *d, u32 r); +void g2d_set_flip(struct g2d_dev *d, u32 r); u32 g2d_cmd_stretch(u32 e); void g2d_set_cmd(struct g2d_dev *d, u32 c); -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] Format and frame rate configuration in subdev video and pad ops
Hi Sakari, On Sunday 29 January 2012 11:28:16 Sakari Ailus wrote: Hi all, We have now two type of subdev drivers, those which use the Media controller framework and those which do not. The former group implements v4l2_subdev_pad_ops for the purpose whereas the latter uses v4l2_subdev_video_ops. In practice the two implement essentially the same feature set. Same goes for simple bus receiver drivers (also called bridge) whereas all the more complex ISP drivers rightly use the pad ops. The two groups of drivers are currently mostly not mixable, and the reason is mostly the above, as far as I understand. To improve interoperability, it would be relatively easy to provide wrapper functions for either groups of the ISP / bus receiver drivers so they do need not to be changed to support both. This is something I've proposed a couple of months ago. I still stand by my proposal, it's a good idea. More complex sensor drivers, for example the SMIA++ exports more than one subdev for the configuration of sensor's image processing --- there is functionality which is present in ISPs only: cropping in three different locations and scaling in two. Many of the decisions in the configuration are policy decisions and thus belong to user space. This kind of drivers cannot be utilised without Media controller support, and thus I believe it is right for even simple bus receiver drivers to implement Media controller support to allow all bridge / ISP drivers to use them. While not all the user space is not yet in place to support such drivers I have not forgotten work on this library --- it just takes time. There are two sets of wrappers that can be implemented to improve the current situation. After the full transition to pad ops (should it ever happen is to be decided, I guess) these wrappers could be removed. Wrappers for sensor drivers to implement pad ops using video ops. There's one pad on such subdevs and a few other restrictions: try formats cannot be supported since there is no v4l2_fh support in video ops. How should the try operations requiring v4l2_fh behave in this case? Should they just return the current ACTIVE format (or crop) or should they behave as ACTIVE version of the same op does? I might pick the first option as it's less wrong. Complete support is not possible due to lack of functionality in the interface. I'm not sure I would implement such wrappers. I think we should instead convert the sensor drivers to pad ops, and use the video ops through pad ops wrapper if the sensor is used with an ISP that doesn't support pad ops yet. Wrappers for sensor drivers to implement video ops using pad ops. This is trivial: all the information is available through the pad ops, with v4l2_subdev_format fields which == V4L2_SUBDEV_FORMAT_ACTIVE and pad == 0. The same mostly goes for crop: v4l2_crop contains a subset of information in v4l2_subdev_crop. Conclusion: to achieve maximum compatibility with bridge / ISP drivers using the two sets of ops, sensor / tuner etc. drivers should use pad ops to implement format, crop and frame rate configuration and enumeration. What is missing is a set of wrappers for sensor drivers to allow bridge and ISP drivers using either set of ops to use these sensor drivers. Comments, questions? relevant video ops: int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code); int (*enum_mbus_fsizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); int (*g_mbus_fmt)(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt); int (*try_mbus_fmt)(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt); int (*s_mbus_fmt)(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt); relevant pad ops: int (*enum_mbus_code)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh struct v4l2_subdev_mbus_code_enum *code); int (*enum_frame_size)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_frame_size_enum *fse); int (*enum_frame_interval)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_frame_interval_enum *fie) int (*get_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_format *format); int (*set_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_format *format); /** * struct v4l2_mbus_framefmt - frame format on the media bus * @width: frame width * @height: frame height * @code: data format code (from enum v4l2_mbus_pixelcode) * @field: used interlacing type (from enum v4l2_field) * @colorspace: colorspace of the data (from enum v4l2_colorspace) */ struct v4l2_mbus_framefmt { __u32
Re: [PATCH 01/15] mm: page_alloc: remove trailing whitespace
On Thu, Jan 26, 2012 at 10:00:43AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com Signed-off-by: Michal Nazarewicz min...@mina86.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Ordinarily, I do not like these sort of patches because they can interfere with git blame but as it is comments that are affected; Acked-by: Mel Gorman m...@csn.ul.ie Thanks -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 02/15] mm: page_alloc: update migrate type of pages on pcp when isolating
On Thu, Jan 26, 2012 at 10:00:44AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com This commit changes set_migratetype_isolate() so that it updates migrate type of pages on pcp list which is saved in their page_private. Signed-off-by: Michal Nazarewicz min...@mina86.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com --- include/linux/page-isolation.h |6 ++ mm/page_alloc.c|1 + mm/page_isolation.c| 24 3 files changed, 31 insertions(+), 0 deletions(-) diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h index 051c1b1..8c02c2b 100644 --- a/include/linux/page-isolation.h +++ b/include/linux/page-isolation.h @@ -27,6 +27,12 @@ extern int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn); /* + * Check all pages in pageblock, find the ones on pcp list, and set + * their page_private to MIGRATE_ISOLATE. + */ +extern void update_pcp_isolate_block(unsigned long pfn); + +/* * Internal funcs.Changes pageblock's migrate type. * Please use make_pagetype_isolated()/make_pagetype_movable(). */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e1c5656..70709e7 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5465,6 +5465,7 @@ out: if (!ret) { set_pageblock_migratetype(page, MIGRATE_ISOLATE); move_freepages_block(zone, page, MIGRATE_ISOLATE); + update_pcp_isolate_block(pfn); } spin_unlock_irqrestore(zone-lock, flags); diff --git a/mm/page_isolation.c b/mm/page_isolation.c index 4ae42bb..9ea2f6e 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -139,3 +139,27 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn) spin_unlock_irqrestore(zone-lock, flags); return ret ? 0 : -EBUSY; } + +/* must hold zone-lock */ +void update_pcp_isolate_block(unsigned long pfn) +{ + unsigned long end_pfn = pfn + pageblock_nr_pages; + struct page *page; + + while (pfn end_pfn) { + if (!pfn_valid_within(pfn)) { + ++pfn; + continue; + } + There is a potential problem here that you need to be aware of. set_pageblock_migratetype() is called from start_isolate_page_range(). I do not think there is a guarantee that pfn + pageblock_nr_pages is not in a different block of MAX_ORDER_NR_PAGES. If that is right then your options are to add a check like this; if ((pfn (MAX_ORDER_NR_PAGES - 1)) == 0 !pfn_valid(pfn)) break; or else ensure that end_pfn is always MAX_ORDER_NR_PAGES aligned and in the same block as pfn and relying on the caller to have called pfn_valid. + page = pfn_to_page(pfn); + if (PageBuddy(page)) { + pfn += 1 page_order(page); + } else if (page_count(page) == 0) { + set_page_private(page, MIGRATE_ISOLATE); + ++pfn; This is dangerous for two reasons. If the page_count is 0, it could be because the page is in the process of being freed and is not necessarily on the per-cpu lists yet and you cannot be sure if the contents of page-private are important. Second, there is nothing to prevent another CPU allocating this page from its per-cpu list while the private field is getting updated from here which might lead to some interesting races. I recognise that what you are trying to do is respond to Gilad's request that you really check if an IPI here is necessary. I think what you need to do is check if a page with a count of 0 is encountered and if it is, then a draining of the per-cpu lists is necessary. To address Gilad's concerns, be sure to only this this once per attempt at CMA rather than for every page encountered with a count of 0 to avoid a storm of IPIs. + } else { + ++pfn; + } + } +} -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 03/15] mm: compaction: introduce isolate_migratepages_range().
On Thu, Jan 26, 2012 at 10:00:45AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com This commit introduces isolate_migratepages_range() function which extracts functionality from isolate_migratepages() so that it can be used on arbitrary PFN ranges. isolate_migratepages() function is implemented as a simple wrapper around isolate_migratepages_range(). Signed-off-by: Michal Nazarewicz min...@mina86.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Super, this is much easier to read. I have just one nit below but once that is fixed; Acked-by: Mel Gorman m...@csn.ul.ie @@ -313,7 +316,7 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone, } else if (!locked) spin_lock_irq(zone-lru_lock); - if (!pfn_valid_within(low_pfn)) + if (!pfn_valid(low_pfn)) continue; nr_scanned++; This chunk looks unrelated to the rest of the patch. I think what you are doing is patching around a bug that CMA exposed which is very similar to the bug report at http://www.spinics.net/lists/linux-mm/msg29260.html . Is this true? If so, I posted a fix that only calls pfn_valid() when necessary. Can you check if that works for you and if so, drop this hunk please? If the patch does not work for you, then this hunk still needs to be in a separate patch and handled separately as it would also be a fix for -stable. -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 04/15] mm: compaction: introduce isolate_freepages_range()
On Thu, Jan 26, 2012 at 10:00:46AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com This commit introduces isolate_freepages_range() function which generalises isolate_freepages_block() so that it can be used on arbitrary PFN ranges. isolate_freepages_block() is left with only minor changes. The minor changes to isolate_freepages_block() look fine in terms of how current compaction works. I have a minor comment on isolate_freepages_range() but it is up to you whether to address them or not. Whether you alter isolate_freepages_range() or not; Acked-by: Mel Gorman m...@csn.ul.ie SNIP @@ -105,6 +109,80 @@ static unsigned long isolate_freepages_block(struct zone *zone, return total_isolated; } +/** + * isolate_freepages_range() - isolate free pages. + * @start_pfn: The first PFN to start isolating. + * @end_pfn: The one-past-last PFN. + * + * Non-free pages, invalid PFNs, or zone boundaries within the + * [start_pfn, end_pfn) range are considered errors, cause function to + * undo its actions and return zero. + * + * Otherwise, function returns one-past-the-last PFN of isolated page + * (which may be greater then end_pfn if end fell in a middle of + * a free page). + */ +static unsigned long +isolate_freepages_range(unsigned long start_pfn, unsigned long end_pfn) +{ + unsigned long isolated, pfn, block_end_pfn, flags; + struct zone *zone = NULL; + LIST_HEAD(freelist); + struct page *page; + + for (pfn = start_pfn; pfn end_pfn; pfn += isolated) { + if (!pfn_valid(pfn)) + break; + + if (!zone) + zone = page_zone(pfn_to_page(pfn)); + else if (zone != page_zone(pfn_to_page(pfn))) + break; + So what you are checking for here is if you straddle zones. You could just initialise zone outside of the for loop. You can then check outside the loop if end_pfn is in a different zone to start_pfn. If it is, either adjust end_pfn accordingly or bail the entire operation avoiding the need for release_freepages() later. This will be a little cheaper. + /* + * On subsequent iterations round_down() is actually not + * needed, but we keep it that we not to complicate the code. + */ + block_end_pfn = round_down(pfn, pageblock_nr_pages) + + pageblock_nr_pages; Seems a little more involved than it needs to be. Something like this might suit and be a bit nicer? block_end_pfn = ALIGN(pfn+1, pageblock_nr_pages); + block_end_pfn = min(block_end_pfn, end_pfn); + + spin_lock_irqsave(zone-lock, flags); + isolated = isolate_freepages_block(pfn, block_end_pfn, +freelist, true); + spin_unlock_irqrestore(zone-lock, flags); + + /* + * In strict mode, isolate_freepages_block() returns 0 if + * there are any holes in the block (ie. invalid PFNs or + * non-free pages). + */ + if (!isolated) + break; + + /* + * If we managed to isolate pages, it is always (1 n) * + * pageblock_nr_pages for some non-negative n. (Max order + * page may span two pageblocks). + */ + } + + /* split_free_page does not map the pages */ + list_for_each_entry(page, freelist, lru) { + arch_alloc_page(page, 0); + kernel_map_pages(page, 1, 1); + } + This block is copied in two places - isolate_freepages and isolate_freepages_range() so sharing a common helper would be nice. I suspect you didn't because it would interfere with existing code more than was strictly necessary which I complained about previously as it made review harder. If that was your thinking, then just create this helper in a separate patch. It's not critical though. + if (pfn end_pfn) { + /* Loop terminated early, cleanup. */ + release_freepages(freelist); + return 0; + } + + /* We don't use freelists for anything. */ + return pfn; +} + /* Returns true if the page is within a block suitable for migration to */ static bool suitable_migration_target(struct page *page) { -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[GIT PULL FOR v3.3] OMAP3 ISP fix
Hi Mauro, Here's one patch for v3.3 that fixes a regression. The patch was included in v3.2, but a merge conflict coupled with a bad conflict resolution removed it from v3.3. The following changes since commit dcd6c92267155e70a94b3927bce681ce74b80d1f: Linux 3.3-rc1 (2012-01-19 15:04:48 -0800) are available in the git repository at: git://linuxtv.org/pinchartl/media.git omap3isp-omap3isp-stable Laurent Pinchart (1): omap3isp: Fix crash caused by subdevs now having a pointer to devnodes drivers/media/video/omap3isp/ispccdc.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 04/15] mm: compaction: introduce isolate_freepages_range()
On Mon, Jan 30, 2012 at 11:48:20AM +, Mel Gorman wrote: + if (!zone) + zone = page_zone(pfn_to_page(pfn)); + else if (zone != page_zone(pfn_to_page(pfn))) + break; + So what you are checking for here is if you straddle zones. You could just initialise zone outside of the for loop. You can then check outside the loop if end_pfn is in a different zone to start_pfn. If it is, either adjust end_pfn accordingly or bail the entire operation avoiding the need for release_freepages() later. This will be a little cheaper. Whoops, silly me! You are watching for overlapping zones which can happen in some rare configurations and for that checking page_zone() like this is necessary. You can still initialise zone outside the loop but the page_zone() check is still necessary. My bad. -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 05/15] mm: compaction: export some of the functions
On Thu, Jan 26, 2012 at 10:00:47AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com This commit exports some of the functions from compaction.c file outside of it adding their declaration into internal.h header file so that other mm related code can use them. This forced compaction.c to always be compiled (as opposed to being compiled only if CONFIG_COMPACTION is defined) but as to avoid introducing code that user did not ask for, part of the compaction.c is now wrapped in on #ifdef. Signed-off-by: Michal Nazarewicz min...@mina86.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com --- mm/Makefile |3 +- mm/compaction.c | 314 ++- mm/internal.h | 33 ++ 3 files changed, 184 insertions(+), 166 deletions(-) diff --git a/mm/Makefile b/mm/Makefile index 50ec00e..8aada89 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -13,7 +13,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ readahead.o swap.o truncate.o vmscan.o shmem.o \ prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \ page_isolation.o mm_init.o mmu_context.o percpu.o \ -$(mmu-y) +compaction.o $(mmu-y) obj-y += init-mm.o ifdef CONFIG_NO_BOOTMEM @@ -32,7 +32,6 @@ obj-$(CONFIG_NUMA) += mempolicy.o obj-$(CONFIG_SPARSEMEM) += sparse.o obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o obj-$(CONFIG_SLOB) += slob.o -obj-$(CONFIG_COMPACTION) += compaction.o obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o obj-$(CONFIG_KSM) += ksm.o obj-$(CONFIG_PAGE_POISONING) += debug-pagealloc.o diff --git a/mm/compaction.c b/mm/compaction.c index 63f82be..3e21d28 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -16,30 +16,11 @@ #include linux/sysfs.h #include internal.h +#if defined CONFIG_COMPACTION || defined CONFIG_CMA + This is pedantic but you reference CONFIG_CMA before the patch that declares it. The only time this really matters is when it breaks bisection but I do not think that is the case here. Whether you fix this or not by moving the CONFIG_CMA check to the same patch that declares it in Kconfig Acked-by: Mel Gorman m...@csn.ul.ie -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] [media] omap3isp: ccdc: Fix crash in HS/VS interrupt handler
The HS/VS interrupt handler needs to access the pipeline object. It erronously tries to get it from the CCDC output video node, which isn't necessarily included in the pipeline. This leads to a NULL pointer dereference. Fix the bug by getting the pipeline object from the CCDC subdev entity. Reported-by: Gary Thomas g...@mlbassoc.com Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Acked-by: Sakari Ailus sakari.ai...@iki.fi Signed-off-by: Mauro Carvalho Chehab mche...@redhat.com CC: sta...@kernel.org --- drivers/media/video/omap3isp/ispccdc.c |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) This patch fixes a crash in v3.2 and is included in v3.3-rc1. It isn't applicable to previous kernel versions. diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c index b0b0fa5..9012b57 100644 --- a/drivers/media/video/omap3isp/ispccdc.c +++ b/drivers/media/video/omap3isp/ispccdc.c @@ -1406,8 +1406,7 @@ static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event) static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc) { - struct isp_pipeline *pipe = - to_isp_pipeline(ccdc-video_out.video.entity); + struct isp_pipeline *pipe = to_isp_pipeline(ccdc-subdev.entity); struct video_device *vdev = ccdc-subdev.devnode; struct v4l2_event event; -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] More on subdev selections API: composition
Hi Sakari, On 01/29/2012 07:06 PM, Sakari Ailus wrote: The problem with multiple sink pads is that which one you're referring to when you're configuring the first processing step on the source. Without composition there are no issues. What I can think of is to create a special composition target which is not bound to any pad, but reflects the size of the rectangle on which streams may be composed from source pad. Cropping on source pad refers to the coordinates of the composition rectangle. Composition target on sink pad in the original proposal would be renamed as the scaling target. There would I would prefer to stick with CROP and COMPOSE target names on both video and subdev nodes, not to add unnecessary confusion. also be no composition on source pads as it does not make that much sense. To make configuration simple, accessing any unsupported rectangles should return EINVAL. So devices not supporting composition would work as proposed earlier: the compose rectangle would be omitted and the sink crop (if supported) would refer to either scaling or crop targets or even the sink format directly. URL:http://www.retiisi.org.uk/v4l2/tmp/format2.eps Alternatively I think we could as well drop composition support at this point as we have no drivers using it. We still need to plan ahead how it No, that's not true there is no drivers supporting composition. On S5P FIMC I currently use crop on source pad to configure composition rectangle on the output buffers. The drivers forms following pipeline: /dev/subdev? /dev/subdev?/dev/video? ++ ++ +-+ | sensor |oo| scaler |oo| DMA | ++ ++ +-+ pads: S0 SC0 SC1D0 Physically the scaler and DMA are tightly coupled in one platform device, hence SC1 - D0 link is immutable. Format on D0 link is currently always same as configured with VIDIOC_S_FMT on /dev/video?. What is needed here seems just crop on sink pad (SC0) and compose on source pad (SC1). But I'm not so sure about it, given your interpretation and after short (well, not so) discussion with Tomasz. TBH all functionality of the device could be exposed with the scaler subdev removed and VIDIOC_S/G_SELECTION used on /dev/video?. It is getting overly complicated with all the subdevs as above in place and your guys interpretation of the subdev selection. could be supported as the need likely arises at some point. As far as I see the current interface proposal is compatible with composition. Should we discuss this further on #v4l-meeting, I propose Tuesday 2012-01-31 15:00 Finnish time (13:00 GMT). Regards, -- Sylwester Nawrocki Samsung Poland RD Center -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/4] media i.MX27 camera: improve discard buffer handling.
Hi Guennadi, On 27 January 2012 19:02, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: (removing bar...@tkos.co.il - it bounces) On Thu, 26 Jan 2012, javier Martin wrote: Hi Guennadi, On 25 January 2012 13:12, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: On Fri, 20 Jan 2012, Javier Martin wrote: The way discard buffer was previously handled lead to possible races that made a buffer that was not yet ready to be overwritten by new video data. This is easily detected at 25fps just adding #define DEBUG to enable the memset check and seeing how the image is corrupted. A new discard queue and two discard buffers have been added to make them flow trough the pipeline of queues and thus provide suitable event ordering. Hmm, do I understand it right, that the problem is, that while the first frame went to the discard buffer, the second one went already to a user buffer, while it wasn't ready yet? The problem is not only related to the discard buffer but also the way valid buffers were handled in an unsafe basis. For instance, the buf-bufnum = !bufnum issue. If you receive and IRQ from bufnum = 0 you have to update buffer 0, not buffer 1. And you solve this by adding one more discard buffer? Wouldn't it be possible to either not start capture until .start_streaming() is issued, which should also be the case after your patch 2/4, or, at least, just reuse one discard buffer multiple times until user buffers are available? If I understand right, you don't really introduce two discard buffers, there's still only one data buffer, but you add two discard data objects and a list to keep them on. TBH, this seems severely over-engineered to me. What's wrong with just keeping one DMA data buffer and using it as long, as needed, and checking in your ISR, whether a proper buffer is present, by looking for list_empty(active)? I added a couple of comments below, but my biggest question really is - why are these two buffer objects needed? Please, consider getting rid of them. So, this is not a full review, if the objects get removed, most of this patch will change anyway. 1. Why a discard buffer is needed? When I first took a look at the code it only supported CH1 of the PrP (i.e. RGB formats) and a discard buffer was used. My first reaction was trying to get rid of that trick. Both CH1 and CH2 of the PrP have two pointers that the engine uses to write video frames in a ping-pong basis. However, there is a big difference between both channels: if you want to detect frame loss in CH1 you have to continually feed the two pointers with valid memory areas because the engine is always writing and you can't stop it, and this is where the discard buffer function is required, but CH2 has a mechanism to stop capturing and keep counting loss frames, thus a discard buffer wouldn't be needed. To sum up: the driver would be much cleaner without this discard buffer trick but we would have to drop support for CH1 (RGB format). Being respectful to CH1 support I decided to add CH2 by extending the discard buffer strategy to both channels, since the code is cleaner this way and doesn't make sense to manage both channels differently. 2. Why two discard buffer objects are needed? After enabling the DEBUG functionality that writes the buffers with 0xaa before they are filled with video data, I discovered some of them were being corrupted. When I tried to find the reason I found that we really have a pipeline here: --- --- capture (n) | active_bufs (2)| --- where capture has buffers that are queued and ready to be written into active_bufs represents those buffers that are assigned to a pointer in the PrP and has a maximum of 2 since there are two pointers that are written in a ping-pong fashion Ok, I understand what the discard memory is used for and why you need to write it twice to the hardware - to those two pointers. And I can kindof agree, that using them uniformly with user buffers on the active list simplifies handling. I just don't think it's a good idea to keep two struct vb2_buffer instances around with no use. Maybe you could use something like struct mx2_buf_internal { struct list_head queue; int bufnum; bool discard; }; struct mx2_buffer { struct vb2_buffer vb; enum mx2_buffer_state state; struct mx2_buf_internal internal; }; and only use struct mx2_buf_internal for your discard buffers. You are right, the approach you suggest is more efficient. What I purpose is that you accept my following v3 patch series and allow me to send a further cleanup series with the following changes: 1. Remove goto out from mx2_videobuf_queue. 2. Use
Re: [PATCH v2 3/4] media i.MX27 camera: improve discard buffer handling.
On 27 January 2012 19:13, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: On Thu, 26 Jan 2012, Javier Martin wrote: The way discard buffer was previously handled lead to possible races that made a buffer that was not yet ready to be overwritten by new video data. This is easily detected at 25fps just adding #define DEBUG to enable the memset check and seeing how the image is corrupted. A new discard queue and two discard buffers have been added to make them flow trough the pipeline of queues and thus provide suitable event ordering. Signed-off-by: Javier Martin javier.mar...@vista-silicon.com --- Changes since v1: - Don't allocate discard buffer on every set_fmt. --- drivers/media/video/mx2_camera.c | 261 +- 1 files changed, 144 insertions(+), 117 deletions(-) diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 045c018..71054ab 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -237,7 +237,8 @@ struct mx2_buffer { struct list_head queue; enum mx2_buffer_state state; - int bufnum; + int bufnum; + bool discard; }; struct mx2_camera_dev { @@ -256,6 +257,7 @@ struct mx2_camera_dev { struct list_head capture; struct list_head active_bufs; + struct list_head discard; spinlock_t lock; @@ -268,6 +270,7 @@ struct mx2_camera_dev { u32 csicr1; + struct mx2_buffer buf_discard[2]; void *discard_buffer; dma_addr_t discard_buffer_dma; size_t discard_size; @@ -329,6 +332,30 @@ static struct mx2_fmt_cfg *mx27_emma_prp_get_format( return mx27_emma_prp_table[0]; }; +static void mx27_update_emma_buf(struct mx2_camera_dev *pcdev, + unsigned long phys, int bufnum) +{ + struct mx2_fmt_cfg *prp = pcdev-emma_prp; + + if (prp-cfg.channel == 1) { + writel(phys, pcdev-base_emma + + PRP_DEST_RGB1_PTR + 4 * bufnum); + } else { + writel(phys, pcdev-base_emma + + PRP_DEST_Y_PTR - 0x14 * bufnum); + if (prp-out_fmt == V4L2_PIX_FMT_YUV420) { + u32 imgsize = pcdev-icd-user_height * + pcdev-icd-user_width; + + writel(phys + imgsize, + pcdev-base_emma + PRP_DEST_CB_PTR - + 0x14 * bufnum); + writel(phys + ((5 * imgsize) / 4), pcdev-base_emma + + PRP_DEST_CR_PTR - 0x14 * bufnum); Please fix indentation. OK, will do in v3. + } + } +} + static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev) { unsigned long flags; @@ -377,7 +404,7 @@ static int mx2_camera_add_device(struct soc_camera_device *icd) writel(pcdev-csicr1, pcdev-base_csi + CSICR1); pcdev-icd = icd; - pcdev-frame_count = -1; + pcdev-frame_count = 0; dev_info(icd-parent, Camera driver attached to camera %d\n, icd-devnum); @@ -631,7 +658,7 @@ static void mx2_videobuf_release(struct vb2_buffer *vb) spin_lock_irqsave(pcdev-lock, flags); if (mx27_camera_emma(pcdev)) { - list_del_init(buf-queue); + INIT_LIST_HEAD(buf-queue); The buffer had to be deleted from the queue to clean up the queue. The _init was actually not needed. Now, that you do INIT_LIST_HEAD(pcdev-capture); and INIT_LIST_HEAD(pcdev-active_bufs); in .stop_streaming(), you don't need to do anything about your individual buffers. You never test list_empty(buf-queue), so, it doesn't matter what they contain. Fine, v3 will solve this. } else if (cpu_is_mx25() buf-state == MX2_STATE_ACTIVE) { if (pcdev-fb1_active == buf) { pcdev-csicr1 = ~CSICR1_FB1_DMA_INTEN; @@ -647,6 +674,34 @@ static void mx2_videobuf_release(struct vb2_buffer *vb) spin_unlock_irqrestore(pcdev-lock, flags); } +static void mx27_camera_emma_buf_init(struct soc_camera_device *icd, + int bytesperline) +{ + struct soc_camera_host *ici = + to_soc_camera_host(icd-parent); + struct mx2_camera_dev *pcdev = ici-priv; + struct mx2_fmt_cfg *prp = pcdev-emma_prp; + + writel((icd-user_width 16) | icd-user_height, + pcdev-base_emma + PRP_SRC_FRAME_SIZE); + writel(prp-cfg.src_pixel, + pcdev-base_emma + PRP_SRC_PIXEL_FORMAT_CNTL); + if (prp-cfg.channel == 1) { + writel((icd-user_width 16) | icd-user_height, + pcdev-base_emma + PRP_CH1_OUT_IMAGE_SIZE); + writel(bytesperline, + pcdev-base_emma +
Re: [PATCH v2 4/4] media i.MX27 camera: handle overflows properly.
On 27 January 2012 19:16, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote: (removed bar...@tkos.co.il - it bounces) On Thu, 26 Jan 2012, Javier Martin wrote: Signed-off-by: Javier Martin javier.mar...@vista-silicon.com --- Changes since v1: - Make ifs in irq callback mutually exclusive. - Add new argument to mx27_camera_frame_done_emma() to handle errors. --- drivers/media/video/mx2_camera.c | 38 -- 1 files changed, 16 insertions(+), 22 deletions(-) diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 71054ab..1759673 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -1213,7 +1213,7 @@ static struct soc_camera_host_ops mx2_soc_camera_host_ops = { }; static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, - int bufnum) + int bufnum, bool err) { struct mx2_buffer *buf; struct vb2_buffer *vb; @@ -1262,7 +1262,10 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, list_del_init(buf-queue); do_gettimeofday(vb-v4l2_buf.timestamp); vb-v4l2_buf.sequence = pcdev-frame_count; - vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + if (err) + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); + else + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); } pcdev-frame_count++; @@ -1297,21 +1300,12 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) struct mx2_buffer *buf; if (status (1 7)) { /* overflow */ - u32 cntl; - /* - * We only disable channel 1 here since this is the only - * enabled channel - * - * FIXME: the correct DMA overflow handling should be resetting - * the buffer, returning an error frame, and continuing with - * the next one. - */ - cntl = readl(pcdev-base_emma + PRP_CNTL); - writel(cntl ~(PRP_CNTL_CH1EN | PRP_CNTL_CH2EN), - pcdev-base_emma + PRP_CNTL); - writel(cntl, pcdev-base_emma + PRP_CNTL); - } - if status (3 5)) == (3 5)) || + buf = list_entry(pcdev-active_bufs.next, + struct mx2_buffer, queue); + mx27_camera_frame_done_emma(pcdev, + buf-bufnum, 1); use true for bool variables. + status = ~(1 7); + } else if status (3 5)) == (3 5)) || ((status (3 3)) == (3 3))) !list_empty(pcdev-active_bufs)) { /* @@ -1320,13 +1314,13 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) */ buf = list_entry(pcdev-active_bufs.next, struct mx2_buffer, queue); - mx27_camera_frame_done_emma(pcdev, buf-bufnum); + mx27_camera_frame_done_emma(pcdev, buf-bufnum, 0); false status = ~(1 (6 - buf-bufnum)); /* mark processed */ + } else if ((status (1 6)) || (status (1 4))) { + mx27_camera_frame_done_emma(pcdev, 0, 0); false + } else if ((status (1 5)) || (status (1 3))) { + mx27_camera_frame_done_emma(pcdev, 1, 0); false } - if ((status (1 6)) || (status (1 4))) - mx27_camera_frame_done_emma(pcdev, 0); - if ((status (1 5)) || (status (1 3))) - mx27_camera_frame_done_emma(pcdev, 1); writel(status, pcdev-base_emma + PRP_INTRSTATUS); Don't worry, this will be fixed in v3. -- Javier Martin Vista Silicon S.L. CDTUC - FASE C - Oficina S-345 Avda de los Castros s/n 39005- Santander. Cantabria. Spain +34 942 25 32 60 www.vista-silicon.com -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 06/15] mm: page_alloc: introduce alloc_contig_range()
On Thu, Jan 26, 2012 at 10:00:48AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com This commit adds the alloc_contig_range() function which tries to allocate given range of pages. It tries to migrate all already allocated pages that fall in the range thus freeing them. Once all pages in the range are freed they are removed from the buddy system thus allocated for the caller to use. Signed-off-by: Michal Nazarewicz min...@mina86.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com --- include/linux/page-isolation.h |7 ++ mm/page_alloc.c| 183 2 files changed, 190 insertions(+), 0 deletions(-) diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h index 8c02c2b..430cf61 100644 --- a/include/linux/page-isolation.h +++ b/include/linux/page-isolation.h @@ -39,5 +39,12 @@ extern void update_pcp_isolate_block(unsigned long pfn); extern int set_migratetype_isolate(struct page *page); extern void unset_migratetype_isolate(struct page *page); +#ifdef CONFIG_CMA + +/* The below functions must be run on a range from a single zone. */ +extern int alloc_contig_range(unsigned long start, unsigned long end); +extern void free_contig_range(unsigned long pfn, unsigned nr_pages); + +#endif Did you really mean page-isolation.h? I would have thought gfp.h would be a more suitable fit. #endif diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 70709e7..b4f50532 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -57,6 +57,7 @@ #include linux/ftrace_event.h #include linux/memcontrol.h #include linux/prefetch.h +#include linux/migrate.h #include linux/page-debug-flags.h #include asm/tlbflush.h @@ -5488,6 +5489,188 @@ out: spin_unlock_irqrestore(zone-lock, flags); } +#ifdef CONFIG_CMA + +static unsigned long pfn_align_to_maxpage_down(unsigned long pfn) +{ + return pfn ~(MAX_ORDER_NR_PAGES - 1); +} + +static unsigned long pfn_align_to_maxpage_up(unsigned long pfn) +{ + return ALIGN(pfn, MAX_ORDER_NR_PAGES); +} + +static struct page * +__alloc_contig_migrate_alloc(struct page *page, unsigned long private, + int **resultp) +{ + return alloc_page(GFP_HIGHUSER_MOVABLE); +} + +/* [start, end) must belong to a single zone. */ +static int __alloc_contig_migrate_range(unsigned long start, unsigned long end) +{ + /* This function is based on compact_zone() from compaction.c. */ + + unsigned long pfn = start; + unsigned int tries = 0; + int ret = 0; + + struct compact_control cc = { + .nr_migratepages = 0, + .order = -1, + .zone = page_zone(pfn_to_page(start)), + .sync = true, + }; + INIT_LIST_HEAD(cc.migratepages); + + migrate_prep_local(); + + while (pfn end || !list_empty(cc.migratepages)) { + if (fatal_signal_pending(current)) { + ret = -EINTR; + break; + } + + if (list_empty(cc.migratepages)) { + cc.nr_migratepages = 0; + pfn = isolate_migratepages_range(cc.zone, cc, + pfn, end); + if (!pfn) { + ret = -EINTR; + break; + } + tries = 0; + } else if (++tries == 5) { + ret = ret 0 ? ret : -EBUSY; + break; + } + + ret = migrate_pages(cc.migratepages, + __alloc_contig_migrate_alloc, + 0, false, true); + } + + putback_lru_pages(cc.migratepages); + return ret; +} + +/** + * alloc_contig_range() -- tries to allocate given range of pages + * @start: start PFN to allocate + * @end: one-past-the-last PFN to allocate + * + * The PFN range does not have to be pageblock or MAX_ORDER_NR_PAGES + * aligned, however it's the caller's responsibility to guarantee that + * we are the only thread that changes migrate type of pageblocks the + * pages fall in. + * + * The PFN range must belong to a single zone. + * + * Returns zero on success or negative error code. On success all + * pages which PFN is in [start, end) are allocated for the caller and + * need to be freed with free_contig_range(). + */ +int alloc_contig_range(unsigned long start, unsigned long end) +{ + unsigned long outer_start, outer_end; + int ret = 0, order; + + /* + * What we do here is we mark all pageblocks in range as + * MIGRATE_ISOLATE. Because of the way page allocator work, we + * align the range to MAX_ORDER pages so that page allocator + * won't try to merge buddies from different pageblocks and +
Re: [PATCH][media] s5p-g2d: Add HFLIP and VFLIP support
Hi Sashin, Thanks for the patch. On Monday 30 January 2012 10:58:43 Sachin Kamat wrote: This patch adds support for flipping the image horizontally and vertically. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org --- drivers/media/video/s5p-g2d/g2d-hw.c |5 +++ drivers/media/video/s5p-g2d/g2d.c| 47 +-- drivers/media/video/s5p-g2d/g2d.h|3 ++ 3 files changed, 46 insertions(+), 9 deletions(-) [snip] diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c index febaa67..dea9701 100644 --- a/drivers/media/video/s5p-g2d/g2d.c +++ b/drivers/media/video/s5p-g2d/g2d.c @@ -178,6 +178,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) { struct g2d_ctx *ctx = container_of(ctrl-handler, struct g2d_ctx, ctrl_handler); + switch (ctrl-id) { case V4L2_CID_COLORFX: if (ctrl-val == V4L2_COLORFX_NEGATIVE) @@ -185,6 +186,21 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) else ctx-rop = ROP4_COPY; break; + + case V4L2_CID_HFLIP: + if (ctrl-val == 1) + ctx-hflip = 1; + else + ctx-hflip = 0; + break; + + case V4L2_CID_VFLIP: + if (ctrl-val == 1) + ctx-vflip = (1 1); + else + ctx-vflip = 0; + break; + default: v4l2_err(ctx-dev-v4l2_dev, unknown control\n); return -EINVAL; @@ -200,11 +216,9 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx) { struct g2d_dev *dev = ctx-dev; - v4l2_ctrl_handler_init(ctx-ctrl_handler, 1); - if (ctx-ctrl_handler.error) { - v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); - return ctx-ctrl_handler.error; - } + v4l2_ctrl_handler_init(ctx-ctrl_handler, 3); + if (ctx-ctrl_handler.error) + goto error; There's not need to verify ctx-ctrl_handler.error after every call to v4l2_ctrl_handler_init() or v4l2_ctrl_new_*(). You can verify it once only after initialization all controls. v4l2_ctrl_new_std_menu( ctx-ctrl_handler, @@ -214,12 +228,25 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx) ~((1 V4L2_COLORFX_NONE) | (1 V4L2_COLORFX_NEGATIVE)), V4L2_COLORFX_NONE); - if (ctx-ctrl_handler.error) { - v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); - return ctx-ctrl_handler.error; - } + if (ctx-ctrl_handler.error) + goto error; + + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + if (ctx-ctrl_handler.error) + goto error; + + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); As a single register controls hflip and vflip, you should group the two controls in a cluster. + if (ctx-ctrl_handler.error) + goto error; return 0; + +error: + v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); + return ctx-ctrl_handler.error; + } static int g2d_open(struct file *file) @@ -564,6 +591,8 @@ static void device_run(void *prv) g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); g2d_set_rop4(dev, ctx-rop); + g2d_set_flip(dev, ctx-hflip | ctx-vflip); + Is this called for every frame, or once at stream start only ? In the later case, this means that hflip and vflip won't be changeable during streaming. Is that on purpose ? if (ctx-in.c_width != ctx-out.c_width || ctx-in.c_height != ctx-out.c_height) cmd |= g2d_cmd_stretch(1); diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/video/s5p-g2d/g2d.h index 5eae901..b3be3c8 100644 --- a/drivers/media/video/s5p-g2d/g2d.h +++ b/drivers/media/video/s5p-g2d/g2d.h @@ -59,6 +59,8 @@ struct g2d_ctx { struct g2d_frameout; struct v4l2_ctrl_handler ctrl_handler; u32 rop; + u32 hflip; + u32 vflip; }; struct g2d_fmt { @@ -77,6 +79,7 @@ void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a); void g2d_start(struct g2d_dev *d); void g2d_clear_int(struct g2d_dev *d); void g2d_set_rop4(struct g2d_dev *d, u32 r); +void g2d_set_flip(struct g2d_dev *d, u32 r); u32 g2d_cmd_stretch(u32 e); void g2d_set_cmd(struct g2d_dev *d, u32 c); -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 07/15] mm: page_alloc: change fallbacks array handling
On Thu, Jan 26, 2012 at 10:00:49AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com This commit adds a row for MIGRATE_ISOLATE type to the fallbacks array which was missing from it. It also, changes the array traversal logic a little making MIGRATE_RESERVE an end marker. The letter change, removes the implicit MIGRATE_UNMOVABLE from the end of each row which was read by __rmqueue_fallback() function. Signed-off-by: Michal Nazarewicz min...@mina86.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Acked-by: Mel Gorman m...@csn.ul.ie -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/4] media i.MX27 camera: migrate driver to videobuf2
Signed-off-by: Javier Martin javier.mar...@vista-silicon.com --- Changes since v2: - Return ENOTTY for VIDIOC_CREATE_BUFS - Check buffer size properly. - Do not remove unfixed FIXME. - Remove mx25 queued buffers from the queue list at release. --- drivers/media/video/mx2_camera.c | 289 +- 1 files changed, 127 insertions(+), 162 deletions(-) diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index ca76dd2..ae7cae6 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -3,6 +3,7 @@ * * Copyright (C) 2008, Sascha Hauer, Pengutronix * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography + * Copyright (C) 2012, Javier Martin, Vista Silicon S.L. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,8 +31,8 @@ #include media/v4l2-common.h #include media/v4l2-dev.h -#include media/videobuf-core.h -#include media/videobuf-dma-contig.h +#include media/videobuf2-core.h +#include media/videobuf2-dma-contig.h #include media/soc_camera.h #include media/soc_mediabus.h @@ -223,6 +224,22 @@ struct mx2_fmt_cfg { struct mx2_prp_cfg cfg; }; +enum mx2_buffer_state { + MX2_STATE_QUEUED, + MX2_STATE_ACTIVE, + MX2_STATE_DONE, +}; + +/* buffer for one video frame */ +struct mx2_buffer { + /* common v4l buffer stuff -- must be first */ + struct vb2_buffer vb; + struct list_headqueue; + enum mx2_buffer_state state; + + int bufnum; +}; + struct mx2_camera_dev { struct device *dev; struct soc_camera_host soc_host; @@ -256,16 +273,7 @@ struct mx2_camera_dev { size_t discard_size; struct mx2_fmt_cfg *emma_prp; u32 frame_count; -}; - -/* buffer for one video frame */ -struct mx2_buffer { - /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - - enum v4l2_mbus_pixelcodecode; - - int bufnum; + struct vb2_alloc_ctx*alloc_ctx; }; static struct mx2_fmt_cfg mx27_emma_prp_table[] = { @@ -407,7 +415,7 @@ static irqreturn_t mx27_camera_irq(int irq_csi, void *data) static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, int state) { - struct videobuf_buffer *vb; + struct vb2_buffer *vb; struct mx2_buffer *buf; struct mx2_buffer **fb_active = fb == 1 ? pcdev-fb1_active : pcdev-fb2_active; @@ -420,25 +428,24 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, goto out; vb = (*fb_active)-vb; - dev_dbg(pcdev-dev, %s (vb=0x%p) 0x%08lx %d\n, __func__, - vb, vb-baddr, vb-bsize); + dev_dbg(pcdev-dev, %s (vb=0x%p) 0x%p %lu\n, __func__, + vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); - vb-state = state; - do_gettimeofday(vb-ts); - vb-field_count++; - - wake_up(vb-done); + do_gettimeofday(vb-v4l2_buf.timestamp); + vb-v4l2_buf.sequence++; + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); if (list_empty(pcdev-capture)) { buf = NULL; writel(0, pcdev-base_csi + fb_reg); } else { buf = list_entry(pcdev-capture.next, struct mx2_buffer, - vb.queue); + queue); vb = buf-vb; - list_del(vb-queue); - vb-state = VIDEOBUF_ACTIVE; - writel(videobuf_to_dma_contig(vb), pcdev-base_csi + fb_reg); + list_del(buf-queue); + buf-state = MX2_STATE_ACTIVE; + writel(vb2_dma_contig_plane_dma_addr(vb, 0), + pcdev-base_csi + fb_reg); } *fb_active = buf; @@ -453,9 +460,9 @@ static irqreturn_t mx25_camera_irq(int irq_csi, void *data) u32 status = readl(pcdev-base_csi + CSISR); if (status CSISR_DMA_TSF_FB1_INT) - mx25_camera_frame_done(pcdev, 1, VIDEOBUF_DONE); + mx25_camera_frame_done(pcdev, 1, MX2_STATE_DONE); else if (status CSISR_DMA_TSF_FB2_INT) - mx25_camera_frame_done(pcdev, 2, VIDEOBUF_DONE); + mx25_camera_frame_done(pcdev, 2, MX2_STATE_DONE); /* FIXME: handle CSISR_RFF_OR_INT */ @@ -467,59 +474,50 @@ static irqreturn_t mx25_camera_irq(int irq_csi, void *data) /* * Videobuf operations */ -static int mx2_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, - unsigned int *size) +static int mx2_videobuf_setup(struct vb2_queue *vq, + const struct v4l2_format *fmt, + unsigned int *count, unsigned int *num_planes, +
[PATCH v3 2/4] media i.MX27 camera: add start_stream and stop_stream callbacks.
Add start_stream and stop_stream callback in order to enable and disable the eMMa-PrP properly and save CPU usage avoiding IRQs when the device is not streaming. This also makes the driver return 0 as the sequence number of the first frame. Signed-off-by: Javier Martin javier.mar...@vista-silicon.com --- - Make start_streaming cleaner. --- drivers/media/video/mx2_camera.c | 100 - 1 files changed, 75 insertions(+), 25 deletions(-) diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index ae7cae6..35ab971 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -377,7 +377,7 @@ static int mx2_camera_add_device(struct soc_camera_device *icd) writel(pcdev-csicr1, pcdev-base_csi + CSICR1); pcdev-icd = icd; - pcdev-frame_count = 0; + pcdev-frame_count = -1; dev_info(icd-parent, Camera driver attached to camera %d\n, icd-devnum); @@ -656,11 +656,79 @@ static void mx2_videobuf_release(struct vb2_buffer *vb) spin_unlock_irqrestore(pcdev-lock, flags); } +static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct soc_camera_device *icd = soc_camera_from_vb2q(q); + struct soc_camera_host *ici = + to_soc_camera_host(icd-parent); + struct mx2_camera_dev *pcdev = ici-priv; + struct mx2_fmt_cfg *prp = pcdev-emma_prp; + + if (mx27_camera_emma(pcdev)) { + unsigned long flags; + if (count 2) + return -EINVAL; + + spin_lock_irqsave(pcdev-lock, flags); + if (prp-cfg.channel == 1) { + writel(PRP_CNTL_CH1EN | + PRP_CNTL_CSIEN | + prp-cfg.in_fmt | + prp-cfg.out_fmt | + PRP_CNTL_CH1_LEN | + PRP_CNTL_CH1BYP | + PRP_CNTL_CH1_TSKIP(0) | + PRP_CNTL_IN_TSKIP(0), + pcdev-base_emma + PRP_CNTL); + } else { + writel(PRP_CNTL_CH2EN | + PRP_CNTL_CSIEN | + prp-cfg.in_fmt | + prp-cfg.out_fmt | + PRP_CNTL_CH2_LEN | + PRP_CNTL_CH2_TSKIP(0) | + PRP_CNTL_IN_TSKIP(0), + pcdev-base_emma + PRP_CNTL); + } + spin_unlock_irqrestore(pcdev-lock, flags); + } + + return 0; +} + +static int mx2_stop_streaming(struct vb2_queue *q) +{ + struct soc_camera_device *icd = soc_camera_from_vb2q(q); + struct soc_camera_host *ici = + to_soc_camera_host(icd-parent); + struct mx2_camera_dev *pcdev = ici-priv; + struct mx2_fmt_cfg *prp = pcdev-emma_prp; + unsigned long flags; + u32 cntl; + + spin_lock_irqsave(pcdev-lock, flags); + if (mx27_camera_emma(pcdev)) { + cntl = readl(pcdev-base_emma + PRP_CNTL); + if (prp-cfg.channel == 1) { + writel(cntl ~PRP_CNTL_CH1EN, + pcdev-base_emma + PRP_CNTL); + } else { + writel(cntl ~PRP_CNTL_CH2EN, + pcdev-base_emma + PRP_CNTL); + } + } + spin_unlock_irqrestore(pcdev-lock, flags); + + return 0; +} + static struct vb2_ops mx2_videobuf_ops = { - .queue_setup= mx2_videobuf_setup, - .buf_prepare= mx2_videobuf_prepare, - .buf_queue = mx2_videobuf_queue, - .buf_cleanup= mx2_videobuf_release, + .queue_setup = mx2_videobuf_setup, + .buf_prepare = mx2_videobuf_prepare, + .buf_queue = mx2_videobuf_queue, + .buf_cleanup = mx2_videobuf_release, + .start_streaming = mx2_start_streaming, + .stop_streaming = mx2_stop_streaming, }; static int mx2_camera_init_videobuf(struct vb2_queue *q, @@ -718,16 +786,6 @@ static void mx27_camera_emma_buf_init(struct soc_camera_device *icd, writel(pcdev-discard_buffer_dma, pcdev-base_emma + PRP_DEST_RGB2_PTR); - writel(PRP_CNTL_CH1EN | - PRP_CNTL_CSIEN | - prp-cfg.in_fmt | - prp-cfg.out_fmt | - PRP_CNTL_CH1_LEN | - PRP_CNTL_CH1BYP | - PRP_CNTL_CH1_TSKIP(0) | - PRP_CNTL_IN_TSKIP(0), - pcdev-base_emma + PRP_CNTL); - writel((icd-user_width 16) | icd-user_height, pcdev-base_emma +
[PATCH v3 3/4] media i.MX27 camera: improve discard buffer handling.
The way discard buffer was previously handled lead to possible races that made a buffer that was not yet ready to be overwritten by new video data. This is easily detected at 25fps just adding #define DEBUG to enable the memset check and seeing how the image is corrupted. A new discard queue and two discard buffers have been added to make them flow trough the pipeline of queues and thus provide suitable event ordering. Signed-off-by: Javier Martin javier.mar...@vista-silicon.com --- Changes since v2: - Remove BUG_ON when active list is empty. - Replace empty list checks with warnings. --- drivers/media/video/mx2_camera.c | 280 +- 1 files changed, 153 insertions(+), 127 deletions(-) diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 35ab971..e7ccd97 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -237,7 +237,8 @@ struct mx2_buffer { struct list_headqueue; enum mx2_buffer_state state; - int bufnum; + int bufnum; + booldiscard; }; struct mx2_camera_dev { @@ -256,6 +257,7 @@ struct mx2_camera_dev { struct list_headcapture; struct list_headactive_bufs; + struct list_headdiscard; spinlock_t lock; @@ -268,6 +270,7 @@ struct mx2_camera_dev { u32 csicr1; + struct mx2_buffer buf_discard[2]; void*discard_buffer; dma_addr_t discard_buffer_dma; size_t discard_size; @@ -329,6 +332,29 @@ static struct mx2_fmt_cfg *mx27_emma_prp_get_format( return mx27_emma_prp_table[0]; }; +static void mx27_update_emma_buf(struct mx2_camera_dev *pcdev, +unsigned long phys, int bufnum) +{ + struct mx2_fmt_cfg *prp = pcdev-emma_prp; + + if (prp-cfg.channel == 1) { + writel(phys, pcdev-base_emma + + PRP_DEST_RGB1_PTR + 4 * bufnum); + } else { + writel(phys, pcdev-base_emma + + PRP_DEST_Y_PTR - 0x14 * bufnum); + if (prp-out_fmt == V4L2_PIX_FMT_YUV420) { + u32 imgsize = pcdev-icd-user_height * + pcdev-icd-user_width; + + writel(phys + imgsize, pcdev-base_emma + + PRP_DEST_CB_PTR - 0x14 * bufnum); + writel(phys + ((5 * imgsize) / 4), pcdev-base_emma + + PRP_DEST_CR_PTR - 0x14 * bufnum); + } + } +} + static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev) { unsigned long flags; @@ -377,7 +403,7 @@ static int mx2_camera_add_device(struct soc_camera_device *icd) writel(pcdev-csicr1, pcdev-base_csi + CSICR1); pcdev-icd = icd; - pcdev-frame_count = -1; + pcdev-frame_count = 0; dev_info(icd-parent, Camera driver attached to camera %d\n, icd-devnum); @@ -397,13 +423,6 @@ static void mx2_camera_remove_device(struct soc_camera_device *icd) mx2_camera_deactivate(pcdev); - if (pcdev-discard_buffer) { - dma_free_coherent(ici-v4l2_dev.dev, pcdev-discard_size, - pcdev-discard_buffer, - pcdev-discard_buffer_dma); - pcdev-discard_buffer = NULL; - } - pcdev-icd = NULL; } @@ -640,7 +659,6 @@ static void mx2_videobuf_release(struct vb2_buffer *vb) */ spin_lock_irqsave(pcdev-lock, flags); - list_del_init(buf-queue); if (cpu_is_mx25() buf-state == MX2_STATE_ACTIVE) { if (pcdev-fb1_active == buf) { pcdev-csicr1 = ~CSICR1_FB1_DMA_INTEN; @@ -656,6 +674,34 @@ static void mx2_videobuf_release(struct vb2_buffer *vb) spin_unlock_irqrestore(pcdev-lock, flags); } +static void mx27_camera_emma_buf_init(struct soc_camera_device *icd, + int bytesperline) +{ + struct soc_camera_host *ici = + to_soc_camera_host(icd-parent); + struct mx2_camera_dev *pcdev = ici-priv; + struct mx2_fmt_cfg *prp = pcdev-emma_prp; + + writel((icd-user_width 16) | icd-user_height, + pcdev-base_emma + PRP_SRC_FRAME_SIZE); + writel(prp-cfg.src_pixel, + pcdev-base_emma + PRP_SRC_PIXEL_FORMAT_CNTL); + if (prp-cfg.channel == 1) { + writel((icd-user_width 16) | icd-user_height, + pcdev-base_emma + PRP_CH1_OUT_IMAGE_SIZE); + writel(bytesperline, + pcdev-base_emma + PRP_DEST_CH1_LINE_STRIDE); + writel(prp-cfg.ch1_pixel, + pcdev-base_emma + PRP_CH1_PIXEL_FORMAT_CNTL); +
[PATCH v3 4/4] media i.MX27 camera: handle overflows properly.
Signed-off-by: Javier Martin javier.mar...@vista-silicon.com --- Changes since v2: - Use true and false for bool variables. --- drivers/media/video/mx2_camera.c | 38 -- 1 files changed, 16 insertions(+), 22 deletions(-) diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index e7ccd97..09bcfe0 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -1210,7 +1210,7 @@ static struct soc_camera_host_ops mx2_soc_camera_host_ops = { }; static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, - int bufnum) + int bufnum, bool err) { struct mx2_fmt_cfg *prp = pcdev-emma_prp; struct mx2_buffer *buf; @@ -1258,7 +1258,10 @@ static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev, list_del_init(buf-queue); do_gettimeofday(vb-v4l2_buf.timestamp); vb-v4l2_buf.sequence = pcdev-frame_count; - vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + if (err) + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); + else + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); } pcdev-frame_count++; @@ -1302,21 +1305,12 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) __func__); if (status (1 7)) { /* overflow */ - u32 cntl; - /* -* We only disable channel 1 here since this is the only -* enabled channel -* -* FIXME: the correct DMA overflow handling should be resetting -* the buffer, returning an error frame, and continuing with -* the next one. -*/ - cntl = readl(pcdev-base_emma + PRP_CNTL); - writel(cntl ~(PRP_CNTL_CH1EN | PRP_CNTL_CH2EN), - pcdev-base_emma + PRP_CNTL); - writel(cntl, pcdev-base_emma + PRP_CNTL); - } - if (((status (3 5)) == (3 5)) || + buf = list_entry(pcdev-active_bufs.next, + struct mx2_buffer, queue); + mx27_camera_frame_done_emma(pcdev, + buf-bufnum, true); + status = ~(1 7); + } else if (((status (3 5)) == (3 5)) || ((status (3 3)) == (3 3))) { /* * Both buffers have triggered, process the one we're expecting @@ -1324,13 +1318,13 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data) */ buf = list_entry(pcdev-active_bufs.next, struct mx2_buffer, queue); - mx27_camera_frame_done_emma(pcdev, buf-bufnum); + mx27_camera_frame_done_emma(pcdev, buf-bufnum, false); status = ~(1 (6 - buf-bufnum)); /* mark processed */ + } else if ((status (1 6)) || (status (1 4))) { + mx27_camera_frame_done_emma(pcdev, 0, false); + } else if ((status (1 5)) || (status (1 3))) { + mx27_camera_frame_done_emma(pcdev, 1, false); } - if ((status (1 6)) || (status (1 4))) - mx27_camera_frame_done_emma(pcdev, 0); - if ((status (1 5)) || (status (1 3))) - mx27_camera_frame_done_emma(pcdev, 1); writel(status, pcdev-base_emma + PRP_INTRSTATUS); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] omap3isp: Prevent pipelines that contain a crashed entity from starting
The OMAP3 ISP preview engine will violate the L4 bus protocol if we try to write some of its internal registers after it failed to stop properly. This generates an external abort on non-linefetch fault, triggering a fatal kernel oops. We can't always prevent preview engine stop failures (they can for instance be caused by a sensor crash), but we can improve the system reliability by refusing to start streaming on a pipeline that contains the preview engine if it failed to stop. The driver will then eventually reset the ISP (when all applications will have closed their file handles related to OMAP3 ISP device nodes), making the ISP usable again. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Acked-by: Sakari Ailus sakari.ai...@iki.fi --- drivers/media/video/omap3isp/isp.c | 27 +-- drivers/media/video/omap3isp/isp.h |3 ++- drivers/media/video/omap3isp/ispvideo.c |4 drivers/media/video/omap3isp/ispvideo.h |2 ++ 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index 12d5f92..3db8583 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c @@ -739,6 +739,17 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe, unsigned long flags; int ret; + /* If the preview engine crashed it might not respond to read/write +* operations on the L4 bus. This would result in a bus fault and a +* kernel oops. Refuse to start streaming in that case. This check must +* be performed before the loop below to avoid starting entities if the +* pipeline won't start anyway (those entities would then likely fail to +* stop, making the problem worse). +*/ + if ((pipe-entities isp-crashed) + (1U isp-isp_prev.subdev.entity.id)) + return -EIO; + spin_lock_irqsave(pipe-lock, flags); pipe-state = ~(ISP_PIPELINE_IDLE_INPUT | ISP_PIPELINE_IDLE_OUTPUT); spin_unlock_irqrestore(pipe-lock, flags); @@ -879,13 +890,15 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) if (ret) { dev_info(isp-dev, Unable to stop %s\n, subdev-name); + /* If the entity failed to stopped, assume it has +* crashed. Mark it as such, the ISP will be reset when +* applications will release it. +*/ + isp-crashed |= 1U subdev-entity.id; failure = -ETIMEDOUT; } } - if (failure 0) - isp-needs_reset = true; - return failure; } @@ -1069,6 +1082,7 @@ static int isp_reset(struct isp_device *isp) udelay(1); } + isp-crashed = 0; return 0; } @@ -1496,10 +1510,11 @@ void omap3isp_put(struct isp_device *isp) if (--isp-ref_count == 0) { isp_disable_interrupts(isp); isp_save_ctx(isp); - if (isp-needs_reset) { + /* Reset the ISP if an entity has failed to stop. This is the +* only way to recover from such conditions. +*/ + if (isp-crashed) isp_reset(isp); - isp-needs_reset = false; - } isp_disable_clocks(isp); } mutex_unlock(isp-isp_mutex); diff --git a/drivers/media/video/omap3isp/isp.h b/drivers/media/video/omap3isp/isp.h index d96603e..f8d1f10 100644 --- a/drivers/media/video/omap3isp/isp.h +++ b/drivers/media/video/omap3isp/isp.h @@ -145,6 +145,7 @@ struct isp_platform_callback { * @raw_dmamask: Raw DMA mask * @stat_lock: Spinlock for handling statistics * @isp_mutex: Mutex for serializing requests to ISP. + * @crashed: Bitmask of crashed entities (indexed by entity ID) * @has_context: Context has been saved at least once and can be restored. * @ref_count: Reference count for handling multiple ISP requests. * @cam_ick: Pointer to camera interface clock structure. @@ -184,7 +185,7 @@ struct isp_device { /* ISP Obj */ spinlock_t stat_lock; /* common lock for statistic drivers */ struct mutex isp_mutex; /* For handling ref_count field */ - bool needs_reset; + u32 crashed; int has_context; int ref_count; unsigned int autoidle; diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c index b020700..2107d99 100644 --- a/drivers/media/video/omap3isp/ispvideo.c +++ b/drivers/media/video/omap3isp/ispvideo.c @@ -292,6 +292,7 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) int ret; pipe-max_rate = pipe-l3_ick; + pipe-entities = 0; subdev = isp_video_remote_subdev(pipe-output, NULL); if (subdev == NULL)
[PATCH] mt9p031: Remove unused xskip and yskip fields in struct mt9p031
The fields are set but never used, remove them. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/media/video/mt9p031.c |4 1 files changed, 0 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c index 93c3ec7..0bdddbb 100644 --- a/drivers/media/video/mt9p031.c +++ b/drivers/media/video/mt9p031.c @@ -115,8 +115,6 @@ struct mt9p031 { struct mt9p031_platform_data *pdata; struct mutex power_lock; /* lock to protect power_count */ int power_count; - u16 xskip; - u16 yskip; const struct mt9p031_pll_divs *pll; @@ -785,8 +783,6 @@ static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) format-field = V4L2_FIELD_NONE; format-colorspace = V4L2_COLORSPACE_SRGB; - mt9p031-xskip = 1; - mt9p031-yskip = 1; return mt9p031_set_power(subdev, 1); } -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 05/15] mm: compaction: export some of the functions
On Thu, Jan 26, 2012 at 10:00:47AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com --- a/mm/compaction.c +++ b/mm/compaction.c @@ -16,30 +16,11 @@ #include linux/sysfs.h #include internal.h +#if defined CONFIG_COMPACTION || defined CONFIG_CMA + On Mon, 30 Jan 2012 12:57:26 +0100, Mel Gorman m...@csn.ul.ie wrote: This is pedantic but you reference CONFIG_CMA before the patch that declares it. The only time this really matters is when it breaks bisection but I do not think that is the case here. I think I'll choose to be lazy on this one. ;) I actually tried to move some commits around to resolve this future-reference, but this resulted in quite a few conflicts during rebase and after several minutes I decided that it's not worth the effort. Whether you fix this or not by moving the CONFIG_CMA check to the same patch that declares it in Kconfig Acked-by: Mel Gorman m...@csn.ul.ie -- Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michał “mina86” Nazarewicz(o o) ooo +email/xmpp: m...@google.com--ooO--(_)--Ooo-- -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/15] mm: mmzone: MIGRATE_CMA migration type added
On Thu, Jan 26, 2012 at 10:00:50AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com The MIGRATE_CMA migration type has two main characteristics: (i) only movable pages can be allocated from MIGRATE_CMA pageblocks and (ii) page allocator will never change migration type of MIGRATE_CMA pageblocks. This guarantees (to some degree) that page in a MIGRATE_CMA page block can always be migrated somewhere else (unless there's no memory left in the system). It is designed to be used for allocating big chunks (eg. 10MiB) of physically contiguous memory. Once driver requests contiguous memory, pages from MIGRATE_CMA pageblocks may be migrated away to create a contiguous block. To minimise number of migrations, MIGRATE_CMA migration type is the last type tried when page allocator falls back to other migration types then requested. Signed-off-by: Michal Nazarewicz min...@mina86.com Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- include/linux/mmzone.h | 43 + include/linux/page-isolation.h |3 ++ mm/Kconfig |2 +- mm/compaction.c| 11 +-- mm/page_alloc.c| 68 +--- mm/vmstat.c|3 ++ 6 files changed, 107 insertions(+), 23 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 650ba2f..fcd4a14 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -35,13 +35,37 @@ */ #define PAGE_ALLOC_COSTLY_ORDER 3 -#define MIGRATE_UNMOVABLE 0 -#define MIGRATE_RECLAIMABLE 1 -#define MIGRATE_MOVABLE 2 -#define MIGRATE_PCPTYPES 3 /* the number of types on the pcp lists */ -#define MIGRATE_RESERVE 3 -#define MIGRATE_ISOLATE 4 /* can't allocate from here */ -#define MIGRATE_TYPES 5 +enum { + MIGRATE_UNMOVABLE, + MIGRATE_RECLAIMABLE, + MIGRATE_MOVABLE, + MIGRATE_PCPTYPES, /* the number of types on the pcp lists */ + MIGRATE_RESERVE = MIGRATE_PCPTYPES, +#ifdef CONFIG_CMA + /* + * MIGRATE_CMA migration type is designed to mimic the way + * ZONE_MOVABLE works. Only movable pages can be allocated + * from MIGRATE_CMA pageblocks and page allocator never + * implicitly change migration type of MIGRATE_CMA pageblock. + * + * The way to use it is to change migratetype of a range of + * pageblocks to MIGRATE_CMA which can be done by + * __free_pageblock_cma() function. What is important though + * is that a range of pageblocks must be aligned to + * MAX_ORDER_NR_PAGES should biggest page be bigger then + * a single pageblock. + */ + MIGRATE_CMA, +#endif + MIGRATE_ISOLATE,/* can't allocate from here */ + MIGRATE_TYPES +}; + +#ifdef CONFIG_CMA +# define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA) +#else +# define is_migrate_cma(migratetype) false +#endif #define for_each_migratetype_order(order, type) \ for (order = 0; order MAX_ORDER; order++) \ @@ -54,6 +78,11 @@ static inline int get_pageblock_migratetype(struct page *page) return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end); } +static inline bool is_pageblock_cma(struct page *page) +{ + return is_migrate_cma(get_pageblock_migratetype(page)); +} + struct free_area { struct list_headfree_list[MIGRATE_TYPES]; unsigned long nr_free; diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h index 430cf61..454dd29 100644 --- a/include/linux/page-isolation.h +++ b/include/linux/page-isolation.h @@ -45,6 +45,9 @@ extern void unset_migratetype_isolate(struct page *page); extern int alloc_contig_range(unsigned long start, unsigned long end); extern void free_contig_range(unsigned long pfn, unsigned nr_pages); +/* CMA stuff */ +extern void init_cma_reserved_pageblock(struct page *page); + #endif #endif diff --git a/mm/Kconfig b/mm/Kconfig index e338407..3922002 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -198,7 +198,7 @@ config COMPACTION config MIGRATION bool Page migration def_bool y - depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION + depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION || CMA help Allows the migration of the physical location of pages of processes while the virtual addresses are not changed. This is useful in diff --git a/mm/compaction.c b/mm/compaction.c index 3e21d28..a075b43 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -35,6 +35,11 @@ static unsigned long release_freepages(struct list_head *freelist) return count; } +static inline bool migrate_async_suitable(int migratetype) +{ + return
Re: [PATCH 10/15] mm: extract reclaim code from __alloc_pages_direct_reclaim()
On Thu, Jan 26, 2012 at 10:00:52AM +0100, Marek Szyprowski wrote: This patch extracts common reclaim code from __alloc_pages_direct_reclaim() function to separate function: __perform_reclaim() which can be later used by alloc_contig_range(). Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com CC: Michal Nazarewicz min...@mina86.com --- mm/page_alloc.c | 30 +- 1 files changed, 21 insertions(+), 9 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 4e60c0b..e35d06b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2094,16 +2094,13 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, } #endif /* CONFIG_COMPACTION */ -/* The really slow allocator path where we enter direct reclaim */ -static inline struct page * -__alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order, - struct zonelist *zonelist, enum zone_type high_zoneidx, - nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, - int migratetype, unsigned long *did_some_progress) +/* Perform direct synchronous page reclaim */ +static inline int +__perform_reclaim(gfp_t gfp_mask, unsigned int order, struct zonelist *zonelist, + nodemask_t *nodemask) This function is too large to be inlined. Make it a static int. Once that is fixed add a Acked-by: Mel Gorman m...@csn.ul.ie -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 03/15] mm: compaction: introduce isolate_migratepages_range().
On Thu, Jan 26, 2012 at 10:00:45AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com @@ -313,7 +316,7 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone, } else if (!locked) spin_lock_irq(zone-lru_lock); - if (!pfn_valid_within(low_pfn)) + if (!pfn_valid(low_pfn)) continue; nr_scanned++; On Mon, 30 Jan 2012 12:24:28 +0100, Mel Gorman m...@csn.ul.ie wrote: This chunk looks unrelated to the rest of the patch. I think what you are doing is patching around a bug that CMA exposed which is very similar to the bug report at http://www.spinics.net/lists/linux-mm/msg29260.html . Is this true? If so, I posted a fix that only calls pfn_valid() when necessary. Can you check if that works for you and if so, drop this hunk please? If the patch does not work for you, then this hunk still needs to be in a separate patch and handled separately as it would also be a fix for -stable. I'll actually never encountered this bug myself and CMA is unlikely to expose it, since it always operates on continuous memory regions with no holes. I've made this change because looking at the code it seemed like this may cause problems in some cases. The crash that you linked to looks like the kind of problem I was thinking about. I'll drop this hunk and let you resolve this independently of CMA. -- Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michał “mina86” Nazarewicz(o o) ooo +email/xmpp: m...@google.com--ooO--(_)--Ooo-- -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH][media] s5p-g2d: Add HFLIP and VFLIP support
On 01/30/2012 01:11 PM, Laurent Pinchart wrote: static int g2d_open(struct file *file) @@ -564,6 +591,8 @@ static void device_run(void *prv) g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); g2d_set_rop4(dev, ctx-rop); +g2d_set_flip(dev, ctx-hflip | ctx-vflip); + Is this called for every frame, or once at stream start only ? In the later case, this means that hflip and vflip won't be changeable during streaming. Is that on purpose ? The device_run() callback is called per each frame, i.e. per each single buffer pair. Hence it should be possible to reconfigure flipping when streaming is on. Thanks, -- Sylwester Nawrocki Samsung Poland RD Center -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 11/15] mm: trigger page reclaim in alloc_contig_range() to stabilize watermarks
On Thu, Jan 26, 2012 at 10:00:53AM +0100, Marek Szyprowski wrote: alloc_contig_range() performs memory allocation so it also should keep track on keeping the correct level of memory watermarks. This commit adds a call to *_slowpath style reclaim to grab enough pages to make sure that the final collection of contiguous pages from freelists will not starve the system. Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com CC: Michal Nazarewicz min...@mina86.com --- mm/page_alloc.c | 36 1 files changed, 36 insertions(+), 0 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e35d06b..05eaa82 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5613,6 +5613,34 @@ static int __alloc_contig_migrate_range(unsigned long start, unsigned long end) return ret; } +/* + * Trigger memory pressure bump to reclaim some pages in order to be able to + * allocate 'count' pages in single page units. Does similar work as + *__alloc_pages_slowpath() function. + */ +static int __reclaim_pages(struct zone *zone, gfp_t gfp_mask, int count) +{ + enum zone_type high_zoneidx = gfp_zone(gfp_mask); + struct zonelist *zonelist = node_zonelist(0, gfp_mask); + int did_some_progress = 0; + int order = 1; + unsigned long watermark; + + /* Obey watermarks as if the page was being allocated */ + watermark = low_wmark_pages(zone) + count; + while (!zone_watermark_ok(zone, 0, watermark, 0, 0)) { + wake_all_kswapd(order, zonelist, high_zoneidx, zone_idx(zone)); + + did_some_progress = __perform_reclaim(gfp_mask, order, zonelist, + NULL); + if (!did_some_progress) { + /* Exhausted what can be done so it's blamo time */ + out_of_memory(zonelist, gfp_mask, order, NULL); + } There are three problems here 1. CMA can trigger the OOM killer. That seems like overkill to me but as I do not know the consequences of CMA failing, it's your call. 2. You cannot guarantee that try_to_free_pages will free pages from the zone you care about or that kswapd will do anything You check the watermarks and take into account the size of the pending CMA allocation. kswapd in vmscan.c on the other hand will simply check the watermarks and probably go back to sleep. You should be aware of this in case you ever get bugs that CMA takes too long and that it appears to be stuck in this loop with kswapd staying asleep. 3. You reclaim from zones other than your target zone try_to_free_pages is not necessarily going to free pages in the zone you are checking for. It'll work on ARM in many cases because there will be only one zone but on other arches, this logic will be problematic and will potentially livelock. You need to pass in a zonelist that only contains the zone that CMA cares about. If it cannot reclaim, did_some_progress == 0 and it'll exit. Otherwise there is a possibility that this will loop forever reclaiming pages from the wrong zones. I won't ack this particular patch but I am not going to insist that you fix these prior to merging either. If you leave problem 3 as it is, I would really like to see a comment explaning the problem for future users of CMA on other arches (if they exist). -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/15] mm: mmzone: MIGRATE_CMA migration type added
On Thu, Jan 26, 2012 at 10:00:50AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com @@ -875,10 +895,15 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, * This array describes the order lists are fallen back to when * the free lists for the desirable migrate type are depleted */ -static int fallbacks[MIGRATE_TYPES][3] = { +static int fallbacks[MIGRATE_TYPES][4] = { [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE }, [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE }, +#ifdef CONFIG_CMA + [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_CMA, MIGRATE_RESERVE }, On Mon, 30 Jan 2012 13:35:42 +0100, Mel Gorman m...@csn.ul.ie wrote: This is a curious choice. MIGRATE_CMA is allowed to contain movable pages. By using MIGRATE_RECLAIMABLE and MIGRATE_UNMOVABLE for movable pages instead of MIGRATE_CMA, you increase the changes that unmovable pages will need to use MIGRATE_MOVABLE in the future which impacts fragmentation avoidance. I would recommend that you change this to { MIGRATE_CMA, MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE } At the beginning the idea was to try hard not to get pages from MIGRATE_CMA allocated at all, thus it was put at the end of the fallbacks list, but on a busy system this probably won't help anyway, so I'll change it per your suggestion. @@ -1017,11 +1049,14 @@ __rmqueue_fallback(struct zone *zone, int order, int start_migratetype) rmv_page_order(page); /* Take ownership for orders = pageblock_order */ - if (current_order = pageblock_order) + if (current_order = pageblock_order + !is_pageblock_cma(page)) change_pageblock_range(page, current_order, start_migratetype); - expand(zone, page, order, current_order, area, migratetype); + expand(zone, page, order, current_order, area, + is_migrate_cma(start_migratetype) +? start_migratetype : migratetype); What is this check meant to be doing? start_migratetype is determined by allocflags_to_migratetype() and that never will be MIGRATE_CMA so is_migrate_cma(start_migratetype) should always be false. Right, thanks! This should be the other way around, ie.: + expand(zone, page, order, current_order, area, + is_migrate_cma(migratetype) +? migratetype : start_migratetype); I'll fix this and the calls to is_pageblock_cma(). -- Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michał “mina86” Nazarewicz(o o) ooo +email/xmpp: m...@google.com--ooO--(_)--Ooo-- -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv19 00/15] Contiguous Memory Allocator
On Fri, Jan 27, 2012 at 04:26:24PM -0800, Andrew Morton wrote: On Thu, 26 Jan 2012 15:31:40 + Arnd Bergmann a...@arndb.de wrote: On Thursday 26 January 2012, Marek Szyprowski wrote: Welcome everyone! Yes, that's true. This is yet another release of the Contiguous Memory Allocator patches. This version mainly includes code cleanups requested by Mel Gorman and a few minor bug fixes. Hi Marek, Thanks for keeping up this work! I really hope it works out for the next merge window. Someone please tell me when it's time to start paying attention again ;) These patches don't seem to have as many acked-bys and reviewed-bys as I'd expect. I reviewed the core MM changes and I've acked most of them so the next release should have a few acks where you expect them. I did not add a reviewed-by because I did not build and test the thing. For me, Patch 2 is the only one that must be fixed prior to merging as it can interfere with pages on a remote per-cpu list which is dangerous. I know your suggestion will be to delete the per-cpu lists and be done with it but I am a bit away from doing that just yet. Patch 8 could do with a bit more care too but it is not a potential hand grenade like patch 2 and could be fixed as part of a follow-up. Even if you don't see an ack from me there, it should not be treated as a show stopper. I highlighted some issues on how CMA interacts with reclaim but I think this is a problem specific to CMA and should not prevent it being merged. I just wanted to be sure that the CMA people were aware of the potential issues so they will recognise the class of bug if it occurs. Given the scope and duration of this, it would be useful to gather these up. But please ensure they are real ones - people sometimes like to ack things without showing much sign of having actually read them. FWIW, the acks I put on the core MM changes are real acks :) The patches do seem to have been going round in ever-decreasing circles lately and I think we have decided to merge them (yes?) so we may as well get on and do that and sort out remaining issues in-tree. I'm a lot happier with the core MM patches than I was when I reviewed this first around last September or October. -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 03/15] mm: compaction: introduce isolate_migratepages_range().
On Mon, Jan 30, 2012 at 01:42:50PM +0100, Michal Nazarewicz wrote: On Thu, Jan 26, 2012 at 10:00:45AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com @@ -313,7 +316,7 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone, } else if (!locked) spin_lock_irq(zone-lru_lock); - if (!pfn_valid_within(low_pfn)) + if (!pfn_valid(low_pfn)) continue; nr_scanned++; On Mon, 30 Jan 2012 12:24:28 +0100, Mel Gorman m...@csn.ul.ie wrote: This chunk looks unrelated to the rest of the patch. I think what you are doing is patching around a bug that CMA exposed which is very similar to the bug report at http://www.spinics.net/lists/linux-mm/msg29260.html . Is this true? If so, I posted a fix that only calls pfn_valid() when necessary. Can you check if that works for you and if so, drop this hunk please? If the patch does not work for you, then this hunk still needs to be in a separate patch and handled separately as it would also be a fix for -stable. I'll actually never encountered this bug myself and CMA is unlikely to expose it, since it always operates on continuous memory regions with no holes. I've made this change because looking at the code it seemed like this may cause problems in some cases. The crash that you linked to looks like the kind of problem I was thinking about. I'll drop this hunk and let you resolve this independently of CMA. Ok, thanks. -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH][media] s5p-g2d: Add HFLIP and VFLIP support
Hi Laurent and Sachin, Thanks for the patch and for your comments. From: Laurent Pinchart [mailto:laurent.pinch...@ideasonboard.com] Sent: 30 January 2012 13:12 Hi Sashin, Thanks for the patch. On Monday 30 January 2012 10:58:43 Sachin Kamat wrote: This patch adds support for flipping the image horizontally and vertically. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org --- drivers/media/video/s5p-g2d/g2d-hw.c |5 +++ drivers/media/video/s5p-g2d/g2d.c| 47 + -- drivers/media/video/s5p-g2d/g2d.h|3 ++ 3 files changed, 46 insertions(+), 9 deletions(-) [snip] diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c index febaa67..dea9701 100644 --- a/drivers/media/video/s5p-g2d/g2d.c +++ b/drivers/media/video/s5p-g2d/g2d.c @@ -178,6 +178,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) { struct g2d_ctx *ctx = container_of(ctrl-handler, struct g2d_ctx, ctrl_handler); + switch (ctrl-id) { case V4L2_CID_COLORFX: if (ctrl-val == V4L2_COLORFX_NEGATIVE) @@ -185,6 +186,21 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) else ctx-rop = ROP4_COPY; break; + + case V4L2_CID_HFLIP: + if (ctrl-val == 1) + ctx-hflip = 1; + else + ctx-hflip = 0; + break; + + case V4L2_CID_VFLIP: + if (ctrl-val == 1) + ctx-vflip = (1 1); + else + ctx-vflip = 0; + break; I think that case V4L2_CID_HFLIP: ctx-hflip = ctrl-val; break; case V4L2_CID_VFLIP: ctx-vflip = (ctrl-val 1); break; will be sufficient, as flip controls have min=0 and max=1 which makes them safe to use. + default: v4l2_err(ctx-dev-v4l2_dev, unknown control\n); return -EINVAL; @@ -200,11 +216,9 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx) { struct g2d_dev *dev = ctx-dev; - v4l2_ctrl_handler_init(ctx-ctrl_handler, 1); - if (ctx-ctrl_handler.error) { - v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); - return ctx-ctrl_handler.error; - } + v4l2_ctrl_handler_init(ctx-ctrl_handler, 3); + if (ctx-ctrl_handler.error) + goto error; There's not need to verify ctx-ctrl_handler.error after every call to v4l2_ctrl_handler_init() or v4l2_ctrl_new_*(). You can verify it once only after initialization all controls. I agree. v4l2_ctrl_new_std_menu( ctx-ctrl_handler, @@ -214,12 +228,25 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx) ~((1 V4L2_COLORFX_NONE) | (1 V4L2_COLORFX_NEGATIVE)), V4L2_COLORFX_NONE); - if (ctx-ctrl_handler.error) { - v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); - return ctx-ctrl_handler.error; - } + if (ctx-ctrl_handler.error) + goto error; + + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + if (ctx-ctrl_handler.error) + goto error; + + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); As a single register controls hflip and vflip, you should group the two controls in a cluster. I think it doesn't matter in this use case. As register are not written in the g2d_s_ctrl. Because the driver uses multiple context it modifies the appropriate values in its context structure and registers are written when the transaction is run. Also there is no logical connection between horizontal and vertical flip. I think this is the case when using clusters. Here one is independent from another. + if (ctx-ctrl_handler.error) + goto error; return 0; + +error: + v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); + return ctx-ctrl_handler.error; + } static int g2d_open(struct file *file) @@ -564,6 +591,8 @@ static void device_run(void *prv) g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); g2d_set_rop4(dev, ctx-rop); + g2d_set_flip(dev, ctx-hflip | ctx-vflip); + Is this called for every frame, or once at stream start only ? In the later case, this means that hflip and vflip won't be changeable during streaming. Is that on purpose ? if (ctx-in.c_width != ctx-out.c_width || ctx-in.c_height != ctx-out.c_height) cmd |= g2d_cmd_stretch(1); diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/video/s5p-g2d/g2d.h index 5eae901..b3be3c8 100644 --- a/drivers/media/video/s5p-g2d/g2d.h +++ b/drivers/media/video/s5p-g2d/g2d.h @@ -59,6 +59,8 @@ struct g2d_ctx { struct
Re: [PATCH v2 1/1] omap3isp: Prevent crash at module unload
Hi Sakari, Thanks for the patch. On Friday 27 January 2012 11:18:51 Sakari Ailus wrote: iommu_domain_free() was called in isp_remove() before omap3isp_put(). omap3isp_put() must not save the context if the IOMMU no longer is there. Fix this. Signed-off-by: Sakari Ailus sakari.ai...@iki.fi Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Applied to my tree. --- Compared to v1, neither the ISP context is saved. drivers/media/video/omap3isp/isp.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index 12d5f92..d4e0905 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c @@ -1495,7 +1495,8 @@ void omap3isp_put(struct isp_device *isp) BUG_ON(isp-ref_count == 0); if (--isp-ref_count == 0) { isp_disable_interrupts(isp); - isp_save_ctx(isp); + if (isp-domain) + isp_save_ctx(isp); if (isp-needs_reset) { isp_reset(isp); isp-needs_reset = false; @@ -1981,6 +1982,7 @@ static int isp_remove(struct platform_device *pdev) omap3isp_get(isp); iommu_detach_device(isp-domain, pdev-dev); iommu_domain_free(isp-domain); + isp-domain = NULL; omap3isp_put(isp); free_irq(isp-irq_num, isp); -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Linaro-mm-sig] [PATCH 05/10] v4l: add buffer exporting via dmabuf
Hi Subash, On Friday 27 January 2012 14:40:34 Subash Patel wrote: On 01/24/2012 05:36 PM, Tomasz Stanislawski wrote: On 01/24/2012 12:07 PM, Subash Patel wrote: Instead of adding another IOCTL to query the file-descriptor in user-space, why dont we extend the existing ones in v4l2/vb2? When the memory type set is V4L2_MEMORY_DMABUF, call to VIDIOC_REQBUFS /VIDIOC_QUERYBUF from driver can take/return the fd. We will need to add another attribute to struct v4l2_requestbuffers for this. struct v4l2_requestbuffers { ... __u32 buf_fd; }; The application requesting buffer would set it to -1, and will receive the fd's when it calls the vb2_querybuf. In the same way, application which is trying to attach to already allocated buffer will set this to valid fd when it calls vidioc_reqbuf, and in vb2_reqbuf depending on the memory type, this can be checked and used to attach with the dma_buf for the respective buffer. Ofcourse, this requires changes in vb2_reqbufs and vb2_querybuf similar to what you did in vb2_expbufs. Will there be any issues in such an approach? I like your idea but IMO there are some issues which this approach. The VIDIOC_REQBUF is used to create a collection of buffers (i.e. 5 frames). Every frame is a separate buffer therefore it should have separate dmabuf file descriptor. This way you should add buffer index to v4l2_request_buffers. Of course but one could reuse count field but there is still problem with multiplane buffers (see below). I agree. Please note that dmabuf file could be create only for buffers with MMAP memory type. The DMABUF memory type for VIDIOC_REQBUFS indicate that a buffer is imported from DMABUF file descriptor. Similar way like content of USERPTR buffers is taken from user pointer. Therefore only MMAP buffers can be exported as DMABUF file descriptor. I think for time being, mmap is best way we can share buffers between IP's, like MM and GPU. If VIDIOC_REQUBUF is used for buffer exporting, how to request a bunch of buffers that are dedicated to obtain memory from DMABUF file descriptors? I am not sure if I understand this question. But what I meant is, VIDIOC_REQBUF with memory type V4L2_MEMORY_DMABUF will ask the driver to allocate MMAP type memory and create the dmabuf handles for those. In the next call to VIDIOC_QUERYBUF (which you do on each of the buffers infact), driver will return the dmabuf file descriptors to user space. This can be used by the user space to mmap(when dmabuf supports) or pass it onto another process to share the buffers. That would be nice, but VIDIOC_REQBUFS(DMABUF) is already used to allocate buffers that will be imported using dma-buf. We need to handle both the importer use case and the exporter use case, we can't handle both with just VIDIOC_REQBUFS(DMABUF). The recipient user process can now pass these dmabuf file descriptors in VIDIOC_REQBUF itself to its driver (say another v4l2 based). In the driver, when the user space calls VIDIOC_QUERYBUF for those buffers, we can call dmabuf's attach() to actually link to the buffer. Does it make sense? The second problem is VIDIOC_QUERYBUF. According to V4L2 spec, the memory type field is read only. The driver returns the same memory type as it was used in VIDIOC_REQBUFS. Therefore VIDIOC_QUERYBUF can only be used for MMAP buffers to obtain memoffset. For DMABUF it may return fd=-1 or most recently used file descriptor. As I remember, it was not defined yet. I was thinking why not the memory type move out from enum to an int? In that case, we can send ORed types, like V4L2_MEMORY_MMAP|V4L2_MEMORY_DMABUF etc. Does it help? That would break our API, so we can't do that (although we could still OR enum types). The third reason are multiplane buffers. This API was introduced if V4L2 buffer (IMO it should be called a frame) consist of multiple memory buffers. Every plane can be mmapped separately. Therefore it should be possible to export every plane as separate DMABUF descriptor. Do we require to export every plane as separate dmabuf? I think dmabuf should cover entire multi-plane buffer instead of individual planes. It depends on the drivers you use. Some drivers require planes to be contiguous in memory, in which case a single dma-buf will likely be used. Other drivers can allocate the planes in separate memory regions. Several dma- buf objects then make sense. How to calculate individual plane offsets should be the property of the driver depending on its need for it. After some research it was found that memoffset is good identifier of a plane in a buffers. This id is also available in the userspace without any API extensions. VIDIOC_EXPBUF was used to export a buffer by id, similar way as mmap uses this identifier to map a buffer to userspace. It seams to be the simplest solution. Ok. Then dont you think when dmabuf
Re: [PATCH] dma-buf: add dma_data_direction to unmap dma_buf_op
Hi Sumit, On Friday 27 January 2012 10:43:28 Sumit Semwal wrote: Some exporters may use DMA map/unmap APIs in dma-buf ops, which require enum dma_data_direction for both map and unmap operations. Thus, the unmap dma_buf_op also needs to have enum dma_data_direction as a parameter. Reported-by: Tomasz Stanislawski t.stanisl...@samsung.com Signed-off-by: Sumit Semwal sumit.sem...@ti.com --- drivers/base/dma-buf.c |7 +-- include/linux/dma-buf.h |8 +--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 8afe2dd..c9a945f 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c @@ -271,16 +271,19 @@ EXPORT_SYMBOL_GPL(dma_buf_map_attachment); * dma_buf_ops. * @attach: [in]attachment to unmap buffer from * @sg_table:[in]scatterlist info of the buffer to unmap + * @direction: [in]direction of DMA transfer * */ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, - struct sg_table *sg_table) + struct sg_table *sg_table, + enum dma_data_direction direction) { if (WARN_ON(!attach || !attach-dmabuf || !sg_table)) return; mutex_lock(attach-dmabuf-lock); - attach-dmabuf-ops-unmap_dma_buf(attach, sg_table); + attach-dmabuf-ops-unmap_dma_buf(attach, sg_table, + direction); mutex_unlock(attach-dmabuf-lock); } diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 86f6241..847b026 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -63,7 +63,8 @@ struct dma_buf_ops { struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *, enum dma_data_direction); void (*unmap_dma_buf)(struct dma_buf_attachment *, - struct sg_table *); + struct sg_table *, + enum dma_data_direction); /* TODO: Add try_map_dma_buf version, to return immed with -EBUSY * if the call would block. */ @@ -122,7 +123,8 @@ void dma_buf_put(struct dma_buf *dmabuf); struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *, enum dma_data_direction); -void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *); +void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, + enum dma_data_direction); #else static inline struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, @@ -166,7 +168,7 @@ static inline struct sg_table *dma_buf_map_attachment( } static inline void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, -struct sg_table *sg) + struct sg_table *sg, enum dma_data_direction write) s/write/dir/ (or direction) ? { return; } -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFCv1 2/4] v4l:vb2: add support for shared buffer (dma_buf)
Hi Daniel, On Sunday 29 January 2012 14:03:40 Daniel Vetter wrote: On Sun, Jan 29, 2012 at 01:03:39PM +0200, Sakari Ailus wrote: Daniel Vetter wrote: On Thu, Jan 26, 2012 at 01:28:16AM +0200, Sakari Ailus wrote: Why you should not hang onto mappings forever? This is currently done by virtually all V4L2 drivers where such mappings are relevant. Not doing so would really kill the performance i.e. it's infeasible. Same goes to (m)any other multimedia devices dealing with buffers containing streaming video data. Because I want dynamic memory managemt simple because everything else does not make sense. I know that in v4l things don't work that way, but in drm they _do_. And if you share tons of buffers with drm drivers and don't follow the rules, the OOM killer will come around and shot at your apps. Because at least in i915 we do slurp in as much memory as we can until the oom killer starts growling, at which point we kick out stuff. I know that current dma_buf isn't there and for many use-cases discussed here we can get away without that complexity. So you actually can just map your dma_buf and never ever let go of that mapping again in many cases. The only reason I'm such a stuborn bastard about all this is that drm/* will do dynamic bo management even with dma_buf sooner or later and you should better know that and why and the implications if you choose to ignore it. And obviously, the generic dma_buf interface needs to be able to support it. I do not think we should completely ignore this issue, but I think we might want to at least postpone the implementation for non-DRM subsystems to an unknown future date. The reason is simply that it's currently unfeasible for various reasons. Sharing large buffers with GPUs (where you might want to manage them independently of the user space) is uncommon; typically you're sharing buffers for viewfinder that tend to be around few megabytes in size and there may be typically up to five of them. Also, we're still far from getting things working in the first place. Let's not complicate them more than we have to. The very reason why we're pre-allocating these large buffers in applications is that you can readily use them when you need them. Consider camera, for example: a common use case is to have a set of 24 MB buffers (for 12 Mp images) prepared while the viewfinder is running. These buffers must be immediately usable when the user presses the shutter button. We don't want to continuously map and unmap buffers in viewfinder either: that adds a significan CPU load for no technical reason whatsoever. Typically viewfinder also involves running software algorithms that consume much of the available CPU time, so adding an unnecessary CPU hog to the picture doesn't sound that enticing. If the performance of memory management can be improved to such an extent it really takes much less than a millisecond or so to perform all the pinning-to-memory, IOMMU mapping and so on systems for 24 MB buffers on regular embedded systems I think I wouldn't have much against doing so. Currently I think we're talking about numbers that are at least 100-fold. If you want to do this to buffers used only in DRM I'm fine with that. A few things: - I do understand that there are use cases where allocate, pin forget works. I don't like the forget part :-) As a V4L2 developer, I'm not advocating for keeping mappings around forever, but to keep them for as long as possible. Without such a feature, dma-buf support in V4L2 will just be a proof-of-concept, with little use in real products. - I'm perfectly fine if you do this in your special embedded product. Or the entire v4l subsystem, I don't care much about that one, either. I thought the point of these discussions was to start caring about each- other's subsystems :-) But: - I'm fully convinced that all these special purpose single use-case scenarios will show up sooner or later on a more general purpose platform. - And as soon as your on a general purpose platform, you _want_ dynamic memory management. I'm pretty sure we want dynamic memory management in special-purpose platforms as well. I mean the entire reason people are pushing CMA is that preallocating gobs of memory statically really isn't that great an idea ... So to summarize I understand your constraints - gpu drivers have worked like v4l a few years ago. The thing I'm trying to achieve with this constant yelling is just to raise awereness for these issues so that people aren't suprised when drm starts pulling tricks on dma_bufs. Once again, our constraints is not that we need to keep mappings around forever, but that we want to keep them for as long as possible. I don't think DRM is an issue here, I'm perfectly fine with releasing the mapping when DRM (or any other subsystem) needs
Re: [RFCv1 2/4] v4l:vb2: add support for shared buffer (dma_buf)
Hi Daniel, On Tuesday 24 January 2012 14:03:22 Daniel Vetter wrote: On Mon, Jan 23, 2012 at 11:54:20AM +0100, Laurent Pinchart wrote: On Monday 23 January 2012 11:35:01 Daniel Vetter wrote: See my other mail, dma_buf v1 does not support cpu access. v1 is in the kernel now, let's start discussing v2 ;-) Ok, I'm in ;-) I've thought a bit about this, and I think a reasonable next step would be to enable cpu access from kernelspace. Userspace and mmap support is a hole different beast altogether and I think we should postpone that until we've got the kernel part hashed out. Userspace access through mmap can already be handled by the subsystem that exports the buffer, so I'm fine with postponing implementing this inside dma- buf. I'm thinking about adding 3 pairs of function to dma_buf (not to dma_buf_attachment). dma_buf_get_backing_storage/put_backing_storage This will be used before/after kernel cpu access to ensure that the backing storage is in memory. E.g. gem objects can be swapped out, so they need to be pinned before we can access them. For exporters with static allocations this would be a no-op. I think a start, length range would make sense, but the exporter is free to just swap in the entire object unconditionally. The range is specified in multiples of PAGE_SIZE - I don't think there's any usescase for a get/put_backing_storage which deals in smaller units. The get/put functions are allowed to block and grab all kinds of looks. get is allowed to fail with e.g. -ENOMEM. dma_buf_kmap/kunmap This maps _one_ page into the kernels address space and out of it. This function also flushes/invalidates any caches required. Importers are not allowed to map more than 2 pages at the same time in total (to allow copies). This is because at least for gem objects the backing storage can be in high-mem. Importers are allowed to sleep while holding such a kernel mapping. These functions are not allowed to fail (like kmap/kunmap). dma_buf_kmap_atomic/kunmap_atomic For performance we want to also allow atomic mappigns. Only difference is that importers are not allowed to sleep while holding an atomic mapping. These functions are again not allowed to fail. Comments, flames? Before commenting (I don't plan on flaming :-)), I'd like to take a small step back. Could you describe the use case(s) you think of for kernel mappings ? If this sounds sensible I'll throw together a quick rfc over the next few days. Cheers, Daniel PS: Imo the next step after this would be adding userspace mmap support. This has the funky requirement that the exporter needs to be able to shot down any ptes before it moves around the buffer. I think solving that nice little problem is a good exercise to prepare us for solving similar get of this buffer, now issues with permanent device address space mappings ... -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/15] mm: mmzone: MIGRATE_CMA migration type added
On Mon, Jan 30, 2012 at 02:06:50PM +0100, Michal Nazarewicz wrote: @@ -1017,11 +1049,14 @@ __rmqueue_fallback(struct zone *zone, int order, int start_migratetype) rmv_page_order(page); /* Take ownership for orders = pageblock_order */ - if (current_order = pageblock_order) + if (current_order = pageblock_order + !is_pageblock_cma(page)) change_pageblock_range(page, current_order, start_migratetype); - expand(zone, page, order, current_order, area, migratetype); + expand(zone, page, order, current_order, area, + is_migrate_cma(start_migratetype) +? start_migratetype : migratetype); What is this check meant to be doing? start_migratetype is determined by allocflags_to_migratetype() and that never will be MIGRATE_CMA so is_migrate_cma(start_migratetype) should always be false. Right, thanks! This should be the other way around, ie.: + expand(zone, page, order, current_order, area, +is_migrate_cma(migratetype) + ? migratetype : start_migratetype); I'll fix this and the calls to is_pageblock_cma(). That makes a lot more sense. Thanks. I have a vague recollection that there was a problem with finding unmovable pages in MIGRATE_CMA regions. This might have been part of the problem. -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 02/15] mm: page_alloc: update migrate type of pages on pcp when isolating
On Mon, 30 Jan 2012 12:15:22 +0100, Mel Gorman m...@csn.ul.ie wrote: On Thu, Jan 26, 2012 at 10:00:44AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com @@ -139,3 +139,27 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn) spin_unlock_irqrestore(zone-lock, flags); return ret ? 0 : -EBUSY; } + +/* must hold zone-lock */ +void update_pcp_isolate_block(unsigned long pfn) +{ + unsigned long end_pfn = pfn + pageblock_nr_pages; + struct page *page; + + while (pfn end_pfn) { + if (!pfn_valid_within(pfn)) { + ++pfn; + continue; + } + On Mon, 30 Jan 2012 12:15:22 +0100, Mel Gorman m...@csn.ul.ie wrote: There is a potential problem here that you need to be aware of. set_pageblock_migratetype() is called from start_isolate_page_range(). I do not think there is a guarantee that pfn + pageblock_nr_pages is not in a different block of MAX_ORDER_NR_PAGES. If that is right then your options are to add a check like this; if ((pfn (MAX_ORDER_NR_PAGES - 1)) == 0 !pfn_valid(pfn)) break; or else ensure that end_pfn is always MAX_ORDER_NR_PAGES aligned and in the same block as pfn and relying on the caller to have called pfn_valid. pfn = round_down(pfn, pageblock_nr_pages); end_pfn = pfn + pageblock_nr_pages; should do the trick as well, right? move_freepages_block() seem to be doing the same thing. + page = pfn_to_page(pfn); + if (PageBuddy(page)) { + pfn += 1 page_order(page); + } else if (page_count(page) == 0) { + set_page_private(page, MIGRATE_ISOLATE); + ++pfn; This is dangerous for two reasons. If the page_count is 0, it could be because the page is in the process of being freed and is not necessarily on the per-cpu lists yet and you cannot be sure if the contents of page-private are important. Second, there is nothing to prevent another CPU allocating this page from its per-cpu list while the private field is getting updated from here which might lead to some interesting races. I recognise that what you are trying to do is respond to Gilad's request that you really check if an IPI here is necessary. I think what you need to do is check if a page with a count of 0 is encountered and if it is, then a draining of the per-cpu lists is necessary. To address Gilad's concerns, be sure to only this this once per attempt at CMA rather than for every page encountered with a count of 0 to avoid a storm of IPIs. It's actually more then that. This is the same issue that I first fixed with a change to free_pcppages_bulk() function[1]. At the time of positing, you said you'd like me to try and find a different solution which would not involve paying the price of calling get_pageblock_migratetype(). Later I also realised that this solution is not enough. [1] http://article.gmane.org/gmane.linux.kernel.mm/70314 My next attempt was to run drain PCP list while holding zone-lock[2], but that quickly proven to be broken approach when Marek started testing it on an SMP system. [2] http://article.gmane.org/gmane.linux.kernel.mm/72016 This patch is yet another attempt of solving this old issue. Even though it has a potential race condition we came to conclusion that the actual chances of causing any problems are slim. Various stress tests did not, in fact, show the race to be an issue. The problem is that if a page is on a PCP list, and it's underlaying pageblocks' migrate type is changed to MIGRATE_ISOLATE, the page (i) will still remain on PCP list and thus someone can allocate it, and (ii) when removed from PCP list, the page will be put on freelist of migrate type it had prior to change. (i) is actually not such a big issue since the next thing that happens after isolation is migration so all the pages will get freed. (ii) is actual problem and if [1] is not an acceptable solution I really don't have a good fix for that. One things that comes to mind is calling drain_all_pages() prior to acquiring zone-lock in set_migratetype_isolate(). This is however prone to races since after the drain and before the zone-lock is acquired, pages might get moved back to PCP list. Draining PCP list after acquiring zone-lock is not possible because smp_call_function_many() cannot be called with interrupts disabled, and changing spin_lock_irqsave() to spin_lock() followed by local_irq_save() causes a dead lock (that's what [2] attempted to do). Any suggestions are welcome! + } else { + ++pfn; + } + } +} -- Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michał “mina86” Nazarewicz(o o) ooo +email/xmpp: m...@google.com--ooO--(_)--Ooo-- -- To unsubscribe
Re: [PATCHv19 00/15] Contiguous Memory Allocator
On Mon, 30 Jan 2012 14:25:12 +0100, Mel Gorman m...@csn.ul.ie wrote: I reviewed the core MM changes and I've acked most of them so the next release should have a few acks where you expect them. I did not add a reviewed-by because I did not build and test the thing. Thanks! I've either replied to your comments or applied suggested changes. If anyone cares, not-tested changes are available at git://github.com/mina86/linux-2.6.git cma -- Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michał “mina86” Nazarewicz(o o) ooo +email/xmpp: m...@google.com--ooO--(_)--Ooo-- -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 02/15] mm: page_alloc: update migrate type of pages on pcp when isolating
On Mon, Jan 30, 2012 at 04:41:22PM +0100, Michal Nazarewicz wrote: On Mon, 30 Jan 2012 12:15:22 +0100, Mel Gorman m...@csn.ul.ie wrote: On Thu, Jan 26, 2012 at 10:00:44AM +0100, Marek Szyprowski wrote: From: Michal Nazarewicz min...@mina86.com @@ -139,3 +139,27 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn) spin_unlock_irqrestore(zone-lock, flags); return ret ? 0 : -EBUSY; } + +/* must hold zone-lock */ +void update_pcp_isolate_block(unsigned long pfn) +{ + unsigned long end_pfn = pfn + pageblock_nr_pages; + struct page *page; + + while (pfn end_pfn) { + if (!pfn_valid_within(pfn)) { + ++pfn; + continue; + } + On Mon, 30 Jan 2012 12:15:22 +0100, Mel Gorman m...@csn.ul.ie wrote: There is a potential problem here that you need to be aware of. set_pageblock_migratetype() is called from start_isolate_page_range(). I do not think there is a guarantee that pfn + pageblock_nr_pages is not in a different block of MAX_ORDER_NR_PAGES. If that is right then your options are to add a check like this; if ((pfn (MAX_ORDER_NR_PAGES - 1)) == 0 !pfn_valid(pfn)) break; or else ensure that end_pfn is always MAX_ORDER_NR_PAGES aligned and in the same block as pfn and relying on the caller to have called pfn_valid. pfn = round_down(pfn, pageblock_nr_pages); end_pfn = pfn + pageblock_nr_pages; should do the trick as well, right? move_freepages_block() seem to be doing the same thing. That would also do it the trick. + page = pfn_to_page(pfn); + if (PageBuddy(page)) { + pfn += 1 page_order(page); + } else if (page_count(page) == 0) { + set_page_private(page, MIGRATE_ISOLATE); + ++pfn; This is dangerous for two reasons. If the page_count is 0, it could be because the page is in the process of being freed and is not necessarily on the per-cpu lists yet and you cannot be sure if the contents of page-private are important. Second, there is nothing to prevent another CPU allocating this page from its per-cpu list while the private field is getting updated from here which might lead to some interesting races. I recognise that what you are trying to do is respond to Gilad's request that you really check if an IPI here is necessary. I think what you need to do is check if a page with a count of 0 is encountered and if it is, then a draining of the per-cpu lists is necessary. To address Gilad's concerns, be sure to only this this once per attempt at CMA rather than for every page encountered with a count of 0 to avoid a storm of IPIs. It's actually more then that. This is the same issue that I first fixed with a change to free_pcppages_bulk() function[1]. At the time of positing, you said you'd like me to try and find a different solution which would not involve paying the price of calling get_pageblock_migratetype(). Later I also realised that this solution is not enough. [1] http://article.gmane.org/gmane.linux.kernel.mm/70314 Yes. I had forgotten the history but looking at that patch again, I would reach the conclusion that this was adding a new call to get_pageblock_migratetype() in the bulk free path. That would affect everybody whether they were using CMA or not. My next attempt was to run drain PCP list while holding zone-lock[2], but that quickly proven to be broken approach when Marek started testing it on an SMP system. [2] http://article.gmane.org/gmane.linux.kernel.mm/72016 This patch is yet another attempt of solving this old issue. Even though it has a potential race condition we came to conclusion that the actual chances of causing any problems are slim. Various stress tests did not, in fact, show the race to be an issue. It is a really small race. To cause a problem CPU 1 must find a page with count 0, CPU 2 must then allocate the page and set page-private before CPU 1 overwrites that value but it's there. The problem is that if a page is on a PCP list, and it's underlaying pageblocks' migrate type is changed to MIGRATE_ISOLATE, the page (i) will still remain on PCP list and thus someone can allocate it, and (ii) when removed from PCP list, the page will be put on freelist of migrate type it had prior to change. (i) is actually not such a big issue since the next thing that happens after isolation is migration so all the pages will get freed. (ii) is actual problem and if [1] is not an acceptable solution I really don't have a good fix for that. One things that comes to mind is calling drain_all_pages() prior to acquiring zone-lock in set_migratetype_isolate(). This is however prone to races since after the drain and before the zone-lock is acquired, pages might get moved back to PCP list. Draining PCP list after acquiring zone-lock is not possible because
Re: [RFCv1 2/4] v4l:vb2: add support for shared buffer (dma_buf)
On Mon, Jan 30, 2012 at 03:44:20PM +0100, Laurent Pinchart wrote: Hi Daniel, On Tuesday 24 January 2012 14:03:22 Daniel Vetter wrote: On Mon, Jan 23, 2012 at 11:54:20AM +0100, Laurent Pinchart wrote: On Monday 23 January 2012 11:35:01 Daniel Vetter wrote: See my other mail, dma_buf v1 does not support cpu access. v1 is in the kernel now, let's start discussing v2 ;-) Ok, I'm in ;-) I've thought a bit about this, and I think a reasonable next step would be to enable cpu access from kernelspace. Userspace and mmap support is a hole different beast altogether and I think we should postpone that until we've got the kernel part hashed out. Userspace access through mmap can already be handled by the subsystem that exports the buffer, so I'm fine with postponing implementing this inside dma- buf. Actually I think the interface for mmap won't be that horribly. If we add a bit of magic clue so that the exporter can intercept pagefaults we should be able to fake coherent mmaps in all cases. And hence avoid exposing importers and userspace to a lot of ugly things. I'm thinking about adding 3 pairs of function to dma_buf (not to dma_buf_attachment). dma_buf_get_backing_storage/put_backing_storage This will be used before/after kernel cpu access to ensure that the backing storage is in memory. E.g. gem objects can be swapped out, so they need to be pinned before we can access them. For exporters with static allocations this would be a no-op. I think a start, length range would make sense, but the exporter is free to just swap in the entire object unconditionally. The range is specified in multiples of PAGE_SIZE - I don't think there's any usescase for a get/put_backing_storage which deals in smaller units. The get/put functions are allowed to block and grab all kinds of looks. get is allowed to fail with e.g. -ENOMEM. dma_buf_kmap/kunmap This maps _one_ page into the kernels address space and out of it. This function also flushes/invalidates any caches required. Importers are not allowed to map more than 2 pages at the same time in total (to allow copies). This is because at least for gem objects the backing storage can be in high-mem. Importers are allowed to sleep while holding such a kernel mapping. These functions are not allowed to fail (like kmap/kunmap). dma_buf_kmap_atomic/kunmap_atomic For performance we want to also allow atomic mappigns. Only difference is that importers are not allowed to sleep while holding an atomic mapping. These functions are again not allowed to fail. Comments, flames? Before commenting (I don't plan on flaming :-)), I'd like to take a small step back. Could you describe the use case(s) you think of for kernel mappings ? One is simply for devices where the kernel has to shove around the data - I've heard some complaints in the v4l dma_buf threads that this seems to be dearly in need. E.g. when the v4l devices is attached to usb or behind another slow(er) bus where direct dma is not possible. The other is that currently importers are 2nd class citizens and can't do any cpu access. Making kernel cpu access would be the first step (afterswards getting mmap working for userspace cpu access). Now for some simple use-case we can just say use the access paths provided by the exporter. But for gpu drivers this gets really ugly because the upload/download paths aren't standardized within drm/* and they're all highly optimized. So to make buffer sharing possible among gpu's we need this - the current gem prime code just grabs the underlying struct page with sg_page and horribly fails if that doesn't work ;-) On my proposal itself I think I'll change get/put_backing_storage to begin/end_cpu_access - these functions must also do any required flushing to ensure coherency (besides actually grabbing the backing storage). So I think that's a better name. -Daniel -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Adding YUV input support for OMAP3ISP driver
On 2012-01-20 05:19, Laurent Pinchart wrote: Hi Enrico, On Thursday 19 January 2012 15:17:57 Enrico wrote: On Thu, Jan 19, 2012 at 2:52 PM, Gary Thomasg...@mlbassoc.com wrote: On 2012-01-19 06:35, Gary Thomas wrote: My camera init code is attached. In the previous kernel, the I2C bus was probed implicitly when I initialized the OMAP3ISP. I thought I remembered some discussion about how that worked (maybe changing), so this is probably where the problem starts. If you have an example, I can check my setup against it. Note: I reworked how the sensor+I2C was initialized to be omap3_init_camera(cobra3530p73_isp_platform_data); omap_register_i2c_bus(cobra3530p73_isp_platform_data.subdevs-subdevs[0] .i2c_adapter_id, 400, cobra3530p73_isp_platform_data.subdevs-subdevs[0].board_info, 1); The TVP5150 is now found, but 'media-ctl -p' still dies :-( Have a look at [1] (the linux_3.2.bb file to see the list of patches,inside linux-3.2 directory for the actual patches), it's based on mainline kernel 3.2 and the bt656 patches i submitted months ago, it should be easy to adapt it for you board. rant Really, there are patches for all these problems since months (from me, Javier, TI), but because no maintainer cared (apart from Laurent) they were never reviewed/applied and there is always someone who comes back with all the usual problems (additional yuv format, bt656 mode, tvp5150 that doesn't work...). /rant I totally understand your feeling. I'd like to get YUV support integrated in the OMAP3 ISP driver. However, I have no YUV image source hardware, so I can only review the patches but not test them. If someone can rebase the existing patches on top of http://git.linuxtv.org/pinchartl/media.git/shortlog/refs/heads/omap3isp- omap3isp-yuv and test them, then I'll review the result. The attached patches produce a working setup against Laurent's tree above. That said, I don't recall exactly where which changes came from (I'm old school and not very git savvy, sorry). I've CC'd all the folks I think provided at least part of these changes. Perhaps we can all work together to come up with a proper set of patches which can be pushed upstream for this, once and for all? Thanks -- Gary Thomas | Consulting for the MLB Associates |Embedded world From 2ab6c0c7b481d116c9d7faf120efcff1ef2a732f Mon Sep 17 00:00:00 2001 From: Gary Thomas g...@mlbassoc.com Date: Wed, 25 Jan 2012 07:57:21 -0700 Subject: [PATCH 1/2] Merge working driver for TVP5150 --- drivers/media/video/tvp5150.c | 419 - include/media/tvp5150.h |6 + 2 files changed, 375 insertions(+), 50 deletions(-) diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index 6be9910..a472ebe 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c @@ -5,15 +5,17 @@ * This code is placed under the terms of the GNU General Public License v2 */ +#include linux/module.h #include linux/i2c.h #include linux/slab.h #include linux/videodev2.h #include linux/delay.h -#include linux/module.h #include media/v4l2-device.h #include media/tvp5150.h #include media/v4l2-chip-ident.h #include media/v4l2-ctrls.h +#include media/v4l2-subdev.h +#include media/v4l2-mediabus.h #include tvp5150_reg.h @@ -26,11 +28,79 @@ static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, Debug level (0-2)); +/* enum tvp515x_std - enum for supported standards */ +enum tvp515x_std { + STD_PAL_BDGHIN = 0, + STD_NTSC_MJ, + STD_INVALID +}; + +/** + * struct tvp515x_std_info - Structure to store standard informations + * @width: Line width in pixels + * @height:Number of active lines + * @video_std: Value to write in REG_VIDEO_STD register + * @standard: v4l2 standard structure information + */ +struct tvp515x_std_info { + u8 video_std; + struct v4l2_standard standard; + struct v4l2_mbus_framefmt format; +}; + +/** + * Supported standards - + * + * Currently supports two standards only, need to add support for rest of the + * modes, like SECAM, etc... + */ +static struct tvp515x_std_info tvp515x_std_list[] = { + /* Standard: STD_NTSC_MJ */ + /* Standard: STD_PAL_BDGHIN */ + [STD_PAL_BDGHIN] = { + .video_std = VIDEO_STD_PAL_BDGHIN_BIT, + .standard = { + .index = 1, + .id = V4L2_STD_PAL, + .name = PAL, + .frameperiod = {1, 25}, + .framelines = 625 + }, + .format = { + .width = PAL_NUM_ACTIVE_PIXELS, + .height = PAL_NUM_ACTIVE_LINES, + .code = V4L2_MBUS_FMT_UYVY8_2X8, + .field = V4L2_FIELD_INTERLACED, + .colorspace = V4L2_COLORSPACE_SMPTE170M, + }, + }, + [STD_NTSC_MJ] = { + .video_std = VIDEO_STD_NTSC_MJ_BIT, + .standard = { + .index = 0, + .id = V4L2_STD_NTSC, + .name = NTSC, + .frameperiod = {1001, 3}, + .framelines = 525 + }, + .format = { + .width =
Please tag proof-of-concept patches as RFC
Hi All, There's been a lot of proof-of-concept patch series posted recently. I think it's great, but I would just like to suggest the RFC tag is used in the topic of such patches. I feel this would be helpful not only for Mauro, but for all of us. Thanks! Pawel -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
cron job: media_tree daily build: WARNINGS
This message is generated daily by a cron job that builds media_tree for the kernels and architectures in the list below. Results of the daily build of media_tree: date:Mon Jan 30 19:00:18 CET 2012 git hash:59b30294e14fa6a370fdd2bc2921cca1f977ef16 gcc version: i686-linux-gcc (GCC) 4.6.2 host hardware:x86_64 host os: 3.1-2.slh.1-amd64 linux-git-arm-eabi-enoxys: WARNINGS linux-git-arm-eabi-omap: WARNINGS linux-git-armv5-ixp: WARNINGS linux-git-i686: WARNINGS linux-git-m32r: WARNINGS linux-git-mips: WARNINGS linux-git-powerpc64: WARNINGS linux-git-x86_64: WARNINGS linux-2.6.31.12-i686: WARNINGS linux-2.6.32.6-i686: WARNINGS linux-2.6.33-i686: WARNINGS linux-2.6.34-i686: WARNINGS linux-2.6.35.3-i686: WARNINGS linux-2.6.36-i686: WARNINGS linux-2.6.37-i686: WARNINGS linux-2.6.38.2-i686: WARNINGS linux-2.6.39.1-i686: WARNINGS linux-3.0-i686: WARNINGS linux-3.1-i686: WARNINGS linux-3.2.1-i686: WARNINGS linux-3.3-rc1-i686: WARNINGS linux-2.6.31.12-x86_64: WARNINGS linux-2.6.32.6-x86_64: WARNINGS linux-2.6.33-x86_64: WARNINGS linux-2.6.34-x86_64: WARNINGS linux-2.6.35.3-x86_64: WARNINGS linux-2.6.36-x86_64: WARNINGS linux-2.6.37-x86_64: WARNINGS linux-2.6.38.2-x86_64: WARNINGS linux-2.6.39.1-x86_64: WARNINGS linux-3.0-x86_64: WARNINGS linux-3.1-x86_64: WARNINGS linux-3.2.1-x86_64: WARNINGS linux-3.3-rc1-x86_64: WARNINGS apps: WARNINGS spec-git: WARNINGS sparse: ERRORS Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Monday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Monday.tar.bz2 The V4L-DVB specification from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/media.html -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFCv1 2/4] v4l:vb2: add support for shared buffer (dma_buf)
Hi Daniel, On Sun, Jan 29, 2012 at 02:03:40PM +0100, Daniel Vetter wrote: On Sun, Jan 29, 2012 at 01:03:39PM +0200, Sakari Ailus wrote: Daniel Vetter wrote: On Thu, Jan 26, 2012 at 01:28:16AM +0200, Sakari Ailus wrote: Why you should not hang onto mappings forever? This is currently done by virtually all V4L2 drivers where such mappings are relevant. Not doing so would really kill the performance i.e. it's infeasible. Same goes to (m)any other multimedia devices dealing with buffers containing streaming video data. Because I want dynamic memory managemt simple because everything else does not make sense. I know that in v4l things don't work that way, but in drm they _do_. And if you share tons of buffers with drm drivers and don't follow the rules, the OOM killer will come around and shot at your apps. Because at least in i915 we do slurp in as much memory as we can until the oom killer starts growling, at which point we kick out stuff. I know that current dma_buf isn't there and for many use-cases discussed here we can get away without that complexity. So you actually can just map your dma_buf and never ever let go of that mapping again in many cases. The only reason I'm such a stuborn bastard about all this is that drm/* will do dynamic bo management even with dma_buf sooner or later and you should better know that and why and the implications if you choose to ignore it. And obviously, the generic dma_buf interface needs to be able to support it. I do not think we should completely ignore this issue, but I think we might want to at least postpone the implementation for non-DRM subsystems to an unknown future date. The reason is simply that it's currently unfeasible for various reasons. Sharing large buffers with GPUs (where you might want to manage them independently of the user space) is uncommon; typically you're sharing buffers for viewfinder that tend to be around few megabytes in size and there may be typically up to five of them. Also, we're still far from getting things working in the first place. Let's not complicate them more than we have to. The very reason why we're pre-allocating these large buffers in applications is that you can readily use them when you need them. Consider camera, for example: a common use case is to have a set of 24 MB buffers (for 12 Mp images) prepared while the viewfinder is running. These buffers must be immediately usable when the user presses the shutter button. We don't want to continuously map and unmap buffers in viewfinder either: that adds a significan CPU load for no technical reason whatsoever. Typically viewfinder also involves running software algorithms that consume much of the available CPU time, so adding an unnecessary CPU hog to the picture doesn't sound that enticing. If the performance of memory management can be improved to such an extent it really takes much less than a millisecond or so to perform all the pinning-to-memory, IOMMU mapping and so on systems for 24 MB buffers on regular embedded systems I think I wouldn't have much against doing so. Currently I think we're talking about numbers that are at least 100-fold. If you want to do this to buffers used only in DRM I'm fine with that. A few things: - I do understand that there are use cases where allocate, pin forget works. It's not so much about forgetting it; if the buffers could be considered to be paged out at any point I think almost all users would prefer to perform mlock(2) to them. Buffers allocated since they're needed for streaming, not so much for single use pruposes. There are also very few of those buffers compared to DRM. - I'm perfectly fine if you do this in your special embedded product. Or the entire v4l subsystem, I don't care much about that one, either. It's not so special; this is done on desktop PCs as well and I don't think this is going to change any time soon. But: - I'm fully convinced that all these special purpose single use-case scenarios will show up sooner or later on a more general purpose platform. They already do show on PCs. What PCs have been able to afford and still can is to add extra data copies at any part of the stream processing to overcome any minor technical obstacle for which other more memory bus friendly solutions can be used for. - And as soon as your on a general purpose platform, you _want_ dynamic memory management. V4L2 has been like this for some 10 years, embedded or not. When the performance of memory management improves enough we can reconsider this. I mean the entire reason people are pushing CMA is that preallocating gobs of memory statically really isn't that great an idea ... There's a huge difference allocating things statically and an application deciding what it needs to allocate and when; you don't want to keep the buffers around
[PATCH 05/16] cx18: fix handling of 'radio' module parameter
Fixed handling of 'radio' module parameter from module_param_array to module_param_named to fix these compiler warnings in cx18-driver.c: In function ‘__check_radio’: 113:1: warning: return from incompatible pointer type [enabled by default] At top level: 113:1: warning: initialization from incompatible pointer type [enabled by default] 113:1: warning: (near initialization for ‘__param_arr_radio.num’) [enabled by default] Signed-off-by: Danny Kukawka danny.kuka...@bisect.de --- drivers/media/video/cx18/cx18-driver.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 349bd9c..27b5330 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -110,7 +110,7 @@ static int retry_mmio = 1; int cx18_debug; module_param_array(tuner, int, tuner_c, 0644); -module_param_array(radio, bool, radio_c, 0644); +module_param_named(radio, radio_c, bool, 0644); module_param_array(cardtype, int, cardtype_c, 0644); module_param_string(pal, pal, sizeof(pal), 0644); module_param_string(secam, secam, sizeof(secam), 0644); -- 1.7.7.3 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 02/16] max2165: trival fix for some -Wuninitialized warning
Fix for some -Wuninitialized compiler warnings. Signed-off-by: Danny Kukawka danny.kuka...@bisect.de --- drivers/media/common/tuners/max2165.c |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c index cb2c98f..ba84936 100644 --- a/drivers/media/common/tuners/max2165.c +++ b/drivers/media/common/tuners/max2165.c @@ -168,7 +168,7 @@ int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction) int i; if (0 == divisor) - return -1; + return -EINVAL; q = dividend / divisor; remainder = dividend - q * divisor; @@ -194,10 +194,13 @@ static int max2165_set_rf(struct max2165_priv *priv, u32 freq) u8 tf_ntch; u32 t; u32 quotient, fraction; + int ret; /* Set PLL divider according to RF frequency */ - fixpt_div32(freq / 1000, priv-config-osc_clk * 1000, - quotient, fraction); + ret = fixpt_div32(freq / 1000, priv-config-osc_clk * 1000, +quotient, fraction); + if (ret != 0) + return ret; /* 20-bit fraction */ fraction = 12; -- 1.7.7.3 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 0/4] Add some new camera controls
Hi Sylwester, On Sat, Jan 28, 2012 at 06:01:59PM +0100, Sylwester Nawrocki wrote: On 01/04/2012 10:07 PM, Sakari Ailus wrote: On Fri, Dec 30, 2011 at 12:18:40PM +0100, Sylwester Nawrocki wrote: Thus we would three levels of controls for camera, 1) image source class (lowest possible level), dealing mostly with hardware registers; I intended the image source class for controls which only deal with the a/d conversion itself. Other controls would be elsewhere. There hasn't been a final decision on this yet, but an alternative which has been also discussed is just to call this a low level control class. 2) normal camera controls (V4L2_CID_CAMERA_CLASS) [2]; 3) high level camera controls (for camera software algorithms) ... I'm afraid a little it might be hard to distinguish if some control should belong to 2) or 3), as sensors' logic complexity and advancement varies. I can see two main use cases: 1. V4L2 / V4L2 subdev / MC as the low level API for camera control and 2. Regular V4L2 applications. For most controls it's clear which of the two classes they belong to. Have you any ideas on what the class' name could be ? I thought about V4L2_CTRL_CLASS_HIGH_LEVEL_CAMERA or V4L2_CTRL_CLASS_CAMERA_USER although I'm not too happy with any of them and it seems hard to make up some reasonable name, when we already have V4L2_CTRL_CLASS_CAMERA. I might continue to use the current V4L2_CTRL_CLASS_CAMERA to that --- as far I understand most are quite high level controls. We could create a new class for the low level controls instead. Should the new class be for camera controls only or for any low level controls? I'd perhaps vote for a camera, or even sensor low level class. (I actually call it image source class in the patchset.) Another question is how should we call the class for low level controls which may or may not be implemented in sensor. Digital gain, for example. Although I can see an advantage of logically separating controls which have influence on one or more other (lower level) controls. And separate control class would be helpful in that. The candidates to such control class might be: * V4L2_CID_METERING_MODE, * V4L2_CID_EXPOSURE_BIAS, * V4L2_CID_ISO, * V4L2_CID_WHITE_BALANCE_PRESET, * V4L2_CID_SCENEMODE, * V4L2_CID_WDR, * V4L2_CID_ANTISHAKE, The list looks good to me. Cheers, -- Sakari Ailus e-mail: sakari.ai...@iki.fi jabber/XMPP/Gmail: sai...@retiisi.org.uk -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH][media] s5p-g2d: Add HFLIP and VFLIP support
Hi Laurent, Sylwester and Kamil, Thank you for your comments and suggestions. I will re-send the patch with the following 2 changes: 1. Error checking done only once at the end of the init call. 2. Modification in switch case as suggested by Kamil. Regards Sachin On 30 January 2012 19:09, Kamil Debski k.deb...@samsung.com wrote: Hi Laurent and Sachin, Thanks for the patch and for your comments. From: Laurent Pinchart [mailto:laurent.pinch...@ideasonboard.com] Sent: 30 January 2012 13:12 Hi Sashin, Thanks for the patch. On Monday 30 January 2012 10:58:43 Sachin Kamat wrote: This patch adds support for flipping the image horizontally and vertically. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org --- drivers/media/video/s5p-g2d/g2d-hw.c | 5 +++ drivers/media/video/s5p-g2d/g2d.c | 47 + -- drivers/media/video/s5p-g2d/g2d.h | 3 ++ 3 files changed, 46 insertions(+), 9 deletions(-) [snip] diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c index febaa67..dea9701 100644 --- a/drivers/media/video/s5p-g2d/g2d.c +++ b/drivers/media/video/s5p-g2d/g2d.c @@ -178,6 +178,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) { struct g2d_ctx *ctx = container_of(ctrl-handler, struct g2d_ctx, ctrl_handler); + switch (ctrl-id) { case V4L2_CID_COLORFX: if (ctrl-val == V4L2_COLORFX_NEGATIVE) @@ -185,6 +186,21 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) else ctx-rop = ROP4_COPY; break; + + case V4L2_CID_HFLIP: + if (ctrl-val == 1) + ctx-hflip = 1; + else + ctx-hflip = 0; + break; + + case V4L2_CID_VFLIP: + if (ctrl-val == 1) + ctx-vflip = (1 1); + else + ctx-vflip = 0; + break; I think that case V4L2_CID_HFLIP: ctx-hflip = ctrl-val; break; case V4L2_CID_VFLIP: ctx-vflip = (ctrl-val 1); break; will be sufficient, as flip controls have min=0 and max=1 which makes them safe to use. + default: v4l2_err(ctx-dev-v4l2_dev, unknown control\n); return -EINVAL; @@ -200,11 +216,9 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx) { struct g2d_dev *dev = ctx-dev; - v4l2_ctrl_handler_init(ctx-ctrl_handler, 1); - if (ctx-ctrl_handler.error) { - v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); - return ctx-ctrl_handler.error; - } + v4l2_ctrl_handler_init(ctx-ctrl_handler, 3); + if (ctx-ctrl_handler.error) + goto error; There's not need to verify ctx-ctrl_handler.error after every call to v4l2_ctrl_handler_init() or v4l2_ctrl_new_*(). You can verify it once only after initialization all controls. I agree. v4l2_ctrl_new_std_menu( ctx-ctrl_handler, @@ -214,12 +228,25 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx) ~((1 V4L2_COLORFX_NONE) | (1 V4L2_COLORFX_NEGATIVE)), V4L2_COLORFX_NONE); - if (ctx-ctrl_handler.error) { - v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); - return ctx-ctrl_handler.error; - } + if (ctx-ctrl_handler.error) + goto error; + + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + if (ctx-ctrl_handler.error) + goto error; + + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); As a single register controls hflip and vflip, you should group the two controls in a cluster. I think it doesn't matter in this use case. As register are not written in the g2d_s_ctrl. Because the driver uses multiple context it modifies the appropriate values in its context structure and registers are written when the transaction is run. Also there is no logical connection between horizontal and vertical flip. I think this is the case when using clusters. Here one is independent from another. + if (ctx-ctrl_handler.error) + goto error; return 0; + +error: + v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); + return ctx-ctrl_handler.error; + } static int g2d_open(struct file *file) @@ -564,6 +591,8 @@ static void device_run(void *prv) g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); g2d_set_rop4(dev, ctx-rop); + g2d_set_flip(dev, ctx-hflip | ctx-vflip); + Is this called for every frame, or once at stream start only ? In the later case, this means that hflip and vflip won't be changeable during streaming. Is that on purpose ? if (ctx-in.c_width != ctx-out.c_width ||
[PATCH v2] [media] s5p-g2d: Add HFLIP and VFLIP support
This patch adds support for flipping the image horizontally and vertically. Signed-off-by: Sachin Kamat sachin.ka...@linaro.org --- drivers/media/video/s5p-g2d/g2d-hw.c |5 + drivers/media/video/s5p-g2d/g2d.c| 25 - drivers/media/video/s5p-g2d/g2d.h|3 +++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/drivers/media/video/s5p-g2d/g2d-hw.c b/drivers/media/video/s5p-g2d/g2d-hw.c index 39937cf..5b86cbe 100644 --- a/drivers/media/video/s5p-g2d/g2d-hw.c +++ b/drivers/media/video/s5p-g2d/g2d-hw.c @@ -77,6 +77,11 @@ void g2d_set_rop4(struct g2d_dev *d, u32 r) w(r, ROP4_REG); } +void g2d_set_flip(struct g2d_dev *d, u32 r) +{ + w(r, SRC_MSK_DIRECT_REG); +} + u32 g2d_cmd_stretch(u32 e) { e = 1; diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c index febaa67..185e5b5 100644 --- a/drivers/media/video/s5p-g2d/g2d.c +++ b/drivers/media/video/s5p-g2d/g2d.c @@ -178,6 +178,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) { struct g2d_ctx *ctx = container_of(ctrl-handler, struct g2d_ctx, ctrl_handler); + switch (ctrl-id) { case V4L2_CID_COLORFX: if (ctrl-val == V4L2_COLORFX_NEGATIVE) @@ -185,6 +186,15 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl) else ctx-rop = ROP4_COPY; break; + + case V4L2_CID_HFLIP: + ctx-hflip = ctrl-val; + break; + + case V4L2_CID_VFLIP: + ctx-vflip = (ctrl-val 1); + break; + default: v4l2_err(ctx-dev-v4l2_dev, unknown control\n); return -EINVAL; @@ -200,11 +210,7 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx) { struct g2d_dev *dev = ctx-dev; - v4l2_ctrl_handler_init(ctx-ctrl_handler, 1); - if (ctx-ctrl_handler.error) { - v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); - return ctx-ctrl_handler.error; - } + v4l2_ctrl_handler_init(ctx-ctrl_handler, 3); v4l2_ctrl_new_std_menu( ctx-ctrl_handler, @@ -214,6 +220,13 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx) ~((1 V4L2_COLORFX_NONE) | (1 V4L2_COLORFX_NEGATIVE)), V4L2_COLORFX_NONE); + + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + if (ctx-ctrl_handler.error) { v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n); return ctx-ctrl_handler.error; @@ -564,6 +577,8 @@ static void device_run(void *prv) g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); g2d_set_rop4(dev, ctx-rop); + g2d_set_flip(dev, ctx-hflip | ctx-vflip); + if (ctx-in.c_width != ctx-out.c_width || ctx-in.c_height != ctx-out.c_height) cmd |= g2d_cmd_stretch(1); diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/video/s5p-g2d/g2d.h index 5eae901..b3be3c8 100644 --- a/drivers/media/video/s5p-g2d/g2d.h +++ b/drivers/media/video/s5p-g2d/g2d.h @@ -59,6 +59,8 @@ struct g2d_ctx { struct g2d_frameout; struct v4l2_ctrl_handler ctrl_handler; u32 rop; + u32 hflip; + u32 vflip; }; struct g2d_fmt { @@ -77,6 +79,7 @@ void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a); void g2d_start(struct g2d_dev *d); void g2d_clear_int(struct g2d_dev *d); void g2d_set_rop4(struct g2d_dev *d, u32 r); +void g2d_set_flip(struct g2d_dev *d, u32 r); u32 g2d_cmd_stretch(u32 e); void g2d_set_cmd(struct g2d_dev *d, u32 c); -- 1.7.4.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html