From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> To: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, Russell King <linux@armlinux.org.uk>, linux-omap@vger.kernel.org, Thomas Gleixner <tglx@linutronix.de>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, "Ahmed S. Darwish" <a.darwish@linutronix.de>, Sebastian Andrzej Siewior <bigeasy@linutronix.de> Subject: [PATCH 1/3] video: omap: Remove in_interrupt() usage. Date: Mon, 8 Feb 2021 23:38:08 +0100 [thread overview] Message-ID: <20210208223810.388502-2-bigeasy@linutronix.de> (raw) In-Reply-To: <20210208223810.388502-1-bigeasy@linutronix.de> From: "Ahmed S. Darwish" <a.darwish@linutronix.de> alloc_req() uses in_interrupt() to detect if it is safe to use down(). The usage of in_interrupt() in drivers is phased out and Linus clearly requested that code which changes behaviour depending on context should either be separated or the context be conveyed in an argument passed by the caller, which usually knows the context. The semaphore is used as a counting semaphore, initialized with the number of slots in the request pool minus IRQ_REQ_POOL_SIZE - which are reserved for the in_interrupt() user to ensure that a request is always available. The preemptible user will block on the semphore waiting for a request to become available in case there are no requests available. Replace in_interrupt() with a `can_sleep' argument to indicate if it is safe to block on the sempahore. Cc: linux-omap@vger.kernel.org Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- drivers/video/fbdev/omap/hwa742.c | 42 ++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/video/fbdev/omap/hwa742.c b/drivers/video/fbdev/omap/hwa742.c index cfe63932f8255..b191bef22d984 100644 --- a/drivers/video/fbdev/omap/hwa742.c +++ b/drivers/video/fbdev/omap/hwa742.c @@ -100,6 +100,14 @@ struct { struct hwa742_request req_pool[REQ_POOL_SIZE]; struct list_head pending_req_list; struct list_head free_req_list; + + /* + * @req_lock: protect request slots pool and its tracking lists + * @req_sema: counter; slot allocators from task contexts must + * push it down before acquiring a slot. This + * guarantees that atomic contexts will always have + * a minimum of IRQ_REQ_POOL_SIZE slots available. + */ struct semaphore req_sema; spinlock_t req_lock; @@ -224,13 +232,13 @@ static void disable_tearsync(void) hwa742_write_reg(HWA742_NDP_CTRL, b); } -static inline struct hwa742_request *alloc_req(void) +static inline struct hwa742_request *alloc_req(bool can_sleep) { unsigned long flags; struct hwa742_request *req; int req_flags = 0; - if (!in_interrupt()) + if (can_sleep) down(&hwa742.req_sema); else req_flags = REQ_FROM_IRQ_POOL; @@ -399,8 +407,8 @@ static void send_frame_complete(void *data) hwa742.int_ctrl->enable_plane(OMAPFB_PLANE_GFX, 0); } -#define ADD_PREQ(_x, _y, _w, _h) do { \ - req = alloc_req(); \ +#define ADD_PREQ(_x, _y, _w, _h, can_sleep) do {\ + req = alloc_req(can_sleep); \ req->handler = send_frame_handler; \ req->complete = send_frame_complete; \ req->par.update.x = _x; \ @@ -413,7 +421,8 @@ static void send_frame_complete(void *data) } while(0) static void create_req_list(struct omapfb_update_window *win, - struct list_head *req_head) + struct list_head *req_head, + bool can_sleep) { struct hwa742_request *req; int x = win->x; @@ -427,7 +436,7 @@ static void create_req_list(struct omapfb_update_window *win, color_mode = win->format & OMAPFB_FORMAT_MASK; if (x & 1) { - ADD_PREQ(x, y, 1, height); + ADD_PREQ(x, y, 1, height, can_sleep); width--; x++; flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; @@ -439,19 +448,19 @@ static void create_req_list(struct omapfb_update_window *win, if (xspan * height * 2 > hwa742.max_transmit_size) { yspan = hwa742.max_transmit_size / (xspan * 2); - ADD_PREQ(x, ystart, xspan, yspan); + ADD_PREQ(x, ystart, xspan, yspan, can_sleep); ystart += yspan; yspan = height - yspan; flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; } - ADD_PREQ(x, ystart, xspan, yspan); + ADD_PREQ(x, ystart, xspan, yspan, can_sleep); x += xspan; width -= xspan; flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; } if (width) - ADD_PREQ(x, y, 1, height); + ADD_PREQ(x, y, 1, height, can_sleep); } static void auto_update_complete(void *data) @@ -461,12 +470,12 @@ static void auto_update_complete(void *data) jiffies + HWA742_AUTO_UPDATE_TIME); } -static void hwa742_update_window_auto(struct timer_list *unused) +static void __hwa742_update_window_auto(bool can_sleep) { LIST_HEAD(req_list); struct hwa742_request *last; - create_req_list(&hwa742.auto_update_window, &req_list); + create_req_list(&hwa742.auto_update_window, &req_list, can_sleep); last = list_entry(req_list.prev, struct hwa742_request, entry); last->complete = auto_update_complete; @@ -475,6 +484,11 @@ static void hwa742_update_window_auto(struct timer_list *unused) submit_req_list(&req_list); } +static void hwa742_update_window_auto(struct timer_list *unused) +{ + __hwa742_update_window_auto(false); +} + int hwa742_update_window_async(struct fb_info *fbi, struct omapfb_update_window *win, void (*complete_callback)(void *arg), @@ -497,7 +511,7 @@ int hwa742_update_window_async(struct fb_info *fbi, goto out; } - create_req_list(win, &req_list); + create_req_list(win, &req_list, true); last = list_entry(req_list.prev, struct hwa742_request, entry); last->complete = complete_callback; @@ -544,7 +558,7 @@ static void hwa742_sync(void) struct hwa742_request *req; struct completion comp; - req = alloc_req(); + req = alloc_req(true); req->handler = sync_handler; req->complete = NULL; @@ -599,7 +613,7 @@ static int hwa742_set_update_mode(enum omapfb_update_mode mode) omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_READY); break; case OMAPFB_AUTO_UPDATE: - hwa742_update_window_auto(0); + __hwa742_update_window_auto(true); break; case OMAPFB_UPDATE_DISABLED: break; -- 2.30.0
WARNING: multiple messages have this Message-ID (diff)
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> To: linux-fbdev@vger.kernel.org Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sebastian Andrzej Siewior <bigeasy@linutronix.de>, Russell King <linux@armlinux.org.uk>, dri-devel@lists.freedesktop.org, "Ahmed S. Darwish" <a.darwish@linutronix.de>, Thomas Gleixner <tglx@linutronix.de>, linux-omap@vger.kernel.org Subject: [PATCH 1/3] video: omap: Remove in_interrupt() usage. Date: Mon, 8 Feb 2021 23:38:08 +0100 [thread overview] Message-ID: <20210208223810.388502-2-bigeasy@linutronix.de> (raw) In-Reply-To: <20210208223810.388502-1-bigeasy@linutronix.de> From: "Ahmed S. Darwish" <a.darwish@linutronix.de> alloc_req() uses in_interrupt() to detect if it is safe to use down(). The usage of in_interrupt() in drivers is phased out and Linus clearly requested that code which changes behaviour depending on context should either be separated or the context be conveyed in an argument passed by the caller, which usually knows the context. The semaphore is used as a counting semaphore, initialized with the number of slots in the request pool minus IRQ_REQ_POOL_SIZE - which are reserved for the in_interrupt() user to ensure that a request is always available. The preemptible user will block on the semphore waiting for a request to become available in case there are no requests available. Replace in_interrupt() with a `can_sleep' argument to indicate if it is safe to block on the sempahore. Cc: linux-omap@vger.kernel.org Signed-off-by: Ahmed S. Darwish <a.darwish@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- drivers/video/fbdev/omap/hwa742.c | 42 ++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/video/fbdev/omap/hwa742.c b/drivers/video/fbdev/omap/hwa742.c index cfe63932f8255..b191bef22d984 100644 --- a/drivers/video/fbdev/omap/hwa742.c +++ b/drivers/video/fbdev/omap/hwa742.c @@ -100,6 +100,14 @@ struct { struct hwa742_request req_pool[REQ_POOL_SIZE]; struct list_head pending_req_list; struct list_head free_req_list; + + /* + * @req_lock: protect request slots pool and its tracking lists + * @req_sema: counter; slot allocators from task contexts must + * push it down before acquiring a slot. This + * guarantees that atomic contexts will always have + * a minimum of IRQ_REQ_POOL_SIZE slots available. + */ struct semaphore req_sema; spinlock_t req_lock; @@ -224,13 +232,13 @@ static void disable_tearsync(void) hwa742_write_reg(HWA742_NDP_CTRL, b); } -static inline struct hwa742_request *alloc_req(void) +static inline struct hwa742_request *alloc_req(bool can_sleep) { unsigned long flags; struct hwa742_request *req; int req_flags = 0; - if (!in_interrupt()) + if (can_sleep) down(&hwa742.req_sema); else req_flags = REQ_FROM_IRQ_POOL; @@ -399,8 +407,8 @@ static void send_frame_complete(void *data) hwa742.int_ctrl->enable_plane(OMAPFB_PLANE_GFX, 0); } -#define ADD_PREQ(_x, _y, _w, _h) do { \ - req = alloc_req(); \ +#define ADD_PREQ(_x, _y, _w, _h, can_sleep) do {\ + req = alloc_req(can_sleep); \ req->handler = send_frame_handler; \ req->complete = send_frame_complete; \ req->par.update.x = _x; \ @@ -413,7 +421,8 @@ static void send_frame_complete(void *data) } while(0) static void create_req_list(struct omapfb_update_window *win, - struct list_head *req_head) + struct list_head *req_head, + bool can_sleep) { struct hwa742_request *req; int x = win->x; @@ -427,7 +436,7 @@ static void create_req_list(struct omapfb_update_window *win, color_mode = win->format & OMAPFB_FORMAT_MASK; if (x & 1) { - ADD_PREQ(x, y, 1, height); + ADD_PREQ(x, y, 1, height, can_sleep); width--; x++; flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; @@ -439,19 +448,19 @@ static void create_req_list(struct omapfb_update_window *win, if (xspan * height * 2 > hwa742.max_transmit_size) { yspan = hwa742.max_transmit_size / (xspan * 2); - ADD_PREQ(x, ystart, xspan, yspan); + ADD_PREQ(x, ystart, xspan, yspan, can_sleep); ystart += yspan; yspan = height - yspan; flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; } - ADD_PREQ(x, ystart, xspan, yspan); + ADD_PREQ(x, ystart, xspan, yspan, can_sleep); x += xspan; width -= xspan; flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC; } if (width) - ADD_PREQ(x, y, 1, height); + ADD_PREQ(x, y, 1, height, can_sleep); } static void auto_update_complete(void *data) @@ -461,12 +470,12 @@ static void auto_update_complete(void *data) jiffies + HWA742_AUTO_UPDATE_TIME); } -static void hwa742_update_window_auto(struct timer_list *unused) +static void __hwa742_update_window_auto(bool can_sleep) { LIST_HEAD(req_list); struct hwa742_request *last; - create_req_list(&hwa742.auto_update_window, &req_list); + create_req_list(&hwa742.auto_update_window, &req_list, can_sleep); last = list_entry(req_list.prev, struct hwa742_request, entry); last->complete = auto_update_complete; @@ -475,6 +484,11 @@ static void hwa742_update_window_auto(struct timer_list *unused) submit_req_list(&req_list); } +static void hwa742_update_window_auto(struct timer_list *unused) +{ + __hwa742_update_window_auto(false); +} + int hwa742_update_window_async(struct fb_info *fbi, struct omapfb_update_window *win, void (*complete_callback)(void *arg), @@ -497,7 +511,7 @@ int hwa742_update_window_async(struct fb_info *fbi, goto out; } - create_req_list(win, &req_list); + create_req_list(win, &req_list, true); last = list_entry(req_list.prev, struct hwa742_request, entry); last->complete = complete_callback; @@ -544,7 +558,7 @@ static void hwa742_sync(void) struct hwa742_request *req; struct completion comp; - req = alloc_req(); + req = alloc_req(true); req->handler = sync_handler; req->complete = NULL; @@ -599,7 +613,7 @@ static int hwa742_set_update_mode(enum omapfb_update_mode mode) omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_READY); break; case OMAPFB_AUTO_UPDATE: - hwa742_update_window_auto(0); + __hwa742_update_window_auto(true); break; case OMAPFB_UPDATE_DISABLED: break; -- 2.30.0 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2021-02-08 22:39 UTC|newest] Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-02-08 22:38 [PATCH 0/3] video: Remove in_interrupt() usage Sebastian Andrzej Siewior 2021-02-08 22:38 ` Sebastian Andrzej Siewior 2021-02-08 22:38 ` Sebastian Andrzej Siewior [this message] 2021-02-08 22:38 ` [PATCH 1/3] video: omap: " Sebastian Andrzej Siewior 2021-02-08 22:38 ` [PATCH 2/3] video: omapfb: Remove WARN_ON(in_interrupt()) Sebastian Andrzej Siewior 2021-02-08 22:38 ` Sebastian Andrzej Siewior 2021-02-08 22:38 ` [PATCH 3/3] video: fbdev: amba-clcd: Always use msleep() for waiting Sebastian Andrzej Siewior 2021-02-08 22:38 ` Sebastian Andrzej Siewior 2021-02-16 8:35 ` [PATCH 0/3] video: Remove in_interrupt() usage Sebastian Andrzej Siewior 2021-02-16 8:35 ` Sebastian Andrzej Siewior 2021-02-16 8:43 ` Greg Kroah-Hartman 2021-02-16 8:43 ` Greg Kroah-Hartman 2021-02-16 9:09 ` Daniel Vetter 2021-02-16 9:09 ` Daniel Vetter
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210208223810.388502-2-bigeasy@linutronix.de \ --to=bigeasy@linutronix.de \ --cc=a.darwish@linutronix.de \ --cc=dri-devel@lists.freedesktop.org \ --cc=gregkh@linuxfoundation.org \ --cc=linux-fbdev@vger.kernel.org \ --cc=linux-omap@vger.kernel.org \ --cc=linux@armlinux.org.uk \ --cc=tglx@linutronix.de \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.