Messages in this thread | | | Date | Wed, 14 Dec 2005 00:49:58 +0300 | From | Vitaly Wool <> | Subject | Re: [spi-devel-general] [patch 2.6.15-rc5-mm2] SPI, priority inversion tweak |
| |
So you're turning this to be unsafe if the buffer is in use, right? Funny...
David Brownell wrote:
>This is an updated version of the patch from Mark Underwood, handling >the no-memory case better and using SLAB_KERNEL not SLAB_ATOMIC. > >Please apply it on top of the current SPI code in the MM tree. > >- Dave > > >------------------------------------------------------------------------ > >Update the SPI framework to remove a potential priority inversion case by >reverting to kmalloc if the pre-allocated DMA-safe buffer isn't available. > >From: Mark Underwood <basicmark@yahoo.com> >Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> > >--- g26.orig/drivers/spi/spi.c 2005-12-11 11:06:38.000000000 -0800 >+++ g26/drivers/spi/spi.c 2005-12-13 09:56:22.000000000 -0800 >@@ -541,22 +541,30 @@ int spi_write_then_read(struct spi_devic > int status; > struct spi_message message; > struct spi_transfer x[2]; >+ u8 *local_buf; > > /* Use preallocated DMA-safe buffer. We can't avoid copying here, > * (as a pure convenience thing), but we can keep heap costs >- * out of the hot path. >+ * out of the hot path ... > */ > if ((n_tx + n_rx) > SPI_BUFSIZ) > return -EINVAL; > >- down(&lock); >+ /* ... unless someone else is using the pre-allocated buffer */ >+ if (down_trylock(&lock)) { >+ local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL); >+ if (!local_buf) >+ return -ENOMEM; >+ } else >+ local_buf = buf; >+ > memset(x, 0, sizeof x); > >- memcpy(buf, txbuf, n_tx); >- x[0].tx_buf = buf; >+ memcpy(local_buf, txbuf, n_tx); >+ x[0].tx_buf = local_buf; > x[0].len = n_tx; > >- x[1].rx_buf = buf + n_tx; >+ x[1].rx_buf = local_buf + n_tx; > x[1].len = n_rx; > > /* do the i/o */ >@@ -568,7 +576,11 @@ int spi_write_then_read(struct spi_devic > status = message.status; > } > >- up(&lock); >+ if (x[0].tx_buf == buf) >+ up(&lock); >+ else >+ kfree(local_buf); >+ > return status; > } > EXPORT_SYMBOL_GPL(spi_write_then_read); > >
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |