Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1350217 > unrolled thread

Re: [PATCH V2 2/2] mailbox: Introduce TI message manager driver

Started byNishanth Menon <nm@ti.com>
First post2016-03-04 14:10 +0100
Last post2016-03-17 01:40 +0100
Articles 9 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [PATCH V2 2/2] mailbox: Introduce TI message manager driver Nishanth Menon <nm@ti.com> - 2016-03-04 14:10 +0100
    Re: [PATCH V2 2/2] mailbox: Introduce TI message manager driver Jassi Brar <jassisinghbrar@gmail.com> - 2016-03-07 19:40 +0100
      Re: [PATCH V2 2/2] mailbox: Introduce TI message manager driver Nishanth Menon <nm@ti.com> - 2016-03-07 20:20 +0100
        Re: [PATCH V2 2/2] mailbox: Introduce TI message manager driver Jassi Brar <jassisinghbrar@gmail.com> - 2016-03-08 08:20 +0100
          Re: [PATCH V2 2/2] mailbox: Introduce TI message manager driver Nishanth Menon <nm@ti.com> - 2016-03-08 15:40 +0100
            Re: [PATCH V2 2/2] mailbox: Introduce TI message manager driver Jassi Brar <jassisinghbrar@gmail.com> - 2016-03-15 06:40 +0100
              Re: [PATCH V2 2/2] mailbox: Introduce TI message manager driver Nishanth Menon <nm@ti.com> - 2016-03-15 18:10 +0100
                Re: [PATCH V2 2/2] mailbox: Introduce TI message manager driver Jassi Brar <jassisinghbrar@gmail.com> - 2016-03-16 06:20 +0100
                  Re: [PATCH V2 2/2] mailbox: Introduce TI message manager driver Nishanth Menon <nm@ti.com> - 2016-03-17 01:40 +0100

#1350217 — Re: [PATCH V2 2/2] mailbox: Introduce TI message manager driver

FromNishanth Menon <nm@ti.com>
Date2016-03-04 14:10 +0100
SubjectRe: [PATCH V2 2/2] mailbox: Introduce TI message manager driver
Message-ID<r8XEv-7hh-17@gated-at.bofh.it>
Hi Jassi,

Thanks for reviewing the patch.
On 03/03/2016 11:18 PM, Jassi Brar wrote:

[...]

>>
>>  drivers/mailbox/Kconfig     |  11 +
>>  drivers/mailbox/Makefile    |   2 +
>>  drivers/mailbox/ti-msgmgr.c | 657

> Do you want to call it something more specific than 'msgmgr from TI'?
> Maybe its about Keystone, like mailbox-keystone.c ?

Here is the rationale for choosing the name:
There are more than 1 IPC in TI SoCs and even within Keystone SoC.
Further, it is indeed called message manager hardware block and used
across multiple SoC families (even though it is originated by keystone
architecture). we do have a reuse of the omap-mailbox in a future
keystone device (in addition to message manager), so using ti-mailbox is
more appropriate for omap-mailbox, but anyways.. further renaming this
as keystone-mailbox will confuse poor users when the new SoC comes in..

We do have a lot of cross pollination of hardware blocks across TI
architectures, and "keystone-" prefix does not really fit the usage.
hence the usage of vendor-hardwareblock name.

> 
> 
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +#include <linux/of.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/ti-msgmgr.h>
>>
> This seems a bit bold. I think  include/linux/soc/ti/ is the right place.

Sure, I can. Since I followed include/linux/omap-mailbox.h, Would you
suggest all files such as include/linux/omap* be moved to
include/linux/soc/ti/ ? I guess that is not pertinent to this specific
patch, but I am curious..


>> +       /* Do I actually have messages to read? */
>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>> +       if (!msg_count) {
>> +               /* Shared IRQ? */
>> +               dev_dbg(dev, "Spurious event - 0 pending data!\n");
>> +               return IRQ_NONE;
>> +       }
>> +
>> +       /*
>> +        * I have no idea about the protocol being used to communicate with the
>> +        * remote producer - 0 could be valid data, so I wont make a judgement
>> +        * of how many bytes I should be reading. Let the client figure this
>> +        * out.. I just read the full message and pass it on..
>> +        */
> Exactly. And similarly when you send data, you should not have more
> than one message in transit. Now please see my note in
> ti_msgmgr_send_data()
> 
> 
>> +static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
>> +{
>> +       struct device *dev = chan->mbox->dev;
>> +       struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
>> +       const struct ti_msgmgr_desc *desc;
>> +       struct ti_queue_inst *qinst = chan->con_priv;
>> +       int msg_count, num_words, trail_bytes;
>> +       struct ti_msgmgr_message *message = data;
>> +       void __iomem *data_reg;
>> +       u32 *word_data;
>> +
>> +       if (WARN_ON(!inst)) {
>> +               dev_err(dev, "no platform drv data??\n");
>> +               return -EINVAL;
>> +       }
>> +       desc = inst->desc;
>> +
>> +       if (desc->max_message_size < message->len) {
>> +               dev_err(dev, "Queue %s message length %d > max %d\n",
>> +                       qinst->name, message->len, desc->max_message_size);
>> +               return -EINVAL;
>> +       }
>> +
>> +       /* Are we able to send this or not? */
>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>> +       if (msg_count >= desc->max_messages) {
>> +               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
>> +                        msg_count);
>> +               return -EBUSY;
>> +       }
> This seems fishy. mailbox api always submit 1 'complete' message to be
> sent and checks for completion by last_tx_done() before calling
> send_data() again. Controller drivers are not supposed to queue
> messages - mailbox core does. So you should never be unable to send a
> message.


OK-> to explain this, few reasons: (queue messages check and usage of
last_tx_done are kind of intertwined answer..
a) we need to remember that the message manager has a shared RAM.
multiple transmitter over other queues can be sharing the same.
unfortunately, we dont get a threshold kind of interrupt or status that
I am able to exploit in the current incarnation of the solution. The
best we can do in the full system is to constrain the number of messages
that are max pending simultaneously in each of the queue from various
transmitters in the SoC.
b) last_tx_done() is checked if TXDONE_BY_POLL, not if TXDONE_BY_ACK
right? which is how this'd work since txdone_poll is false -> that is
how we want this mechanism to work once the far end is ready for next
message, it acks. I do see your point about being tied to protocol - I
dont like it either.. in fact, I'd prefer that client registration
mention what kind of handshaking is necessary, but: a) that is not how
mailbox framework is constructed at the moment(we state txdone_poll at
mailbox registration, not at client usage) and b) I have no real need
for multiple clients to users of message manager who actually need
non-ACK usage - even for the foreseeable future (at least 1 next
generation of SoC) - if such a need does arise in the future, I will
have to rework framework and make this capability at the registration
time of the client - allowing each client path to use different
mechanisms on hardware such as these that need it.
c) message manager can actually queue more than one message(depending on
client capability). Even though, at this point, we are not really
capable of doing it(again from what I can see for immediate future),
mailbox framework by checking last_tx_done forces a single message
sequencing - which is not really exploiting the capability of the
hardware - in theory, we should be able to queue max num messages, hit
cpuidle and snooze away while the remote entity chomp away data at it's
own pace and finally give us a notification back - but again, we can
argue it is indeed protocol dependent, so setting txdone_poll to false
actually enables that to be done in user. Again - i have no immediate
need for any queued multiple transfer needs yet.. even if i need to, in
the future, it can easily be done by the client by maintaining code as
is - txdone_poll is false.

> 
> 
>> +       /*
>> +        * NOTE about register access involved here:
>> +        * the hardware block is implemented with 32bit access operations and no
>> +        * support for data splitting.  We don't want the hardware to misbehave
>> +        * with sub 32bit access - For example: if the last register write is
>> +        * split into byte wise access, it can result in the queue getting
>> +        * stuck or dummy messages being transmitted or indeterminate behavior.
>> +        * The same can occur if out of order operations take place.
>> +        * Hence, we do not use memcpy_toio or ___iowrite32_copy here, instead
>> +        * we use writel which ensures the sequencing we need.
>> +        */
> .... deja-vu ?

Tell me about it.. but then, surprises like these do pop in once in a
while.. sigh..

>> +
>> +/* Keystone K2G SoC integration details */
>> +static const struct ti_msgmgr_valid_queue_desc k2g_valid_queues[] = {
>> +       {.queue_id = 0, .proxy_id = 0, .is_tx = true,},
>> +       {.queue_id = 1, .proxy_id = 0, .is_tx = true,},
>> +       {.queue_id = 2, .proxy_id = 0, .is_tx = true,},
>> +       {.queue_id = 3, .proxy_id = 0, .is_tx = true,},
>> +       {.queue_id = 5, .proxy_id = 2, .is_tx = false,},
>> +       {.queue_id = 56, .proxy_id = 1, .is_tx = true,},
>> +       {.queue_id = 57, .proxy_id = 2, .is_tx = false,},
>> +       {.queue_id = 58, .proxy_id = 3, .is_tx = true,},
>> +       {.queue_id = 59, .proxy_id = 4, .is_tx = true,},
>> +       {.queue_id = 60, .proxy_id = 5, .is_tx = true,},
>> +       {.queue_id = 61, .proxy_id = 6, .is_tx = true,},
>> +};
>> +
>> +static const struct ti_msgmgr_desc k2g_desc = {
>> +       .queue_count = 64,
>> +       .max_message_size = 64,
>> +       .max_messages = 128,
>> +       .q_slices = 1,
>> +       .q_proxies = 1,
>> +       .data_first_reg = 16,
>> +       .data_last_reg = 31,
>> +       .tx_polled = false,
>> +       .valid_queues = k2g_valid_queues,
>> +       .num_valid_queues = ARRAY_SIZE(k2g_valid_queues),
>> +};
> If these parameters are very configurable, maybe they should be in DT?

These are SoC integration specific data. based on DT, we will only have
SoC specific compatible property in DT. Since  the data is tied to SoC
integration, there is no benefit of keeping these in DT.

-- 
Regards,
Nishanth Menon

[toc] | [next] | [standalone]


#1351871

FromJassi Brar <jassisinghbrar@gmail.com>
Date2016-03-07 19:40 +0100
Message-ID<ra8eu-6wg-27@gated-at.bofh.it>
In reply to#1350217
On Fri, Mar 4, 2016 at 8:05 PM, Nishanth Menon <nm@ti.com> wrote:
> Hi Jassi,
>
> Thanks for reviewing the patch.
> On 03/03/2016 11:18 PM, Jassi Brar wrote:
>
> [...]
>
>>>
>>>  drivers/mailbox/Kconfig     |  11 +
>>>  drivers/mailbox/Makefile    |   2 +
>>>  drivers/mailbox/ti-msgmgr.c | 657
>
>> Do you want to call it something more specific than 'msgmgr from TI'?
>> Maybe its about Keystone, like mailbox-keystone.c ?
>
> Here is the rationale for choosing the name:
> There are more than 1 IPC in TI SoCs and even within Keystone SoC.
> Further, it is indeed called message manager hardware block and used
> across multiple SoC families (even though it is originated by keystone
> architecture). we do have a reuse of the omap-mailbox in a future
> keystone device (in addition to message manager), so using ti-mailbox is
> more appropriate for omap-mailbox, but anyways.. further renaming this
> as keystone-mailbox will confuse poor users when the new SoC comes in..
>
> We do have a lot of cross pollination of hardware blocks across TI
> architectures, and "keystone-" prefix does not really fit the usage.
> hence the usage of vendor-hardwareblock name.
>
OK, I leave that to you to call it whatever you think is right.

>>
>>> +#include <linux/module.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/of.h>
>>> +#include <linux/of_irq.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/ti-msgmgr.h>
>>>
>> This seems a bit bold. I think  include/linux/soc/ti/ is the right place.
>
> Sure, I can. Since I followed c, Would you
> suggest all files such as include/linux/omap* be moved to
> include/linux/soc/ti/ ? I guess that is not pertinent to this specific
> patch, but I am curious..
>
include/linux/omap-mailbox.h predates mailbox api.
But yes, I do think include/linux is not the right place for platform
specific headers. include/linux/soc/ is.

>
>>> +       /* Do I actually have messages to read? */
>>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>>> +       if (!msg_count) {
>>> +               /* Shared IRQ? */
>>> +               dev_dbg(dev, "Spurious event - 0 pending data!\n");
>>> +               return IRQ_NONE;
>>> +       }
>>> +
>>> +       /*
>>> +        * I have no idea about the protocol being used to communicate with the
>>> +        * remote producer - 0 could be valid data, so I wont make a judgement
>>> +        * of how many bytes I should be reading. Let the client figure this
>>> +        * out.. I just read the full message and pass it on..
>>> +        */
>> Exactly. And similarly when you send data, you should not have more
>> than one message in transit. Now please see my note in
>> ti_msgmgr_send_data()
>>
>>
>>> +static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
>>> +{
>>> +       struct device *dev = chan->mbox->dev;
>>> +       struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
>>> +       const struct ti_msgmgr_desc *desc;
>>> +       struct ti_queue_inst *qinst = chan->con_priv;
>>> +       int msg_count, num_words, trail_bytes;
>>> +       struct ti_msgmgr_message *message = data;
>>> +       void __iomem *data_reg;
>>> +       u32 *word_data;
>>> +
>>> +       if (WARN_ON(!inst)) {
>>> +               dev_err(dev, "no platform drv data??\n");
>>> +               return -EINVAL;
>>> +       }
>>> +       desc = inst->desc;
>>> +
>>> +       if (desc->max_message_size < message->len) {
>>> +               dev_err(dev, "Queue %s message length %d > max %d\n",
>>> +                       qinst->name, message->len, desc->max_message_size);
>>> +               return -EINVAL;
>>> +       }
>>> +
>>> +       /* Are we able to send this or not? */
>>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>>> +       if (msg_count >= desc->max_messages) {
>>> +               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
>>> +                        msg_count);
>>> +               return -EBUSY;
>>> +       }
>> This seems fishy. mailbox api always submit 1 'complete' message to be
>> sent and checks for completion by last_tx_done() before calling
>> send_data() again. Controller drivers are not supposed to queue
>> messages - mailbox core does. So you should never be unable to send a
>> message.
>
>
> OK-> to explain this, few reasons: (queue messages check and usage of
> last_tx_done are kind of intertwined answer..
> a) we need to remember that the message manager has a shared RAM.
> multiple transmitter over other queues can be sharing the same.
> unfortunately, we dont get a threshold kind of interrupt or status that
> I am able to exploit in the current incarnation of the solution. The
> best we can do in the full system is to constrain the number of messages
> that are max pending simultaneously in each of the queue from various
> transmitters in the SoC.
> b) last_tx_done() is checked if TXDONE_BY_POLL, not if TXDONE_BY_ACK
> right? which is how this'd work since txdone_poll is false -> that is
> how we want this mechanism to work once the far end is ready for next
> message, it acks. I do see your point about being tied to protocol - I
> dont like it either.. in fact, I'd prefer that client registration
> mention what kind of handshaking is necessary, but: a) that is not how
> mailbox framework is constructed at the moment(we state txdone_poll at
> mailbox registration, not at client usage) and b) I have no real need
> for multiple clients to users of message manager who actually need
> non-ACK usage - even for the foreseeable future (at least 1 next
> generation of SoC) - if such a need does arise in the future, I will
> have to rework framework and make this capability at the registration
> time of the client - allowing each client path to use different
> mechanisms on hardware such as these that need it.
> c) message manager can actually queue more than one message(depending on
> client capability). Even though, at this point, we are not really
> capable of doing it(again from what I can see for immediate future),
> mailbox framework by checking last_tx_done forces a single message
> sequencing - which is not really exploiting the capability of the
> hardware - in theory, we should be able to queue max num messages, hit
> cpuidle and snooze away while the remote entity chomp away data at it's
> own pace and finally give us a notification back - but again, we can
> argue it is indeed protocol dependent, so setting txdone_poll to false
> actually enables that to be done in user. Again - i have no immediate
> need for any queued multiple transfer needs yet.. even if i need to, in
> the future, it can easily be done by the client by maintaining code as
> is - txdone_poll is false.
>
All I suggest is that the controller does not queue more than 1
message at a time, which means the controller driver allows for
maximum possible resources taken by a message.
The buffering is already done by the core, and if for your 'batch
dispatch' thing the client could simply flush them to remote by
pretending it got the ack (which is no worse than simply sending all
messages to remote without caring if the first was successful or not).


>>
>>> +       /*
>>> +        * NOTE about register access involved here:
>>> +        * the hardware block is implemented with 32bit access operations and no
>>> +        * support for data splitting.  We don't want the hardware to misbehave
>>> +        * with sub 32bit access - For example: if the last register write is
>>> +        * split into byte wise access, it can result in the queue getting
>>> +        * stuck or dummy messages being transmitted or indeterminate behavior.
>>> +        * The same can occur if out of order operations take place.
>>> +        * Hence, we do not use memcpy_toio or ___iowrite32_copy here, instead
>>> +        * we use writel which ensures the sequencing we need.
>>> +        */
>> .... deja-vu ?
>
> Tell me about it.. but then, surprises like these do pop in once in a
> while.. sigh..
>
I meant you have same para for read() , so maybe omit this one.

>>> +
>>> +/* Keystone K2G SoC integration details */
>>> +static const struct ti_msgmgr_valid_queue_desc k2g_valid_queues[] = {
>>> +       {.queue_id = 0, .proxy_id = 0, .is_tx = true,},
>>> +       {.queue_id = 1, .proxy_id = 0, .is_tx = true,},
>>> +       {.queue_id = 2, .proxy_id = 0, .is_tx = true,},
>>> +       {.queue_id = 3, .proxy_id = 0, .is_tx = true,},
>>> +       {.queue_id = 5, .proxy_id = 2, .is_tx = false,},
>>> +       {.queue_id = 56, .proxy_id = 1, .is_tx = true,},
>>> +       {.queue_id = 57, .proxy_id = 2, .is_tx = false,},
>>> +       {.queue_id = 58, .proxy_id = 3, .is_tx = true,},
>>> +       {.queue_id = 59, .proxy_id = 4, .is_tx = true,},
>>> +       {.queue_id = 60, .proxy_id = 5, .is_tx = true,},
>>> +       {.queue_id = 61, .proxy_id = 6, .is_tx = true,},
>>> +};
>>> +
>>> +static const struct ti_msgmgr_desc k2g_desc = {
>>> +       .queue_count = 64,
>>> +       .max_message_size = 64,
>>> +       .max_messages = 128,
>>> +       .q_slices = 1,
>>> +       .q_proxies = 1,
>>> +       .data_first_reg = 16,
>>> +       .data_last_reg = 31,
>>> +       .tx_polled = false,
>>> +       .valid_queues = k2g_valid_queues,
>>> +       .num_valid_queues = ARRAY_SIZE(k2g_valid_queues),
>>> +};
>> If these parameters are very configurable, maybe they should be in DT?
>
> These are SoC integration specific data. based on DT, we will only have
> SoC specific compatible property in DT. Since  the data is tied to SoC
> integration, there is no benefit of keeping these in DT.
>
Well, yes if the numbers don't change with very often.

Thanks.

[toc] | [prev] | [next] | [standalone]


#1351898

FromNishanth Menon <nm@ti.com>
Date2016-03-07 20:20 +0100
Message-ID<ra8Rb-702-3@gated-at.bofh.it>
In reply to#1351871
On 03/07/2016 12:31 PM, Jassi Brar wrote:
> On Fri, Mar 4, 2016 at 8:05 PM, Nishanth Menon <nm@ti.com> wrote:
>> Hi Jassi,
>>
>> Thanks for reviewing the patch.
>> On 03/03/2016 11:18 PM, Jassi Brar wrote:
>>
>> [...]
>>
>>>>
>>>>  drivers/mailbox/Kconfig     |  11 +
>>>>  drivers/mailbox/Makefile    |   2 +
>>>>  drivers/mailbox/ti-msgmgr.c | 657
>>
>>> Do you want to call it something more specific than 'msgmgr from TI'?
>>> Maybe its about Keystone, like mailbox-keystone.c ?
>>
>> Here is the rationale for choosing the name:
>> There are more than 1 IPC in TI SoCs and even within Keystone SoC.
>> Further, it is indeed called message manager hardware block and used
>> across multiple SoC families (even though it is originated by keystone
>> architecture). we do have a reuse of the omap-mailbox in a future
>> keystone device (in addition to message manager), so using ti-mailbox is
>> more appropriate for omap-mailbox, but anyways.. further renaming this
>> as keystone-mailbox will confuse poor users when the new SoC comes in..
>>
>> We do have a lot of cross pollination of hardware blocks across TI
>> architectures, and "keystone-" prefix does not really fit the usage.
>> hence the usage of vendor-hardwareblock name.
>>
> OK, I leave that to you to call it whatever you think is right.

thanks.

> 
>>>
>>>> +#include <linux/module.h>
>>>> +#include <linux/of_device.h>
>>>> +#include <linux/of.h>
>>>> +#include <linux/of_irq.h>
>>>> +#include <linux/platform_device.h>
>>>> +#include <linux/ti-msgmgr.h>
>>>>
>>> This seems a bit bold. I think  include/linux/soc/ti/ is the right place.
>>
>> Sure, I can. Since I followed c, Would you
>> suggest all files such as include/linux/omap* be moved to
>> include/linux/soc/ti/ ? I guess that is not pertinent to this specific
>> patch, but I am curious..
>>
> include/linux/omap-mailbox.h predates mailbox api.
> But yes, I do think include/linux is not the right place for platform
> specific headers. include/linux/soc/ is.

Will  fix this.

>>
>>>> +       /* Do I actually have messages to read? */
>>>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>>>> +       if (!msg_count) {
>>>> +               /* Shared IRQ? */
>>>> +               dev_dbg(dev, "Spurious event - 0 pending data!\n");
>>>> +               return IRQ_NONE;
>>>> +       }
>>>> +
>>>> +       /*
>>>> +        * I have no idea about the protocol being used to communicate with the
>>>> +        * remote producer - 0 could be valid data, so I wont make a judgement
>>>> +        * of how many bytes I should be reading. Let the client figure this
>>>> +        * out.. I just read the full message and pass it on..
>>>> +        */
>>> Exactly. And similarly when you send data, you should not have more
>>> than one message in transit. Now please see my note in
>>> ti_msgmgr_send_data()
>>>
>>>
>>>> +static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
>>>> +{
>>>> +       struct device *dev = chan->mbox->dev;
>>>> +       struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
>>>> +       const struct ti_msgmgr_desc *desc;
>>>> +       struct ti_queue_inst *qinst = chan->con_priv;
>>>> +       int msg_count, num_words, trail_bytes;
>>>> +       struct ti_msgmgr_message *message = data;
>>>> +       void __iomem *data_reg;
>>>> +       u32 *word_data;
>>>> +
>>>> +       if (WARN_ON(!inst)) {
>>>> +               dev_err(dev, "no platform drv data??\n");
>>>> +               return -EINVAL;
>>>> +       }
>>>> +       desc = inst->desc;
>>>> +
>>>> +       if (desc->max_message_size < message->len) {
>>>> +               dev_err(dev, "Queue %s message length %d > max %d\n",
>>>> +                       qinst->name, message->len, desc->max_message_size);
>>>> +               return -EINVAL;
>>>> +       }
>>>> +
>>>> +       /* Are we able to send this or not? */
>>>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>>>> +       if (msg_count >= desc->max_messages) {
>>>> +               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
>>>> +                        msg_count);
>>>> +               return -EBUSY;
>>>> +       }
>>> This seems fishy. mailbox api always submit 1 'complete' message to be
>>> sent and checks for completion by last_tx_done() before calling
>>> send_data() again. Controller drivers are not supposed to queue
>>> messages - mailbox core does. So you should never be unable to send a
>>> message.
>>
>>
>> OK-> to explain this, few reasons: (queue messages check and usage of
>> last_tx_done are kind of intertwined answer..
>> a) we need to remember that the message manager has a shared RAM.
>> multiple transmitter over other queues can be sharing the same.
>> unfortunately, we dont get a threshold kind of interrupt or status that
>> I am able to exploit in the current incarnation of the solution. The
>> best we can do in the full system is to constrain the number of messages
>> that are max pending simultaneously in each of the queue from various
>> transmitters in the SoC.
>> b) last_tx_done() is checked if TXDONE_BY_POLL, not if TXDONE_BY_ACK
>> right? which is how this'd work since txdone_poll is false -> that is
>> how we want this mechanism to work once the far end is ready for next
>> message, it acks. I do see your point about being tied to protocol - I
>> dont like it either.. in fact, I'd prefer that client registration
>> mention what kind of handshaking is necessary, but: a) that is not how
>> mailbox framework is constructed at the moment(we state txdone_poll at
>> mailbox registration, not at client usage) and b) I have no real need
>> for multiple clients to users of message manager who actually need
>> non-ACK usage - even for the foreseeable future (at least 1 next
>> generation of SoC) - if such a need does arise in the future, I will
>> have to rework framework and make this capability at the registration
>> time of the client - allowing each client path to use different
>> mechanisms on hardware such as these that need it.
>> c) message manager can actually queue more than one message(depending on
>> client capability). Even though, at this point, we are not really
>> capable of doing it(again from what I can see for immediate future),
>> mailbox framework by checking last_tx_done forces a single message
>> sequencing - which is not really exploiting the capability of the
>> hardware - in theory, we should be able to queue max num messages, hit
>> cpuidle and snooze away while the remote entity chomp away data at it's
>> own pace and finally give us a notification back - but again, we can
>> argue it is indeed protocol dependent, so setting txdone_poll to false
>> actually enables that to be done in user. Again - i have no immediate
>> need for any queued multiple transfer needs yet.. even if i need to, in
>> the future, it can easily be done by the client by maintaining code as
>> is - txdone_poll is false.
>>
> All I suggest is that the controller does not queue more than 1
> message at a time, which means the controller driver allows for
> maximum possible resources taken by a message.
> The buffering is already done by the core, and if for your 'batch
> dispatch' thing the client could simply flush them to remote by
> pretending it got the ack (which is no worse than simply sending all
> messages to remote without caring if the first was successful or not).

Are you suggesting to set txdone_poll is true? the controller is quite
capable of queueing more than 1 message at a time. This the reason for
letting the client choose the mode of operation - use ack mechanism for
operation. client can choose to ignore the buffering in the controller,
as you mentioned, but then, why force txdone_poll to true and deny the
usage of the queue capability of the hardware?

>>>> +       /*
>>>> +        * NOTE about register access involved here:
>>>> +        * the hardware block is implemented with 32bit access operations and no
>>>> +        * support for data splitting.  We don't want the hardware to misbehave
>>>> +        * with sub 32bit access - For example: if the last register write is
>>>> +        * split into byte wise access, it can result in the queue getting
>>>> +        * stuck or dummy messages being transmitted or indeterminate behavior.
>>>> +        * The same can occur if out of order operations take place.
>>>> +        * Hence, we do not use memcpy_toio or ___iowrite32_copy here, instead
>>>> +        * we use writel which ensures the sequencing we need.
>>>> +        */
>>> .... deja-vu ?
>>
>> Tell me about it.. but then, surprises like these do pop in once in a
>> while.. sigh..
>>
> I meant you have same para for read() , so maybe omit this one.

Aaah.. OK. i will add something trivial as "similar constraints as read"..

>>>> +
>>>> +/* Keystone K2G SoC integration details */
>>>> +static const struct ti_msgmgr_valid_queue_desc k2g_valid_queues[] = {
>>>> +       {.queue_id = 0, .proxy_id = 0, .is_tx = true,},
>>>> +       {.queue_id = 1, .proxy_id = 0, .is_tx = true,},
>>>> +       {.queue_id = 2, .proxy_id = 0, .is_tx = true,},
>>>> +       {.queue_id = 3, .proxy_id = 0, .is_tx = true,},
>>>> +       {.queue_id = 5, .proxy_id = 2, .is_tx = false,},
>>>> +       {.queue_id = 56, .proxy_id = 1, .is_tx = true,},
>>>> +       {.queue_id = 57, .proxy_id = 2, .is_tx = false,},
>>>> +       {.queue_id = 58, .proxy_id = 3, .is_tx = true,},
>>>> +       {.queue_id = 59, .proxy_id = 4, .is_tx = true,},
>>>> +       {.queue_id = 60, .proxy_id = 5, .is_tx = true,},
>>>> +       {.queue_id = 61, .proxy_id = 6, .is_tx = true,},
>>>> +};
>>>> +
>>>> +static const struct ti_msgmgr_desc k2g_desc = {
>>>> +       .queue_count = 64,
>>>> +       .max_message_size = 64,
>>>> +       .max_messages = 128,
>>>> +       .q_slices = 1,
>>>> +       .q_proxies = 1,
>>>> +       .data_first_reg = 16,
>>>> +       .data_last_reg = 31,
>>>> +       .tx_polled = false,
>>>> +       .valid_queues = k2g_valid_queues,
>>>> +       .num_valid_queues = ARRAY_SIZE(k2g_valid_queues),
>>>> +};
>>> If these parameters are very configurable, maybe they should be in DT?
>>
>> These are SoC integration specific data. based on DT, we will only have
>> SoC specific compatible property in DT. Since  the data is tied to SoC
>> integration, there is no benefit of keeping these in DT.
>>
> Well, yes if the numbers don't change with very often.

Hopefully not.

-- 
Regards,
Nishanth Menon

[toc] | [prev] | [next] | [standalone]


#1352680

FromJassi Brar <jassisinghbrar@gmail.com>
Date2016-03-08 08:20 +0100
Message-ID<rak5Y-679-5@gated-at.bofh.it>
In reply to#1351898
On Tue, Mar 8, 2016 at 2:18 AM, Nishanth Menon <nm@ti.com> wrote:
> On 03/07/2016 12:31 PM, Jassi Brar wrote:
>> On Fri, Mar 4, 2016 at 8:05 PM, Nishanth Menon <nm@ti.com> wrote:
>>>>
>>>>> +static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
>>>>> +{
>>>>> +       struct device *dev = chan->mbox->dev;
>>>>> +       struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
>>>>> +       const struct ti_msgmgr_desc *desc;
>>>>> +       struct ti_queue_inst *qinst = chan->con_priv;
>>>>> +       int msg_count, num_words, trail_bytes;
>>>>> +       struct ti_msgmgr_message *message = data;
>>>>> +       void __iomem *data_reg;
>>>>> +       u32 *word_data;
>>>>> +
>>>>> +       if (WARN_ON(!inst)) {
>>>>> +               dev_err(dev, "no platform drv data??\n");
>>>>> +               return -EINVAL;
>>>>> +       }
>>>>> +       desc = inst->desc;
>>>>> +
>>>>> +       if (desc->max_message_size < message->len) {
>>>>> +               dev_err(dev, "Queue %s message length %d > max %d\n",
>>>>> +                       qinst->name, message->len, desc->max_message_size);
>>>>> +               return -EINVAL;
>>>>> +       }
>>>>> +
>>>>> +       /* Are we able to send this or not? */
>>>>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>>>>> +       if (msg_count >= desc->max_messages) {
>>>>> +               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
>>>>> +                        msg_count);
>>>>> +               return -EBUSY;
>>>>> +       }
>>>> This seems fishy. mailbox api always submit 1 'complete' message to be
>>>> sent and checks for completion by last_tx_done() before calling
>>>> send_data() again. Controller drivers are not supposed to queue
>>>> messages - mailbox core does. So you should never be unable to send a
>>>> message.
>>>
>>>
>>> OK-> to explain this, few reasons: (queue messages check and usage of
>>> last_tx_done are kind of intertwined answer..
>>> a) we need to remember that the message manager has a shared RAM.
>>> multiple transmitter over other queues can be sharing the same.
>>> unfortunately, we dont get a threshold kind of interrupt or status that
>>> I am able to exploit in the current incarnation of the solution. The
>>> best we can do in the full system is to constrain the number of messages
>>> that are max pending simultaneously in each of the queue from various
>>> transmitters in the SoC.
>>> b) last_tx_done() is checked if TXDONE_BY_POLL, not if TXDONE_BY_ACK
>>> right? which is how this'd work since txdone_poll is false -> that is
>>> how we want this mechanism to work once the far end is ready for next
>>> message, it acks. I do see your point about being tied to protocol - I
>>> dont like it either.. in fact, I'd prefer that client registration
>>> mention what kind of handshaking is necessary, but: a) that is not how
>>> mailbox framework is constructed at the moment(we state txdone_poll at
>>> mailbox registration, not at client usage) and b) I have no real need
>>> for multiple clients to users of message manager who actually need
>>> non-ACK usage - even for the foreseeable future (at least 1 next
>>> generation of SoC) - if such a need does arise in the future, I will
>>> have to rework framework and make this capability at the registration
>>> time of the client - allowing each client path to use different
>>> mechanisms on hardware such as these that need it.
>>> c) message manager can actually queue more than one message(depending on
>>> client capability). Even though, at this point, we are not really
>>> capable of doing it(again from what I can see for immediate future),
>>> mailbox framework by checking last_tx_done forces a single message
>>> sequencing - which is not really exploiting the capability of the
>>> hardware - in theory, we should be able to queue max num messages, hit
>>> cpuidle and snooze away while the remote entity chomp away data at it's
>>> own pace and finally give us a notification back - but again, we can
>>> argue it is indeed protocol dependent, so setting txdone_poll to false
>>> actually enables that to be done in user. Again - i have no immediate
>>> need for any queued multiple transfer needs yet.. even if i need to, in
>>> the future, it can easily be done by the client by maintaining code as
>>> is - txdone_poll is false.
>>>
>> All I suggest is that the controller does not queue more than 1
>> message at a time, which means the controller driver allows for
>> maximum possible resources taken by a message.
>> The buffering is already done by the core, and if for your 'batch
>> dispatch' thing the client could simply flush them to remote by
>> pretending it got the ack (which is no worse than simply sending all
>> messages to remote without caring if the first was successful or not).
>
> Are you suggesting to set txdone_poll is true?
No.

> the controller is quite
> capable of queueing more than 1 message at a time. This the reason for
> letting the client choose the mode of operation - use ack mechanism for
> operation. client can choose to ignore the buffering in the controller,
> as you mentioned, but then, why force txdone_poll to true and deny the
> usage of the queue capability of the hardware?
>
irq/poll/ack whatever you use, there is no valid reason to buffer
messages in the controller driver. Please let me know what usecase you
have in mind that must have messages buffered in controller driver and
not core.

Thanks.

[toc] | [prev] | [next] | [standalone]


#1353104

FromNishanth Menon <nm@ti.com>
Date2016-03-08 15:40 +0100
Message-ID<raqXM-25J-17@gated-at.bofh.it>
In reply to#1352680
Jassi,

On Tue, Mar 8, 2016 at 1:10 AM, Jassi Brar <jassisinghbrar@gmail.com> wrote:
> On Tue, Mar 8, 2016 at 2:18 AM, Nishanth Menon <nm@ti.com> wrote:
>> On 03/07/2016 12:31 PM, Jassi Brar wrote:
>>> On Fri, Mar 4, 2016 at 8:05 PM, Nishanth Menon <nm@ti.com> wrote:
>>>>>
>>>>>> +static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
>>>>>> +{
>>>>>> +       struct device *dev = chan->mbox->dev;
>>>>>> +       struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
>>>>>> +       const struct ti_msgmgr_desc *desc;
>>>>>> +       struct ti_queue_inst *qinst = chan->con_priv;
>>>>>> +       int msg_count, num_words, trail_bytes;
>>>>>> +       struct ti_msgmgr_message *message = data;
>>>>>> +       void __iomem *data_reg;
>>>>>> +       u32 *word_data;
>>>>>> +
>>>>>> +       if (WARN_ON(!inst)) {
>>>>>> +               dev_err(dev, "no platform drv data??\n");
>>>>>> +               return -EINVAL;
>>>>>> +       }
>>>>>> +       desc = inst->desc;
>>>>>> +
>>>>>> +       if (desc->max_message_size < message->len) {
>>>>>> +               dev_err(dev, "Queue %s message length %d > max %d\n",
>>>>>> +                       qinst->name, message->len, desc->max_message_size);
>>>>>> +               return -EINVAL;
>>>>>> +       }
>>>>>> +
>>>>>> +       /* Are we able to send this or not? */
>>>>>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>>>>>> +       if (msg_count >= desc->max_messages) {
>>>>>> +               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
>>>>>> +                        msg_count);
>>>>>> +               return -EBUSY;
>>>>>> +       }
>>>>> This seems fishy. mailbox api always submit 1 'complete' message to be
>>>>> sent and checks for completion by last_tx_done() before calling
>>>>> send_data() again. Controller drivers are not supposed to queue
>>>>> messages - mailbox core does. So you should never be unable to send a
>>>>> message.
>>>>
>>>>
>>>> OK-> to explain this, few reasons: (queue messages check and usage of
>>>> last_tx_done are kind of intertwined answer..
>>>> a) we need to remember that the message manager has a shared RAM.
>>>> multiple transmitter over other queues can be sharing the same.
>>>> unfortunately, we dont get a threshold kind of interrupt or status that
>>>> I am able to exploit in the current incarnation of the solution. The
>>>> best we can do in the full system is to constrain the number of messages
>>>> that are max pending simultaneously in each of the queue from various
>>>> transmitters in the SoC.
>>>> b) last_tx_done() is checked if TXDONE_BY_POLL, not if TXDONE_BY_ACK
>>>> right? which is how this'd work since txdone_poll is false -> that is
>>>> how we want this mechanism to work once the far end is ready for next
>>>> message, it acks. I do see your point about being tied to protocol - I
>>>> dont like it either.. in fact, I'd prefer that client registration
>>>> mention what kind of handshaking is necessary, but: a) that is not how
>>>> mailbox framework is constructed at the moment(we state txdone_poll at
>>>> mailbox registration, not at client usage) and b) I have no real need
>>>> for multiple clients to users of message manager who actually need
>>>> non-ACK usage - even for the foreseeable future (at least 1 next
>>>> generation of SoC) - if such a need does arise in the future, I will
>>>> have to rework framework and make this capability at the registration
>>>> time of the client - allowing each client path to use different
>>>> mechanisms on hardware such as these that need it.
>>>> c) message manager can actually queue more than one message(depending on
>>>> client capability). Even though, at this point, we are not really
>>>> capable of doing it(again from what I can see for immediate future),
>>>> mailbox framework by checking last_tx_done forces a single message
>>>> sequencing - which is not really exploiting the capability of the
>>>> hardware - in theory, we should be able to queue max num messages, hit
>>>> cpuidle and snooze away while the remote entity chomp away data at it's
>>>> own pace and finally give us a notification back - but again, we can
>>>> argue it is indeed protocol dependent, so setting txdone_poll to false
>>>> actually enables that to be done in user. Again - i have no immediate
>>>> need for any queued multiple transfer needs yet.. even if i need to, in
>>>> the future, it can easily be done by the client by maintaining code as
>>>> is - txdone_poll is false.
>>>>
>>> All I suggest is that the controller does not queue more than 1
>>> message at a time, which means the controller driver allows for
>>> maximum possible resources taken by a message.
>>> The buffering is already done by the core, and if for your 'batch
>>> dispatch' thing the client could simply flush them to remote by
>>> pretending it got the ack (which is no worse than simply sending all
>>> messages to remote without caring if the first was successful or not).
>>
>> Are you suggesting to set txdone_poll is true?
> No.
>
>> the controller is quite
>> capable of queueing more than 1 message at a time. This the reason for
>> letting the client choose the mode of operation - use ack mechanism for
>> operation. client can choose to ignore the buffering in the controller,
>> as you mentioned, but then, why force txdone_poll to true and deny the
>> usage of the queue capability of the hardware?
>>
> irq/poll/ack whatever you use, there is no valid reason to buffer
> messages in the controller driver. Please let me know what usecase you
> have in mind that must have messages buffered in controller driver and
> not core.

I am confused, I am _not_ buffering any tx data in the controller
driver - rx data is stored in a temp buffer to send up the stack -
that is just regular practise, right?. In tx, I just check to ensure
that the queue has'nt run out prior to transmission since the hardware
is capable of queueing - ok, in a single transmitter system it is
probably a little overkill, but we would like to function in multiple
producer SoC as well. What am I missing here?

-- 
---
Regards,
Nishanth Menon

[toc] | [prev] | [next] | [standalone]


#1357810

FromJassi Brar <jassisinghbrar@gmail.com>
Date2016-03-15 06:40 +0100
Message-ID<rcPS2-6aZ-9@gated-at.bofh.it>
In reply to#1353104
On Tue, Mar 8, 2016 at 8:07 PM, Nishanth Menon <nm@ti.com> wrote:
> Jassi,
>
> On Tue, Mar 8, 2016 at 1:10 AM, Jassi Brar <jassisinghbrar@gmail.com> wrote:
>> On Tue, Mar 8, 2016 at 2:18 AM, Nishanth Menon <nm@ti.com> wrote:
>>> On 03/07/2016 12:31 PM, Jassi Brar wrote:
>>>> On Fri, Mar 4, 2016 at 8:05 PM, Nishanth Menon <nm@ti.com> wrote:
>>>>>>
>>>>>>> +static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
>>>>>>> +{
>>>>>>> +       struct device *dev = chan->mbox->dev;
>>>>>>> +       struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
>>>>>>> +       const struct ti_msgmgr_desc *desc;
>>>>>>> +       struct ti_queue_inst *qinst = chan->con_priv;
>>>>>>> +       int msg_count, num_words, trail_bytes;
>>>>>>> +       struct ti_msgmgr_message *message = data;
>>>>>>> +       void __iomem *data_reg;
>>>>>>> +       u32 *word_data;
>>>>>>> +
>>>>>>> +       if (WARN_ON(!inst)) {
>>>>>>> +               dev_err(dev, "no platform drv data??\n");
>>>>>>> +               return -EINVAL;
>>>>>>> +       }
>>>>>>> +       desc = inst->desc;
>>>>>>> +
>>>>>>> +       if (desc->max_message_size < message->len) {
>>>>>>> +               dev_err(dev, "Queue %s message length %d > max %d\n",
>>>>>>> +                       qinst->name, message->len, desc->max_message_size);
>>>>>>> +               return -EINVAL;
>>>>>>> +       }
>>>>>>> +
>>>>>>> +       /* Are we able to send this or not? */
>>>>>>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>>>>>>> +       if (msg_count >= desc->max_messages) {
>>>>>>> +               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
>>>>>>> +                        msg_count);
>>>>>>> +               return -EBUSY;
>>>>>>> +       }
>>>>>> This seems fishy. mailbox api always submit 1 'complete' message to be
>>>>>> sent and checks for completion by last_tx_done() before calling
>>>>>> send_data() again. Controller drivers are not supposed to queue
>>>>>> messages - mailbox core does. So you should never be unable to send a
>>>>>> message.
>>>>>
>>>>>
>>>>> OK-> to explain this, few reasons: (queue messages check and usage of
>>>>> last_tx_done are kind of intertwined answer..
>>>>> a) we need to remember that the message manager has a shared RAM.
>>>>> multiple transmitter over other queues can be sharing the same.
>>>>> unfortunately, we dont get a threshold kind of interrupt or status that
>>>>> I am able to exploit in the current incarnation of the solution. The
>>>>> best we can do in the full system is to constrain the number of messages
>>>>> that are max pending simultaneously in each of the queue from various
>>>>> transmitters in the SoC.
>>>>> b) last_tx_done() is checked if TXDONE_BY_POLL, not if TXDONE_BY_ACK
>>>>> right? which is how this'd work since txdone_poll is false -> that is
>>>>> how we want this mechanism to work once the far end is ready for next
>>>>> message, it acks. I do see your point about being tied to protocol - I
>>>>> dont like it either.. in fact, I'd prefer that client registration
>>>>> mention what kind of handshaking is necessary, but: a) that is not how
>>>>> mailbox framework is constructed at the moment(we state txdone_poll at
>>>>> mailbox registration, not at client usage) and b) I have no real need
>>>>> for multiple clients to users of message manager who actually need
>>>>> non-ACK usage - even for the foreseeable future (at least 1 next
>>>>> generation of SoC) - if such a need does arise in the future, I will
>>>>> have to rework framework and make this capability at the registration
>>>>> time of the client - allowing each client path to use different
>>>>> mechanisms on hardware such as these that need it.
>>>>> c) message manager can actually queue more than one message(depending on
>>>>> client capability). Even though, at this point, we are not really
>>>>> capable of doing it(again from what I can see for immediate future),
>>>>> mailbox framework by checking last_tx_done forces a single message
>>>>> sequencing - which is not really exploiting the capability of the
>>>>> hardware - in theory, we should be able to queue max num messages, hit
>>>>> cpuidle and snooze away while the remote entity chomp away data at it's
>>>>> own pace and finally give us a notification back - but again, we can
>>>>> argue it is indeed protocol dependent, so setting txdone_poll to false
>>>>> actually enables that to be done in user. Again - i have no immediate
>>>>> need for any queued multiple transfer needs yet.. even if i need to, in
>>>>> the future, it can easily be done by the client by maintaining code as
>>>>> is - txdone_poll is false.
>>>>>
>>>> All I suggest is that the controller does not queue more than 1
>>>> message at a time, which means the controller driver allows for
>>>> maximum possible resources taken by a message.
>>>> The buffering is already done by the core, and if for your 'batch
>>>> dispatch' thing the client could simply flush them to remote by
>>>> pretending it got the ack (which is no worse than simply sending all
>>>> messages to remote without caring if the first was successful or not).
>>>
>>> Are you suggesting to set txdone_poll is true?
>> No.
>>
>>> the controller is quite
>>> capable of queueing more than 1 message at a time. This the reason for
>>> letting the client choose the mode of operation - use ack mechanism for
>>> operation. client can choose to ignore the buffering in the controller,
>>> as you mentioned, but then, why force txdone_poll to true and deny the
>>> usage of the queue capability of the hardware?
>>>
>> irq/poll/ack whatever you use, there is no valid reason to buffer
>> messages in the controller driver. Please let me know what usecase you
>> have in mind that must have messages buffered in controller driver and
>> not core.
>
> I am confused, I am _not_ buffering any tx data in the controller
> driver - rx data is stored in a temp buffer to send up the stack -
> that is just regular practise, right?
>
right.

> In tx, I just check to ensure
> that the queue has'nt run out prior to transmission since the hardware
> is capable of queueing - ok, in a single transmitter system it is
> probably a little overkill, but we would like to function in multiple
> producer SoC as well. What am I missing here?
>
In send_data() you have ...

+       /* Are we able to send this or not? */
+       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
+       if (msg_count >= desc->max_messages) {
+               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
+                        msg_count);
+               return -EBUSY;
+       }

That is, you check if there are some messages in the TX-Queue already.
I am not sure how you could hit this and if that is legit.

[toc] | [prev] | [next] | [standalone]


#1358156

FromNishanth Menon <nm@ti.com>
Date2016-03-15 18:10 +0100
Message-ID<rd0DN-4Yj-39@gated-at.bofh.it>
In reply to#1357810
On Tue, Mar 15, 2016 at 12:31 AM, Jassi Brar <jassisinghbrar@gmail.com> wrote:
> On Tue, Mar 8, 2016 at 8:07 PM, Nishanth Menon <nm@ti.com> wrote:
>> Jassi,
>>
>> On Tue, Mar 8, 2016 at 1:10 AM, Jassi Brar <jassisinghbrar@gmail.com> wrote:
>>> On Tue, Mar 8, 2016 at 2:18 AM, Nishanth Menon <nm@ti.com> wrote:
>>>> On 03/07/2016 12:31 PM, Jassi Brar wrote:
>>>>> On Fri, Mar 4, 2016 at 8:05 PM, Nishanth Menon <nm@ti.com> wrote:
>>>>>>>
>>>>>>>> +static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
>>>>>>>> +{
>>>>>>>> +       struct device *dev = chan->mbox->dev;
>>>>>>>> +       struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
>>>>>>>> +       const struct ti_msgmgr_desc *desc;
>>>>>>>> +       struct ti_queue_inst *qinst = chan->con_priv;
>>>>>>>> +       int msg_count, num_words, trail_bytes;
>>>>>>>> +       struct ti_msgmgr_message *message = data;
>>>>>>>> +       void __iomem *data_reg;
>>>>>>>> +       u32 *word_data;
>>>>>>>> +
>>>>>>>> +       if (WARN_ON(!inst)) {
>>>>>>>> +               dev_err(dev, "no platform drv data??\n");
>>>>>>>> +               return -EINVAL;
>>>>>>>> +       }
>>>>>>>> +       desc = inst->desc;
>>>>>>>> +
>>>>>>>> +       if (desc->max_message_size < message->len) {
>>>>>>>> +               dev_err(dev, "Queue %s message length %d > max %d\n",
>>>>>>>> +                       qinst->name, message->len, desc->max_message_size);
>>>>>>>> +               return -EINVAL;
>>>>>>>> +       }
>>>>>>>> +
>>>>>>>> +       /* Are we able to send this or not? */
>>>>>>>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>>>>>>>> +       if (msg_count >= desc->max_messages) {
>>>>>>>> +               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
>>>>>>>> +                        msg_count);
>>>>>>>> +               return -EBUSY;
>>>>>>>> +       }
>>>>>>> This seems fishy. mailbox api always submit 1 'complete' message to be
>>>>>>> sent and checks for completion by last_tx_done() before calling
>>>>>>> send_data() again. Controller drivers are not supposed to queue
>>>>>>> messages - mailbox core does. So you should never be unable to send a
>>>>>>> message.
>>>>>>
>>>>>>
>>>>>> OK-> to explain this, few reasons: (queue messages check and usage of
>>>>>> last_tx_done are kind of intertwined answer..
>>>>>> a) we need to remember that the message manager has a shared RAM.
>>>>>> multiple transmitter over other queues can be sharing the same.
>>>>>> unfortunately, we dont get a threshold kind of interrupt or status that
>>>>>> I am able to exploit in the current incarnation of the solution. The
>>>>>> best we can do in the full system is to constrain the number of messages
>>>>>> that are max pending simultaneously in each of the queue from various
>>>>>> transmitters in the SoC.
>>>>>> b) last_tx_done() is checked if TXDONE_BY_POLL, not if TXDONE_BY_ACK
>>>>>> right? which is how this'd work since txdone_poll is false -> that is
>>>>>> how we want this mechanism to work once the far end is ready for next
>>>>>> message, it acks. I do see your point about being tied to protocol - I
>>>>>> dont like it either.. in fact, I'd prefer that client registration
>>>>>> mention what kind of handshaking is necessary, but: a) that is not how
>>>>>> mailbox framework is constructed at the moment(we state txdone_poll at
>>>>>> mailbox registration, not at client usage) and b) I have no real need
>>>>>> for multiple clients to users of message manager who actually need
>>>>>> non-ACK usage - even for the foreseeable future (at least 1 next
>>>>>> generation of SoC) - if such a need does arise in the future, I will
>>>>>> have to rework framework and make this capability at the registration
>>>>>> time of the client - allowing each client path to use different
>>>>>> mechanisms on hardware such as these that need it.
>>>>>> c) message manager can actually queue more than one message(depending on
>>>>>> client capability). Even though, at this point, we are not really
>>>>>> capable of doing it(again from what I can see for immediate future),
>>>>>> mailbox framework by checking last_tx_done forces a single message
>>>>>> sequencing - which is not really exploiting the capability of the
>>>>>> hardware - in theory, we should be able to queue max num messages, hit
>>>>>> cpuidle and snooze away while the remote entity chomp away data at it's
>>>>>> own pace and finally give us a notification back - but again, we can
>>>>>> argue it is indeed protocol dependent, so setting txdone_poll to false
>>>>>> actually enables that to be done in user. Again - i have no immediate
>>>>>> need for any queued multiple transfer needs yet.. even if i need to, in
>>>>>> the future, it can easily be done by the client by maintaining code as
>>>>>> is - txdone_poll is false.
>>>>>>
>>>>> All I suggest is that the controller does not queue more than 1
>>>>> message at a time, which means the controller driver allows for
>>>>> maximum possible resources taken by a message.
>>>>> The buffering is already done by the core, and if for your 'batch
>>>>> dispatch' thing the client could simply flush them to remote by
>>>>> pretending it got the ack (which is no worse than simply sending all
>>>>> messages to remote without caring if the first was successful or not).
>>>>
>>>> Are you suggesting to set txdone_poll is true?
>>> No.
>>>
>>>> the controller is quite
>>>> capable of queueing more than 1 message at a time. This the reason for
>>>> letting the client choose the mode of operation - use ack mechanism for
>>>> operation. client can choose to ignore the buffering in the controller,
>>>> as you mentioned, but then, why force txdone_poll to true and deny the
>>>> usage of the queue capability of the hardware?
>>>>
>>> irq/poll/ack whatever you use, there is no valid reason to buffer
>>> messages in the controller driver. Please let me know what usecase you
>>> have in mind that must have messages buffered in controller driver and
>>> not core.
>>
>> I am confused, I am _not_ buffering any tx data in the controller
>> driver - rx data is stored in a temp buffer to send up the stack -
>> that is just regular practise, right?
>>
> right.
>
>> In tx, I just check to ensure
>> that the queue has'nt run out prior to transmission since the hardware
>> is capable of queueing - ok, in a single transmitter system it is
>> probably a little overkill, but we would like to function in multiple
>> producer SoC as well. What am I missing here?
>>
> In send_data() you have ...
>
> +       /* Are we able to send this or not? */
> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
> +       if (msg_count >= desc->max_messages) {
> +               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
> +                        msg_count);
> +               return -EBUSY;
> +       }
>
> That is, you check if there are some messages in the TX-Queue already.
> I am not sure how you could hit this and if that is legit.

Alright, i will drop this check since it is causing a lot more
confusion that that is worth. we can introduce it when we finally do
hit an issue eventually with multiple processors trying to transmit on
the same queue manager. that is not a concern at the very immediate
time, so we should be good to drop.

please let me know if you are ok with this.

-- 
---
Regards,
Nishanth Menon

[toc] | [prev] | [next] | [standalone]


#1358532

FromJassi Brar <jassisinghbrar@gmail.com>
Date2016-03-16 06:20 +0100
Message-ID<rdc2e-4e2-7@gated-at.bofh.it>
In reply to#1358156
On Tue, Mar 15, 2016 at 10:35 PM, Nishanth Menon <nm@ti.com> wrote:
> On Tue, Mar 15, 2016 at 12:31 AM, Jassi Brar <jassisinghbrar@gmail.com> wrote:
>> On Tue, Mar 8, 2016 at 8:07 PM, Nishanth Menon <nm@ti.com> wrote:
>>> Jassi,
>>>
>>> On Tue, Mar 8, 2016 at 1:10 AM, Jassi Brar <jassisinghbrar@gmail.com> wrote:
>>>> On Tue, Mar 8, 2016 at 2:18 AM, Nishanth Menon <nm@ti.com> wrote:
>>>>> On 03/07/2016 12:31 PM, Jassi Brar wrote:
>>>>>> On Fri, Mar 4, 2016 at 8:05 PM, Nishanth Menon <nm@ti.com> wrote:
>>>>>>>>
>>>>>>>>> +static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data)
>>>>>>>>> +{
>>>>>>>>> +       struct device *dev = chan->mbox->dev;
>>>>>>>>> +       struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
>>>>>>>>> +       const struct ti_msgmgr_desc *desc;
>>>>>>>>> +       struct ti_queue_inst *qinst = chan->con_priv;
>>>>>>>>> +       int msg_count, num_words, trail_bytes;
>>>>>>>>> +       struct ti_msgmgr_message *message = data;
>>>>>>>>> +       void __iomem *data_reg;
>>>>>>>>> +       u32 *word_data;
>>>>>>>>> +
>>>>>>>>> +       if (WARN_ON(!inst)) {
>>>>>>>>> +               dev_err(dev, "no platform drv data??\n");
>>>>>>>>> +               return -EINVAL;
>>>>>>>>> +       }
>>>>>>>>> +       desc = inst->desc;
>>>>>>>>> +
>>>>>>>>> +       if (desc->max_message_size < message->len) {
>>>>>>>>> +               dev_err(dev, "Queue %s message length %d > max %d\n",
>>>>>>>>> +                       qinst->name, message->len, desc->max_message_size);
>>>>>>>>> +               return -EINVAL;
>>>>>>>>> +       }
>>>>>>>>> +
>>>>>>>>> +       /* Are we able to send this or not? */
>>>>>>>>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>>>>>>>>> +       if (msg_count >= desc->max_messages) {
>>>>>>>>> +               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
>>>>>>>>> +                        msg_count);
>>>>>>>>> +               return -EBUSY;
>>>>>>>>> +       }
>>>>>>>> This seems fishy. mailbox api always submit 1 'complete' message to be
>>>>>>>> sent and checks for completion by last_tx_done() before calling
>>>>>>>> send_data() again. Controller drivers are not supposed to queue
>>>>>>>> messages - mailbox core does. So you should never be unable to send a
>>>>>>>> message.
>>>>>>>
>>>>>>>
>>>>>>> OK-> to explain this, few reasons: (queue messages check and usage of
>>>>>>> last_tx_done are kind of intertwined answer..
>>>>>>> a) we need to remember that the message manager has a shared RAM.
>>>>>>> multiple transmitter over other queues can be sharing the same.
>>>>>>> unfortunately, we dont get a threshold kind of interrupt or status that
>>>>>>> I am able to exploit in the current incarnation of the solution. The
>>>>>>> best we can do in the full system is to constrain the number of messages
>>>>>>> that are max pending simultaneously in each of the queue from various
>>>>>>> transmitters in the SoC.
>>>>>>> b) last_tx_done() is checked if TXDONE_BY_POLL, not if TXDONE_BY_ACK
>>>>>>> right? which is how this'd work since txdone_poll is false -> that is
>>>>>>> how we want this mechanism to work once the far end is ready for next
>>>>>>> message, it acks. I do see your point about being tied to protocol - I
>>>>>>> dont like it either.. in fact, I'd prefer that client registration
>>>>>>> mention what kind of handshaking is necessary, but: a) that is not how
>>>>>>> mailbox framework is constructed at the moment(we state txdone_poll at
>>>>>>> mailbox registration, not at client usage) and b) I have no real need
>>>>>>> for multiple clients to users of message manager who actually need
>>>>>>> non-ACK usage - even for the foreseeable future (at least 1 next
>>>>>>> generation of SoC) - if such a need does arise in the future, I will
>>>>>>> have to rework framework and make this capability at the registration
>>>>>>> time of the client - allowing each client path to use different
>>>>>>> mechanisms on hardware such as these that need it.
>>>>>>> c) message manager can actually queue more than one message(depending on
>>>>>>> client capability). Even though, at this point, we are not really
>>>>>>> capable of doing it(again from what I can see for immediate future),
>>>>>>> mailbox framework by checking last_tx_done forces a single message
>>>>>>> sequencing - which is not really exploiting the capability of the
>>>>>>> hardware - in theory, we should be able to queue max num messages, hit
>>>>>>> cpuidle and snooze away while the remote entity chomp away data at it's
>>>>>>> own pace and finally give us a notification back - but again, we can
>>>>>>> argue it is indeed protocol dependent, so setting txdone_poll to false
>>>>>>> actually enables that to be done in user. Again - i have no immediate
>>>>>>> need for any queued multiple transfer needs yet.. even if i need to, in
>>>>>>> the future, it can easily be done by the client by maintaining code as
>>>>>>> is - txdone_poll is false.
>>>>>>>
>>>>>> All I suggest is that the controller does not queue more than 1
>>>>>> message at a time, which means the controller driver allows for
>>>>>> maximum possible resources taken by a message.
>>>>>> The buffering is already done by the core, and if for your 'batch
>>>>>> dispatch' thing the client could simply flush them to remote by
>>>>>> pretending it got the ack (which is no worse than simply sending all
>>>>>> messages to remote without caring if the first was successful or not).
>>>>>
>>>>> Are you suggesting to set txdone_poll is true?
>>>> No.
>>>>
>>>>> the controller is quite
>>>>> capable of queueing more than 1 message at a time. This the reason for
>>>>> letting the client choose the mode of operation - use ack mechanism for
>>>>> operation. client can choose to ignore the buffering in the controller,
>>>>> as you mentioned, but then, why force txdone_poll to true and deny the
>>>>> usage of the queue capability of the hardware?
>>>>>
>>>> irq/poll/ack whatever you use, there is no valid reason to buffer
>>>> messages in the controller driver. Please let me know what usecase you
>>>> have in mind that must have messages buffered in controller driver and
>>>> not core.
>>>
>>> I am confused, I am _not_ buffering any tx data in the controller
>>> driver - rx data is stored in a temp buffer to send up the stack -
>>> that is just regular practise, right?
>>>
>> right.
>>
>>> In tx, I just check to ensure
>>> that the queue has'nt run out prior to transmission since the hardware
>>> is capable of queueing - ok, in a single transmitter system it is
>>> probably a little overkill, but we would like to function in multiple
>>> producer SoC as well. What am I missing here?
>>>
>> In send_data() you have ...
>>
>> +       /* Are we able to send this or not? */
>> +       msg_count = ti_msgmgr_queue_get_num_messages(qinst);
>> +       if (msg_count >= desc->max_messages) {
>> +               dev_warn(dev, "Queue %s is full (%d messages)\n", qinst->name,
>> +                        msg_count);
>> +               return -EBUSY;
>> +       }
>>
>> That is, you check if there are some messages in the TX-Queue already.
>> I am not sure how you could hit this and if that is legit.
>
> Alright, i will drop this check since it is causing a lot more
> confusion
>
It's confusing because you check ti_msgmgr_queue_get_num_messages()
also in ti_msgmgr_last_tx_done() which doesn't make sense because the
former accounts for messages from other senders also (as you say there
could be multiple senders).

> that that is worth. we can introduce it when we finally do
> hit an issue eventually with multiple processors trying to transmit on
> the same queue manager. that is not a concern at the very immediate
> time, so we should be good to drop.
>
> please let me know if you are ok with this.
>
I am ok with whatever you assert is needed for your platform. I just
point out what I think are inconsistencies in your assumptions. I'll
pick the next revision however it is.

Thanks.

[toc] | [prev] | [next] | [standalone]


#1359492

FromNishanth Menon <nm@ti.com>
Date2016-03-17 01:40 +0100
Message-ID<rdu8P-8hX-17@gated-at.bofh.it>
In reply to#1358532
Hi Jassi,

On 03/16/2016 12:16 AM, Jassi Brar wrote:

[...]
>> Alright, i will drop this check since it is causing a lot more
>> confusion
>>
> It's confusing because you check ti_msgmgr_queue_get_num_messages()
> also in ti_msgmgr_last_tx_done() which doesn't make sense because the
> former accounts for messages from other senders also (as you say there
> could be multiple senders).


True -> I will drop it for now. I will see if the case I was trying to
protect is actually possible to be hit in the first place. And if proven
to be required, I will introduce it back with a better explanation and
the usecase where this is needed.

>> that that is worth. we can introduce it when we finally do
>> hit an issue eventually with multiple processors trying to transmit on
>> the same queue manager. that is not a concern at the very immediate
>> time, so we should be good to drop.
>>
>> please let me know if you are ok with this.
>>
> I am ok with whatever you assert is needed for your platform. I just
> point out what I think are inconsistencies in your assumptions. I'll
> pick the next revision however it is.


Thanks for your patience and guidance with this series. I have tried to
incorporate all the alignment we have had on this thread as part of
V3[1] of the series.


[1] http://marc.info/?l=linux-arm-kernel&m=145817434531691&w=2

-- 
Regards,
Nishanth Menon

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web