Date: Fri, 30 Mar 2018 20:11:12 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r331828 - in head/sys/compat/linuxkpi/common: include/linux src Message-ID: <201803302011.w2UKBC8q029559@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Fri Mar 30 20:11:12 2018 New Revision: 331828 URL: https://svnweb.freebsd.org/changeset/base/331828 Log: Optimise use of Giant in the LinuxKPI. - Make sure Giant is locked when calling PCI device methods. Newbus currently requires this. - Avoid unlocking Giant right before aquiring the sleepqueue lock. This can save a task switch. MFC after: 1 week Sponsored by: Mellanox Technologies Modified: head/sys/compat/linuxkpi/common/include/linux/module.h head/sys/compat/linuxkpi/common/src/linux_compat.c head/sys/compat/linuxkpi/common/src/linux_pci.c head/sys/compat/linuxkpi/common/src/linux_rcu.c head/sys/compat/linuxkpi/common/src/linux_schedule.c Modified: head/sys/compat/linuxkpi/common/include/linux/module.h ============================================================================== --- head/sys/compat/linuxkpi/common/include/linux/module.h Fri Mar 30 19:58:58 2018 (r331827) +++ head/sys/compat/linuxkpi/common/include/linux/module.h Fri Mar 30 20:11:12 2018 (r331828) @@ -78,9 +78,7 @@ _module_run(void *arg) printf("Running %s (%p)\n", name, pc); #endif fn = arg; - DROP_GIANT(); fn(); - PICKUP_GIANT(); } #define module_init(fn) \ Modified: head/sys/compat/linuxkpi/common/src/linux_compat.c ============================================================================== --- head/sys/compat/linuxkpi/common/src/linux_compat.c Fri Mar 30 19:58:58 2018 (r331827) +++ head/sys/compat/linuxkpi/common/src/linux_compat.c Fri Mar 30 20:11:12 2018 (r331828) @@ -1804,8 +1804,6 @@ linux_wait_for_common(struct completion *c, int flags) if (SCHEDULER_STOPPED()) return (0); - DROP_GIANT(); - task = current; if (flags != 0) @@ -1819,22 +1817,25 @@ linux_wait_for_common(struct completion *c, int flags) break; sleepq_add(c, NULL, "completion", flags, 0); if (flags & SLEEPQ_INTERRUPTIBLE) { + DROP_GIANT(); error = -sleepq_wait_sig(c, 0); + PICKUP_GIANT(); if (error != 0) { linux_schedule_save_interrupt_value(task, error); error = -ERESTARTSYS; goto intr; } - } else + } else { + DROP_GIANT(); sleepq_wait(c, 0); + PICKUP_GIANT(); + } } if (c->done != UINT_MAX) c->done--; sleepq_release(c); intr: - PICKUP_GIANT(); - return (error); } @@ -1851,8 +1852,6 @@ linux_wait_for_timeout_common(struct completion *c, in if (SCHEDULER_STOPPED()) return (0); - DROP_GIANT(); - task = current; if (flags != 0) @@ -1866,10 +1865,14 @@ linux_wait_for_timeout_common(struct completion *c, in break; sleepq_add(c, NULL, "completion", flags, 0); sleepq_set_timeout(c, linux_timer_jiffies_until(end)); + + DROP_GIANT(); if (flags & SLEEPQ_INTERRUPTIBLE) error = -sleepq_timedwait_sig(c, 0); else error = -sleepq_timedwait(c, 0); + PICKUP_GIANT(); + if (error != 0) { /* check for timeout */ if (error == -EWOULDBLOCK) { @@ -1889,8 +1892,6 @@ linux_wait_for_timeout_common(struct completion *c, in /* return how many jiffies are left */ error = linux_timer_jiffies_until(end); done: - PICKUP_GIANT(); - return (error); } Modified: head/sys/compat/linuxkpi/common/src/linux_pci.c ============================================================================== --- head/sys/compat/linuxkpi/common/src/linux_pci.c Fri Mar 30 19:58:58 2018 (r331827) +++ head/sys/compat/linuxkpi/common/src/linux_pci.c Fri Mar 30 20:11:12 2018 (r331828) @@ -171,12 +171,11 @@ linux_pci_attach(device_t dev) pdev->bus = pbus; } - DROP_GIANT(); spin_lock(&pci_lock); list_add(&pdev->links, &pci_devices); spin_unlock(&pci_lock); + error = pdrv->probe(pdev, id); - PICKUP_GIANT(); if (error) { spin_lock(&pci_lock); list_del(&pdev->links); @@ -194,9 +193,9 @@ linux_pci_detach(device_t dev) linux_set_current(curthread); pdev = device_get_softc(dev); - DROP_GIANT(); + pdev->pdrv->remove(pdev); - PICKUP_GIANT(); + spin_lock(&pci_lock); list_del(&pdev->links); spin_unlock(&pci_lock); @@ -258,11 +257,8 @@ linux_pci_shutdown(device_t dev) linux_set_current(curthread); pdev = device_get_softc(dev); - if (pdev->pdrv->shutdown != NULL) { - DROP_GIANT(); + if (pdev->pdrv->shutdown != NULL) pdev->pdrv->shutdown(pdev); - PICKUP_GIANT(); - } return (0); } Modified: head/sys/compat/linuxkpi/common/src/linux_rcu.c ============================================================================== --- head/sys/compat/linuxkpi/common/src/linux_rcu.c Fri Mar 30 19:58:58 2018 (r331827) +++ head/sys/compat/linuxkpi/common/src/linux_rcu.c Fri Mar 30 20:11:12 2018 (r331828) @@ -297,13 +297,13 @@ linux_synchronize_rcu(void) td = curthread; - DROP_GIANT(); - /* * Synchronizing RCU might change the CPU core this function * is running on. Save current values: */ thread_lock(td); + + DROP_GIANT(); old_cpu = PCPU_GET(cpuid); old_pinned = td->td_pinned; Modified: head/sys/compat/linuxkpi/common/src/linux_schedule.c ============================================================================== --- head/sys/compat/linuxkpi/common/src/linux_schedule.c Fri Mar 30 19:58:58 2018 (r331827) +++ head/sys/compat/linuxkpi/common/src/linux_schedule.c Fri Mar 30 20:11:12 2018 (r331828) @@ -55,6 +55,8 @@ linux_add_to_sleepqueue(void *wchan, struct task_struc sleepq_add(wchan, NULL, wmesg, flags, 0); if (timeout != 0) sleepq_set_timeout(wchan, timeout); + + DROP_GIANT(); if ((state & TASK_INTERRUPTIBLE) != 0) { if (timeout == 0) ret = -sleepq_wait_sig(wchan, 0); @@ -67,6 +69,8 @@ linux_add_to_sleepqueue(void *wchan, struct task_struc } else ret = -sleepq_timedwait(wchan, 0); } + PICKUP_GIANT(); + /* filter return value */ if (ret != 0 && ret != -EWOULDBLOCK) { linux_schedule_save_interrupt_value(task, ret); @@ -248,8 +252,6 @@ linux_wait_event_common(wait_queue_head_t *wqh, wait_q if (lock != NULL) spin_unlock_irq(lock); - DROP_GIANT(); - /* range check timeout */ if (timeout < 1) timeout = 1; @@ -272,8 +274,6 @@ linux_wait_event_common(wait_queue_head_t *wqh, wait_q } PRELE(task->task_thread->td_proc); - PICKUP_GIANT(); - if (lock != NULL) spin_lock_irq(lock); return (ret); @@ -297,8 +297,6 @@ linux_schedule_timeout(int timeout) remainder = ticks + timeout; - DROP_GIANT(); - sleepq_lock(task); state = atomic_read(&task->state); if (state != TASK_WAKING) { @@ -309,8 +307,6 @@ linux_schedule_timeout(int timeout) } set_task_state(task, TASK_RUNNING); - PICKUP_GIANT(); - if (timeout == 0) return (MAX_SCHEDULE_TIMEOUT); @@ -356,8 +352,6 @@ linux_wait_on_bit_timeout(unsigned long *word, int bit void *wchan; int ret; - DROP_GIANT(); - /* range check timeout */ if (timeout < 1) timeout = 1; @@ -380,8 +374,6 @@ linux_wait_on_bit_timeout(unsigned long *word, int bit } set_task_state(task, TASK_RUNNING); - PICKUP_GIANT(); - return (ret); } @@ -399,8 +391,6 @@ linux_wait_on_atomic_t(atomic_t *a, unsigned int state void *wchan; int ret; - DROP_GIANT(); - task = current; wchan = a; for (;;) { @@ -416,8 +406,6 @@ linux_wait_on_atomic_t(atomic_t *a, unsigned int state break; } set_task_state(task, TASK_RUNNING); - - PICKUP_GIANT(); return (ret); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803302011.w2UKBC8q029559>