Module Name: src Committed By: mlelstv Date: Sat Jan 4 22:30:06 UTC 2020
Modified Files: src/sys/dev/usb: if_run.c if_runvar.h Log Message: Avoid race condition. Patch from bouyer@ To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 src/sys/dev/usb/if_run.c cvs rdiff -u -r1.6 -r1.7 src/sys/dev/usb/if_runvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/if_run.c diff -u src/sys/dev/usb/if_run.c:1.34 src/sys/dev/usb/if_run.c:1.35 --- src/sys/dev/usb/if_run.c:1.34 Thu Dec 19 15:17:30 2019 +++ src/sys/dev/usb/if_run.c Sat Jan 4 22:30:06 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_run.c,v 1.34 2019/12/19 15:17:30 gson Exp $ */ +/* $NetBSD: if_run.c,v 1.35 2020/01/04 22:30:06 mlelstv Exp $ */ /* $OpenBSD: if_run.c,v 1.90 2012/03/24 15:11:04 jsg Exp $ */ /*- @@ -23,7 +23,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_run.c,v 1.34 2019/12/19 15:17:30 gson Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_run.c,v 1.35 2020/01/04 22:30:06 mlelstv Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_run.c,v 1 #include <sys/module.h> #include <sys/conf.h> #include <sys/device.h> +#include <sys/atomic.h> #include <sys/bus.h> #include <machine/endian.h> @@ -1784,10 +1785,11 @@ run_task(void *arg) while (ring->next != ring->cur) { cmd = &ring->cmd[ring->next]; splx(s); + membar_consumer(); /* callback */ cmd->cb(sc, cmd->data); s = splusb(); - ring->queued--; + atomic_dec_uint(&ring->queued); ring->next = (ring->next + 1) % RUN_HOST_CMD_RING_COUNT; } wakeup(ring); @@ -1810,10 +1812,11 @@ run_do_async(struct run_softc *sc, void cmd->cb = cb; KASSERT(len <= sizeof(cmd->data)); memcpy(cmd->data, arg, len); + membar_producer(); ring->cur = (ring->cur + 1) % RUN_HOST_CMD_RING_COUNT; /* if there is no pending command already, schedule a task */ - if (++ring->queued == 1) + if (atomic_inc_uint_nv(&ring->queued) == 1) usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); splx(s); } Index: src/sys/dev/usb/if_runvar.h diff -u src/sys/dev/usb/if_runvar.h:1.6 src/sys/dev/usb/if_runvar.h:1.7 --- src/sys/dev/usb/if_runvar.h:1.6 Tue Oct 8 07:30:58 2019 +++ src/sys/dev/usb/if_runvar.h Sat Jan 4 22:30:06 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_runvar.h,v 1.6 2019/10/08 07:30:58 mlelstv Exp $ */ +/* $NetBSD: if_runvar.h,v 1.7 2020/01/04 22:30:06 mlelstv Exp $ */ /* $OpenBSD: if_runvar.h,v 1.8 2010/02/08 18:46:47 damien Exp $ */ /*- @@ -93,7 +93,7 @@ struct run_tx_ring { struct run_tx_data data[RUN_TX_RING_COUNT]; struct usbd_pipe * pipeh; int cur; - int queued; + volatile unsigned queued; uint8_t pipe_no; };