mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Cc: "Edmund Henniges" <eh@emlix.com>, "Daniel Glöckner" <dg@emlix.com>
Subject: Protect code from pollers
Date: Fri,  6 Mar 2020 20:33:58 +0100	[thread overview]
Message-ID: <20200306193406.20531-1-s.hauer@pengutronix.de> (raw)

barebox runs code in pollers. This works reasonably well when the
pollers do not touch any resources that are used by code outside the
pollers as well. Currently we also have fastboot running in a poller
and this is where things become dangerous. This series aims to provide a
way for solving resource conflicts with pollers. It is currently enough
to safely run the networking receive loop inside of pollers, but there
are more possible issues, one of them described below. There are several
more places that have to be sprinkled with:

slices, the barebox idea of locking
===================================

barebox has pollers which execute code in the background whenever one of the
delay functions (udelay, mdelay, ...) or is_timeout() are called. This
introduces resource problems when some device triggers a poller by calling
a delay function and then the poller code calls into the same device again.

As an example consider a I2C GPIO expander which drives a LED which shall
be used as a heartbeat LED:

poller -> LED on/off -> GPIO high/low -> I2C transfer

The I2C controller has a timeout loop using is_timeout() and thus can trigger
a poller run. With this the following can happen during an unrelated I2C
transfer:

I2C transfer -> is_timeout() -> poller -> LED on/off -> GPIO high/low -> I2C transfer

We end up with issuing an I2C transfer during another I2C transfer and
things go downhill.

Due to the lack of interrupts we can't do real locking in barebox. We use
a mechanism called slices instead. A slice describes a resource to which
other slices can be attached. Whenever a slice is needed it must be acquired.
Acquiring a slice never fails, it just increases the acquired counter of
the slice and its dependent slices. when a slice shall be used inside a
poller it must first be tested if the slice is already in use. If it is,
we can't do the operation on the slice now and must return and hope that
we have more luck in the next poller call.

slices can be attached other slices as dependencies. In the example above
LED driver would add a dependency to the GPIO controller and the GPIO driver
would add a dependency to the I2C bus:

GPIO driver probe:

slice_add(&gpio->slice, i2c_device_slice(i2cdev));

LED driver probe:

slice_add(&led->slice, gpio_slice(gpio));

The GPIO code would call slice_acquire(&gpio->slice) before doing any
operation on the GPIO chip providing this GPIO, likewise the I2C core
would call slice_acquire(&i2cbus->slice) before doing an operation on
this I2C bus.

The heartbeat poller code would call slice_acquired(led_slice(led)) and
only continue when the slice is not acquired.

Sascha

Sascha Hauer (8):
  Introduce slices
  net: Add a slice to struct eth_device
  net: mdiobus: Add slice
  usb: Add a slice to usb host controllers
  usbnet: Add slice
  net: Call net_poll() in a poller
  net: reply to ping requests
  usbnet: Be more friendly in the receive path

 common/Makefile            |   1 +
 common/slice.c             | 316 +++++++++++++++++++++++++++++++++++++
 drivers/net/phy/mdio_bus.c |  40 +++++
 drivers/net/phy/phy.c      |   2 +
 drivers/net/usb/usbnet.c   |  22 ++-
 drivers/usb/core/usb.c     |   6 +
 fs/nfs.c                   |   2 -
 fs/tftp.c                  |   2 -
 include/linux/phy.h        |  32 ++--
 include/net.h              |  11 +-
 include/slice.h            |  31 ++++
 include/usb/usb.h          |   7 +
 include/usb/usbnet.h       |   3 +
 net/dhcp.c                 |   1 -
 net/dns.c                  |   1 -
 net/eth.c                  |  29 +++-
 net/net.c                  |  60 ++++++-
 net/netconsole.c           |   4 +-
 net/nfs.c                  |   1 -
 net/ping.c                 |   2 -
 net/sntp.c                 |   2 -
 21 files changed, 524 insertions(+), 51 deletions(-)
 create mode 100644 common/slice.c
 create mode 100644 include/slice.h

-- 
2.25.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

             reply	other threads:[~2020-03-06 19:34 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-06 19:33 Sascha Hauer [this message]
2020-03-06 19:33 ` [PATCH 1/8] Introduce slices Sascha Hauer
2020-03-09 14:49   ` Daniel Glöckner
2020-03-10 10:10     ` Sascha Hauer
2020-03-06 19:34 ` [PATCH 2/8] net: Add a slice to struct eth_device Sascha Hauer
2020-03-06 19:34 ` [PATCH 3/8] net: mdiobus: Add slice Sascha Hauer
2020-03-06 19:34 ` [PATCH 4/8] usb: Add a slice to usb host controllers Sascha Hauer
2020-03-06 19:34 ` [PATCH 5/8] usbnet: Add slice Sascha Hauer
2020-03-06 19:34 ` [PATCH 6/8] net: Call net_poll() in a poller Sascha Hauer
2020-03-06 19:34 ` [PATCH 7/8] net: reply to ping requests Sascha Hauer
2020-03-06 19:34 ` [PATCH 8/8] usbnet: Be more friendly in the receive path Sascha Hauer

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=20200306193406.20531-1-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    --cc=dg@emlix.com \
    --cc=eh@emlix.com \
    /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