svn commit: r355037 - head/sys/dev/pci
Konstantin Belousov
kostikbel at gmail.com
Sun Nov 24 13:10:18 UTC 2019
On Sat, Nov 23, 2019 at 11:43:52PM +0000, Warner Losh wrote:
> Author: imp
> Date: Sat Nov 23 23:43:52 2019
> New Revision: 355037
> URL: https://svnweb.freebsd.org/changeset/base/355037
>
> Log:
> Push Giant down one layer
>
> The /dev/pci device doesn't need GIANT, per se. However, one routine
> that it calls, pci_find_dbsf implicitly does. It walks a list that can
> change when PCI scans a new bus. With hotplug, this means we could
> have a race with that scanning. To prevent that, take out Giant around
> scanning the list.
>
> However, given that we have places in the tree that drop giant, if
> held when we call into them, the whole use of Giant to protect newbus
> may be less effective that we desire, so add a comment about why we're
> talking it out, and we'll address the issue when we lock newbus with
> something other than Giant.
>
> Modified:
> head/sys/dev/pci/pci.c
> head/sys/dev/pci/pci_user.c
>
> Modified: head/sys/dev/pci/pci.c
> ==============================================================================
> --- head/sys/dev/pci/pci.c Sat Nov 23 23:41:21 2019 (r355036)
> +++ head/sys/dev/pci/pci.c Sat Nov 23 23:43:52 2019 (r355037)
> @@ -445,18 +445,21 @@ pci_find_bsf(uint8_t bus, uint8_t slot, uint8_t func)
> device_t
> pci_find_dbsf(uint32_t domain, uint8_t bus, uint8_t slot, uint8_t func)
> {
> - struct pci_devinfo *dinfo;
> + struct pci_devinfo *dinfo = NULL;
>
> + /* Giant because newbus is Giant locked revisit with newbus locking */
> + mtx_lock(&Giant);
> STAILQ_FOREACH(dinfo, &pci_devq, pci_links) {
> if ((dinfo->cfg.domain == domain) &&
> (dinfo->cfg.bus == bus) &&
> (dinfo->cfg.slot == slot) &&
> (dinfo->cfg.func == func)) {
> - return (dinfo->cfg.dev);
> + break;
> }
> }
> + mtx_unlock(&Giant);
>
> - return (NULL);
> + return (dinfo != NULL ? dinfo->cfg.dev : NULL);
I do not think this change is correct. If the parallel hotplug, or
rather, hot-unplug event occurs, then dinfo potentially becomes invalid
right after the Giant unlock, which makes both this function and its
callers to access freed memory. Having caller to lock a newbus lock
around both the call and consumption of the returned data is required.
> }
>
> /* Find a device_t by vendor/device ID */
>
> Modified: head/sys/dev/pci/pci_user.c
> ==============================================================================
> --- head/sys/dev/pci/pci_user.c Sat Nov 23 23:41:21 2019 (r355036)
> +++ head/sys/dev/pci/pci_user.c Sat Nov 23 23:43:52 2019 (r355037)
> @@ -119,7 +119,7 @@ static d_ioctl_t pci_ioctl;
>
> struct cdevsw pcicdev = {
> .d_version = D_VERSION,
> - .d_flags = D_NEEDGIANT,
> + .d_flags = 0,
> .d_open = pci_open,
> .d_close = pci_close,
> .d_ioctl = pci_ioctl,
More information about the svn-src-all
mailing list