Re: [PATCH 2/2] omap:mailbox-provide multiple reader support

2010-07-28 Thread Ohad Ben-Cohen
Hi Hari,

On Wed, Jul 28, 2010 at 1:02 AM, Ohad Ben-Cohen  wrote:
> On Wed, Jul 21, 2010 at 12:41 AM, Hari Kanigeri  wrote:
> > This patch provides mutiple readers support for a mailbox
> > instance.
> >
> > Signed-off-by: Hari Kanigeri 
> > ---
> >  arch/arm/plat-omap/include/plat/mailbox.h |    6 ++-
> >  arch/arm/plat-omap/mailbox.c              |   63 
> > 
> >  2 files changed, 40 insertions(+), 29 deletions(-)
> >
> > diff --git a/arch/arm/plat-omap/include/plat/mailbox.h 
> > b/arch/arm/plat-omap/include/plat/mailbox.h
> > index 0486d64..c8e47d8 100644
> > --- a/arch/arm/plat-omap/include/plat/mailbox.h
> > +++ b/arch/arm/plat-omap/include/plat/mailbox.h
> > @@ -68,13 +68,15 @@ struct omap_mbox {
> >        void                    *priv;
> >
> >        void                    (*err_notify)(void);
> > +       atomic_t                use_count;
> > +       struct blocking_notifier_head   notifier;
> >  };
> >
> >  int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
> >  void omap_mbox_init_seq(struct omap_mbox *);
> >
> > -struct omap_mbox *omap_mbox_get(const char *);
> > -void omap_mbox_put(struct omap_mbox *);
> > +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
>
> In this context, I'd like to change notifier to support adding a
> cookie which will be passed back to the handler function (unmodified,
> in a similar manner to request_irq's void *dev param).

This can be easily achieved with a simple container_of manipulation,
so please disregard my request : your patch is fine as-is. After it is
accepted, it'd be simple to add this context-get-back to dspbridge.

Thanks,
Ohad.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] omap:mailbox-provide multiple reader support

2010-07-27 Thread Ohad Ben-Cohen
Hi Hari,

On Wed, Jul 21, 2010 at 12:41 AM, Hari Kanigeri  wrote:
> This patch provides mutiple readers support for a mailbox
> instance.
>
> Signed-off-by: Hari Kanigeri 
> ---
>  arch/arm/plat-omap/include/plat/mailbox.h |    6 ++-
>  arch/arm/plat-omap/mailbox.c              |   63 
>  2 files changed, 40 insertions(+), 29 deletions(-)
>
> diff --git a/arch/arm/plat-omap/include/plat/mailbox.h 
> b/arch/arm/plat-omap/include/plat/mailbox.h
> index 0486d64..c8e47d8 100644
> --- a/arch/arm/plat-omap/include/plat/mailbox.h
> +++ b/arch/arm/plat-omap/include/plat/mailbox.h
> @@ -68,13 +68,15 @@ struct omap_mbox {
>        void                    *priv;
>
>        void                    (*err_notify)(void);
> +       atomic_t                use_count;
> +       struct blocking_notifier_head   notifier;
>  };
>
>  int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
>  void omap_mbox_init_seq(struct omap_mbox *);
>
> -struct omap_mbox *omap_mbox_get(const char *);
> -void omap_mbox_put(struct omap_mbox *);
> +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);

In this context, I'd like to change notifier to support adding a
cookie which will be passed back to the handler function (unmodified,
in a similar manner to request_irq's void *dev param).

This cookie param will be passed to the mailbox callback whenever a
mailbox event is triggered, and will allow drivers to have multiple
instances: instead of maintaining their state in a global variable
(like bridge is doing today), it will be given back every time a
mailbox event is delivered. For syslink it will also help using the
same mbox callback for different devices (e.g. sysm3, appm3).

The changes should be minor, and shouldn't affect existing notifier
users, here's the diff (untested):

diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 540703b..e740aea 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -51,6 +51,7 @@ struct notifier_block {
int (*notifier_call)(struct notifier_block *, unsigned long, void *);
struct notifier_block *next;
int priority;
+   void *dev_id;
 };

 struct atomic_notifier_head {
diff --git a/kernel/notifier.c b/kernel/notifier.c
index 2488ba7..050fd9b 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -64,6 +64,7 @@ static int notifier_chain_unregister(struct notifier_block **n
  * @nl:Pointer to head of the blocking notifier chain
  * @val:   Value passed unmodified to notifier function
  * @v: Pointer passed unmodified to notifier function
+ * If pointer is NULL, the notifier block's
cookie is passed
  * @nr_to_call:Number of notifier functions to be called. Don't care
  * value of this parameter is -1.
  * @nr_calls:  Records the number of notifications sent. Don't care
@@ -90,6 +91,7 @@ static int __kprobes notifier_call_chain(struct notifier_block
continue;
}
 #endif
+   v = v ? v : nb->dev_id;
ret = nb->notifier_call(nb, val, v);

if (nr_calls)


And the only change in your mbox patch should be:

@@ -149,8 +149,8 @@ static void mbox_rx_work(struct work_struct *work)
   if (unlikely(len != sizeof(msg)))
   pr_err("%s: kfifo_out anomaly detected\n", __func__);

-   blocking_notifier_call_chain(&mq->mbox->notifier, len,
-   (void *)msg);
+               blocking_notifier_call_chain(&mq->mbox->notifier, msg, NULL);
   }
 }

The result should be us getting both the mailbox msg and the original
cookie, which will, in our case, be the context of the relevant
dspbridge or syslink driver.

What do you think ?

Thanks,
Ohad.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] omap:mailbox-provide multiple reader support

2010-07-22 Thread Hari Kanigeri
Fernando,

Thanks for looking at the patch.

On Tue, Jul 20, 2010 at 4:59 PM, Guzman Lugo, Fernando
 wrote:
>
>
> Hi Hari,
>
>>
>> @@ -252,28 +252,30 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
>>               }
>>       }
>>
>> -     ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
>> -                             mbox->name, mbox);
>> -     if (unlikely(ret)) {
>> -             printk(KERN_ERR
>> -                     "failed to register mailbox interrupt:%d\n", ret);
>> -             goto fail_request_irq;
>> -     }
>> +     if (atomic_inc_return(&mbox->use_count) == 1) {
>
> What happen if a thread is preempted by other thread which also uses the same 
> mailbox after doing the atomic_inc?
>
> The second thread also will call atomic_inc_return and in this case the value 
> returned will be 2 and it will not initialize the mbox queues but it will 
> return success status, in this point the second thread  will think it could 
> get the mailbox handle without any issue. However the first thread still can 
> fail and not initialize correctly the mailbox leading second thread to not 
> work properly or crash.
>
> I think all the initialization should be protected and not just the use_count.
>

-- How about changing mboxes_lock from spinlock to mutex and
protecting the initialization code ? I guess then the variables don't
have to be atomic too. please share your thougts.

> Please let me know what you think.
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] omap:mailbox-provide multiple reader support

2010-07-22 Thread Hari Kanigeri
Phil,

Thanks for looking at the patch.


On Wed, Jul 21, 2010 at 4:45 AM,   wrote:
> Apologies - top posting and not quoting properly due to having to use MS's 
> braindead OWA.
>
> It appears that most of the "changes" are simply indentation changes caused 
> by the inclusion of a new inner block here:

-- I don't know if we can say most of the changes are simply
indentation changes.

> +       if (atomic_inc_return(&mbox->use_count) == 1) {
> rather than just using a goto to skip past the unneeded parts. (Hmmm, is it 
> not simply an immediate return now?)
> The goto/return is both more idiomatic in linux, and I'm sure a simpler patch.

-- Sure, I will make the change.

>
> Phil
> 
> From: linux-omap-ow...@vger.kernel.org [linux-omap-ow...@vger.kernel.org] On 
> Behalf Of ext Hari Kanigeri [h-kanige...@ti.com]
> Sent: 21 July 2010 01:41
> To: Linux Omap; Tony Lindgren; Doyu Hiroshi (Nokia-MS/Helsinki)
> Cc: Ohad Ben-Cohen; Hari Kanigeri
> Subject: [PATCH 2/2] omap:mailbox-provide multiple reader support
>
> This patch provides mutiple readers support for a mailbox
> instance.
>
> Signed-off-by: Hari Kanigeri 
> ---
>  arch/arm/plat-omap/include/plat/mailbox.h |    6 ++-
>  arch/arm/plat-omap/mailbox.c              |   63 
>  2 files changed, 40 insertions(+), 29 deletions(-)
>
> diff --git a/arch/arm/plat-omap/include/plat/mailbox.h 
> b/arch/arm/plat-omap/include/plat/mailbox.h
> index 0486d64..c8e47d8 100644
> --- a/arch/arm/plat-omap/include/plat/mailbox.h
> +++ b/arch/arm/plat-omap/include/plat/mailbox.h
> @@ -68,13 +68,15 @@ struct omap_mbox {
>        void                    *priv;
>
>        void                    (*err_notify)(void);
> +       atomic_t                use_count;
> +       struct blocking_notifier_head   notifier;
>  };
>
>  int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
>  void omap_mbox_init_seq(struct omap_mbox *);
>
> -struct omap_mbox *omap_mbox_get(const char *);
> -void omap_mbox_put(struct omap_mbox *);
> +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
> +void omap_mbox_put(struct omap_mbox *, struct notifier_block *nb);
>
>  int omap_mbox_register(struct device *parent, struct omap_mbox *);
>  int omap_mbox_unregister(struct omap_mbox *);
> diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
> index baac315..f9f2af4 100644
> --- a/arch/arm/plat-omap/mailbox.c
> +++ b/arch/arm/plat-omap/mailbox.c
> @@ -149,8 +149,8 @@ static void mbox_rx_work(struct work_struct *work)
>                if (unlikely(len != sizeof(msg)))
>                        pr_err("%s: kfifo_out anomaly detected\n", __func__);
>
> -               if (mq->callback)
> -                       mq->callback((void *)msg);
> +               blocking_notifier_call_chain(&mq->mbox->notifier, len,
> +                                                       (void *)msg);
>        }
>  }
>
> @@ -252,28 +252,30 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
>                }
>        }
>
> -       ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
> -                               mbox->name, mbox);
> -       if (unlikely(ret)) {
> -               printk(KERN_ERR
> -                       "failed to register mailbox interrupt:%d\n", ret);
> -               goto fail_request_irq;
> -       }
> +       if (atomic_inc_return(&mbox->use_count) == 1) {
> +               ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
> +                                       mbox->name, mbox);
> +               if (unlikely(ret)) {
> +                       printk(KERN_ERR "failed to register mailbox 
> interrupt:"
> +                                                               "%d\n", ret);
> +                       goto fail_request_irq;
> +               }
>
> -       mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
> -       if (!mq) {
> -               ret = -ENOMEM;
> -               goto fail_alloc_txq;
> -       }
> -       mbox->txq = mq;
> +               mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
> +               if (!mq) {
> +                       ret = -ENOMEM;
> +                       goto fail_alloc_txq;
> +               }
> +               mbox->txq = mq;
>
> -       mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
> -       if (!mq) {
> -               ret = -ENOMEM;
> -               goto fail_alloc_rxq;
> +               mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
> +               if (!mq) {
> +                       ret = -ENOMEM;
> +                       goto fail_alloc_rxq;
> +               }
> +               mbox->rxq = mq;
> +               mq->mbox = mbox;
>        }
> -       mbox->rxq = mq;
> -
>        return 0;
>
>  fail_alloc_rxq:
> @@ -281,6 +283,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
>  fail_alloc_txq:
>        free_irq(mbox->irq, mbox);
>  fail_request_irq:
> +       atomic_dec(&mbox->use_count);
>        if 

RE: [PATCH 2/2] omap:mailbox-provide multiple reader support

2010-07-21 Thread ext-phil.2.carmody
Apologies - top posting and not quoting properly due to having to use MS's 
braindead OWA.

It appears that most of the "changes" are simply indentation changes caused by 
the inclusion of a new inner block here:
+   if (atomic_inc_return(&mbox->use_count) == 1) {
rather than just using a goto to skip past the unneeded parts. (Hmmm, is it not 
simply an immediate return now?)
The goto/return is both more idiomatic in linux, and I'm sure a simpler patch.

Phil

From: linux-omap-ow...@vger.kernel.org [linux-omap-ow...@vger.kernel.org] On 
Behalf Of ext Hari Kanigeri [h-kanige...@ti.com]
Sent: 21 July 2010 01:41
To: Linux Omap; Tony Lindgren; Doyu Hiroshi (Nokia-MS/Helsinki)
Cc: Ohad Ben-Cohen; Hari Kanigeri
Subject: [PATCH 2/2] omap:mailbox-provide multiple reader support

This patch provides mutiple readers support for a mailbox
instance.

Signed-off-by: Hari Kanigeri 
---
 arch/arm/plat-omap/include/plat/mailbox.h |6 ++-
 arch/arm/plat-omap/mailbox.c  |   63 
 2 files changed, 40 insertions(+), 29 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/mailbox.h 
b/arch/arm/plat-omap/include/plat/mailbox.h
index 0486d64..c8e47d8 100644
--- a/arch/arm/plat-omap/include/plat/mailbox.h
+++ b/arch/arm/plat-omap/include/plat/mailbox.h
@@ -68,13 +68,15 @@ struct omap_mbox {
void*priv;

void(*err_notify)(void);
+   atomic_tuse_count;
+   struct blocking_notifier_head   notifier;
 };

 int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
 void omap_mbox_init_seq(struct omap_mbox *);

-struct omap_mbox *omap_mbox_get(const char *);
-void omap_mbox_put(struct omap_mbox *);
+struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
+void omap_mbox_put(struct omap_mbox *, struct notifier_block *nb);

 int omap_mbox_register(struct device *parent, struct omap_mbox *);
 int omap_mbox_unregister(struct omap_mbox *);
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index baac315..f9f2af4 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -149,8 +149,8 @@ static void mbox_rx_work(struct work_struct *work)
if (unlikely(len != sizeof(msg)))
pr_err("%s: kfifo_out anomaly detected\n", __func__);

-   if (mq->callback)
-   mq->callback((void *)msg);
+   blocking_notifier_call_chain(&mq->mbox->notifier, len,
+   (void *)msg);
}
 }

@@ -252,28 +252,30 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
}
}

-   ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
-   mbox->name, mbox);
-   if (unlikely(ret)) {
-   printk(KERN_ERR
-   "failed to register mailbox interrupt:%d\n", ret);
-   goto fail_request_irq;
-   }
+   if (atomic_inc_return(&mbox->use_count) == 1) {
+   ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
+   mbox->name, mbox);
+   if (unlikely(ret)) {
+   printk(KERN_ERR "failed to register mailbox interrupt:"
+   "%d\n", ret);
+   goto fail_request_irq;
+   }

-   mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
-   if (!mq) {
-   ret = -ENOMEM;
-   goto fail_alloc_txq;
-   }
-   mbox->txq = mq;
+   mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
+   if (!mq) {
+   ret = -ENOMEM;
+   goto fail_alloc_txq;
+   }
+   mbox->txq = mq;

-   mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
-   if (!mq) {
-   ret = -ENOMEM;
-   goto fail_alloc_rxq;
+   mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
+   if (!mq) {
+   ret = -ENOMEM;
+   goto fail_alloc_rxq;
+   }
+   mbox->rxq = mq;
+   mq->mbox = mbox;
}
-   mbox->rxq = mq;
-
return 0;

  fail_alloc_rxq:
@@ -281,6 +283,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
  fail_alloc_txq:
free_irq(mbox->irq, mbox);
  fail_request_irq:
+   atomic_dec(&mbox->use_count);
if (likely(mbox->ops->shutdown)) {
if (atomic_dec_return(&mbox_refcount) == 0)
mbox->ops->shutdown(mbox);
@@ -291,10 +294,12 @@ static int omap_mbox_startup(struct omap_mbox *mbox)

 static void omap_mbox_fini(struct omap_mbox *mbox)
 {
-   mbox_queue_free(mbox->txq);
-   mbox_queue_free(mbox->rxq);

-   free_irq(mbox->irq, mbox);
+   if (atomic_dec_return(&mbox->us

RE: [PATCH 2/2] omap:mailbox-provide multiple reader support

2010-07-20 Thread Guzman Lugo, Fernando


Hi Hari,

> -Original Message-
> From: linux-omap-ow...@vger.kernel.org [mailto:linux-omap-
> ow...@vger.kernel.org] On Behalf Of Kanigeri, Hari
> Sent: Tuesday, July 20, 2010 4:42 PM
> To: Linux Omap; Tony Lindgren; Hiroshi DOYU
> Cc: Ohad Ben-Cohen; Kanigeri, Hari
> Subject: [PATCH 2/2] omap:mailbox-provide multiple reader support
> 
> This patch provides mutiple readers support for a mailbox
> instance.
> 
> Signed-off-by: Hari Kanigeri 
> ---
>  arch/arm/plat-omap/include/plat/mailbox.h |6 ++-
>  arch/arm/plat-omap/mailbox.c  |   63 
> 
>  2 files changed, 40 insertions(+), 29 deletions(-)
> 
> diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-
> omap/include/plat/mailbox.h
> index 0486d64..c8e47d8 100644
> --- a/arch/arm/plat-omap/include/plat/mailbox.h
> +++ b/arch/arm/plat-omap/include/plat/mailbox.h
> @@ -68,13 +68,15 @@ struct omap_mbox {
>   void*priv;
> 
>   void(*err_notify)(void);
> + atomic_tuse_count;
> + struct blocking_notifier_head   notifier;
>  };
> 
>  int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
>  void omap_mbox_init_seq(struct omap_mbox *);
> 
> -struct omap_mbox *omap_mbox_get(const char *);
> -void omap_mbox_put(struct omap_mbox *);
> +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
> +void omap_mbox_put(struct omap_mbox *, struct notifier_block *nb);
> 
>  int omap_mbox_register(struct device *parent, struct omap_mbox *);
>  int omap_mbox_unregister(struct omap_mbox *);
> diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
> index baac315..f9f2af4 100644
> --- a/arch/arm/plat-omap/mailbox.c
> +++ b/arch/arm/plat-omap/mailbox.c
> @@ -149,8 +149,8 @@ static void mbox_rx_work(struct work_struct *work)
>   if (unlikely(len != sizeof(msg)))
>   pr_err("%s: kfifo_out anomaly detected\n", __func__);
> 
> - if (mq->callback)
> - mq->callback((void *)msg);
> + blocking_notifier_call_chain(&mq->mbox->notifier, len,
> + (void *)msg);
>   }
>  }
> 
> @@ -252,28 +252,30 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
>   }
>   }
> 
> - ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
> - mbox->name, mbox);
> - if (unlikely(ret)) {
> - printk(KERN_ERR
> - "failed to register mailbox interrupt:%d\n", ret);
> - goto fail_request_irq;
> - }
> + if (atomic_inc_return(&mbox->use_count) == 1) {

What happen if a thread is preempted by other thread which also uses the same 
mailbox after doing the atomic_inc?

The second thread also will call atomic_inc_return and in this case the value 
returned will be 2 and it will not initialize the mbox queues but it will 
return success status, in this point the second thread  will think it could get 
the mailbox handle without any issue. However the first thread still can fail 
and not initialize correctly the mailbox leading second thread to not work 
properly or crash.

I think all the initialization should be protected and not just the use_count.

Please let me know what you think.


Regards,
Fernando.


> + ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
> + mbox->name, mbox);
> + if (unlikely(ret)) {
> + printk(KERN_ERR "failed to register mailbox interrupt:"
> + "%d\n", ret);
> + goto fail_request_irq;
> + }
> 
> - mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
> - if (!mq) {
> - ret = -ENOMEM;
> - goto fail_alloc_txq;
> - }
> - mbox->txq = mq;
> + mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
> + if (!mq) {
> + ret = -ENOMEM;
> + goto fail_alloc_txq;
> + }
> + mbox->txq = mq;
> 
> - mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
> - if (!mq) {
> - ret = -ENOMEM;
> - goto fail_alloc_rxq;
> + mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
> + if (!mq) {
> + ret = -ENOMEM;
> + goto fail_alloc_rxq;
> + }
> + mbox->rxq = mq;
> + mq->mbox = mbox;
>   }
> - mbox->rxq = mq;
> -
>   return 0;
> 
>   fail_alloc_rxq:
> @@ -281,6 +283,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
>   fail_alloc_txq:
>   free_irq(mbox->irq, mbox);
>   fail_request_irq:
> + atomic_dec(&mbox->use_count);
>   if (likely(mbox->ops->shutdown)) {
>   if (atomic_dec_return(&mbox_refcount) == 0)
>   mbox->ops->shutdown(mbo