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
This commit is contained in:
parent
7cf4e46e9b
commit
bf24bc5621
@ -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) \
|
||||
|
@ -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, int timeout, int flags)
|
||||
if (SCHEDULER_STOPPED())
|
||||
return (0);
|
||||
|
||||
DROP_GIANT();
|
||||
|
||||
task = current;
|
||||
|
||||
if (flags != 0)
|
||||
@ -1866,10 +1865,14 @@ linux_wait_for_timeout_common(struct completion *c, int timeout, int flags)
|
||||
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, int timeout, int flags)
|
||||
/* return how many jiffies are left */
|
||||
error = linux_timer_jiffies_until(end);
|
||||
done:
|
||||
PICKUP_GIANT();
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -297,14 +297,14 @@ 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;
|
||||
old_prio = td->td_priority;
|
||||
|
@ -55,6 +55,8 @@ linux_add_to_sleepqueue(void *wchan, struct task_struct *task,
|
||||
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_struct *task,
|
||||
} 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_queue_t *wq, int timeout,
|
||||
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_queue_t *wq, int timeout,
|
||||
}
|
||||
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, unsigned int state,
|
||||
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, unsigned int state,
|
||||
}
|
||||
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 (;;) {
|
||||
@ -417,8 +407,6 @@ linux_wait_on_atomic_t(atomic_t *a, unsigned int state)
|
||||
}
|
||||
set_task_state(task, TASK_RUNNING);
|
||||
|
||||
PICKUP_GIANT();
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user