public inbox for linux-mmc@vger.kernel.org
 help / color / mirror / Atom feed
From: Arnd Bergmann <arnd@arndb.de>
To: David Daney <ddaney@caviumnetworks.com>
Cc: Matt Redfearn <matt.redfearn@imgtec.com>,
	ulf.hansson@linaro.org, linux-mmc@vger.kernel.org,
	Aleksey Makarov <aleksey.makarov@caviumnetworks.com>,
	Chandrakala Chavva <cchavva@caviumnetworks.com>,
	David Daney <david.daney@cavium.com>,
	Aleksey Makarov <aleksey.makarov@auriga.com>,
	Leonid Rosenboim <lrosenboim@caviumnetworks.com>,
	Peter Swain <pswain@cavium.com>,
	Aaron Williams <aaron.williams@cavium.com>
Subject: Re: [RESEND PATCH v7 2/2] mmc: OCTEON: Add host driver for OCTEON MMC controller
Date: Wed, 20 Apr 2016 01:57:08 +0200	[thread overview]
Message-ID: <3904622.mKVlLT0JKv@wuerfel> (raw)
In-Reply-To: <5716BEC7.5000706@caviumnetworks.com>

On Tuesday 19 April 2016 16:27:03 David Daney wrote:
> The way the MMC driver works is that the driver's .request() method is 
> called to initiate a request.   After .request() is finished, it returns 
> back to the kernel so other work can be done.
> 
>  From the interrupt handler, when the request is complete, the interrupt 
> handler calls req->done(req); to terminate the whole thing.
> 
> 
>    So we have:
> 
>    CPU-A                      CPU-B                  CPU-C
> 
>    octeon_mmc_request(0)        .                     .
>       down()                    .                     .
>       queue_request(0);         .                     .
>       return;                   .                     .
>    other_useful_work            .                     .
>     .                           .                     .
>     .                           .                     .
>     .                           .                     .
>    octeon_mmc_request(1)        .                     .
>       down() -> blocks          .                     .
>                              octeon_mmc_interrupt()   .
>                                  up() -> unblocks     .
>       down() <-unblocks          req->done(0)         .
>       queue_request(1);          return;              .
>       return;                   .                     .
>    other_useful_work            .                     .
>     .                           .                octeon_mmc_interrupt()
>     .                           .                     up()
>     .                           .                     req->done(1)
>     .                           .                     return;
>     .                           .                     .
> 
> 
> We don't want to have the thread on CPU-A wait around in an extra mutex 
> or completion for the command to finish.  The MMC core already has its 
> own request waiting code, but it doesn't handle the concept of a slot. 
> These commands can take hundreds or thousands of mS to terminate.  The 
> whole idea of the MMC framework is to queue the request and get back to 
> doing other work ASAP.

Right. This usecase seems to be one of the few that legitimately use
semaphores. However, there has been a long effort to eliminate the
remaining semaphores from the kernel (mostly much stalled since 2.6.32,
but we still try to prevent new ones from creeping in).

I had at one point a patch series that removed all the remaining
semaphores, but didn't get it merged at the time, and now there
are a few dozen new users.

> In the case of this octeon_mmc driver we need to serialize the commands 
> issued to multiple slots, for this we use the semaphore.  If you don't 
> like struct semaphore, we would have to invent a proprietary wait queue 
> mechanism that has semantics nearly identical to struct semaphore, and 
> people would complain that we are reinventing the semaphore.
> 
> It doesn't seem clean to cobble up multiple waiting structures 
> (completion + mutex + logic that surely would contain errors) where a 
> single (well debugged) struct semaphore does what we want.

I think using a wait_event() call could make do this with basically
the same amount of code and by naming it right, this could be just
as expressive. For the usecase you describe, a single completion
structure would actually serve the purpose as well (no need for the
mutex), but it would be unusual to wait for the completion before
starting the work.

If you do this

	wait_event(&host->wq, !host->current_req);

in the request function as well as 

	wake_up(&host->wq);

after setting host->current_req to NULL, I think you end up with
the same level of readability as the semaphore, and slightly
better object code, and you can drop the 'WARN_ON(host->current_req);'
which would be known to be impossible.

	Arnd

  reply	other threads:[~2016-04-19 23:57 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-31 15:26 [RESEND PATCH v7 1/2] mmc: OCTEON: Add DT bindings for OCTEON MMC controller Matt Redfearn
2016-03-31 15:26 ` [RESEND PATCH v7 2/2] mmc: OCTEON: Add host driver " Matt Redfearn
2016-04-19 20:46   ` Arnd Bergmann
2016-04-19 21:45     ` David Daney
2016-04-19 22:09       ` Arnd Bergmann
2016-04-19 23:27         ` David Daney
2016-04-19 23:57           ` Arnd Bergmann [this message]
2016-04-20  0:02             ` Arnd Bergmann
2016-04-21  8:02           ` Ulf Hansson
2016-04-21 10:15             ` Arnd Bergmann
2016-04-21 12:44               ` Ulf Hansson
2016-04-21 13:19                 ` Arnd Bergmann
2016-04-22 13:54                   ` Ulf Hansson
2016-04-22 16:42                     ` Arnd Bergmann
2016-04-22 17:49                       ` David Daney
2016-04-22 20:23                         ` Arnd Bergmann
2016-04-14 12:45 ` [RESEND PATCH v7 1/2] mmc: OCTEON: Add DT bindings " Ulf Hansson
2016-04-18  8:53   ` Matt Redfearn
2016-04-18 11:13     ` Ulf Hansson
2016-04-18 11:37       ` Matt Redfearn
2016-04-18 12:08         ` Ulf Hansson
2016-04-18 12:57           ` Matt Redfearn
2016-04-18 22:59             ` David Daney
2016-04-19  9:15             ` Ulf Hansson
2016-04-19 16:13               ` David Daney
2016-04-19 19:33                 ` Ulf Hansson
2016-04-19 20:25                   ` David Daney
2016-04-19 20:56                     ` Arnd Bergmann
2016-04-19 21:50                       ` David Daney
2016-04-20  9:32                     ` Ulf Hansson
2016-04-20 22:32                       ` David Daney
2016-04-20 22:42                         ` Arnd Bergmann

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=3904622.mKVlLT0JKv@wuerfel \
    --to=arnd@arndb.de \
    --cc=aaron.williams@cavium.com \
    --cc=aleksey.makarov@auriga.com \
    --cc=aleksey.makarov@caviumnetworks.com \
    --cc=cchavva@caviumnetworks.com \
    --cc=david.daney@cavium.com \
    --cc=ddaney@caviumnetworks.com \
    --cc=linux-mmc@vger.kernel.org \
    --cc=lrosenboim@caviumnetworks.com \
    --cc=matt.redfearn@imgtec.com \
    --cc=pswain@cavium.com \
    --cc=ulf.hansson@linaro.org \
    /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: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox