projects/linux·commit 8ec8ba8e

Merge git://git.kvack.org/~bcrl/aio-fixes

8ec8ba8e · Linus Torvalds <[email protected]> · 2014-07-14 17:11:50 -07:00

Pull another aio fix from Ben LaHaise:
 "put_reqs_available() can now be called from within irq context, which
  means that it (and its sibling function get_reqs_available()) now need
  to be irq-safe, not just preempt-safe"

* git://git.kvack.org/~bcrl/aio-fixes:
  aio: protect reqs_available updates from changes in interrupt handlers
Commit
8ec8ba8e7d5b3cdfedf62e46cfa55c8e36172a2d
Parents
3cf521f7 · 263782c1

Merge commit. Changes below are compared with the first parent: 3cf521f7.

Changes

1 files changed · +7 −0

FileStatusAddDelContent
fs/aio.cmodified+7−0View file

fs/aio.c

View file
diff --git a/fs/aio.c b/fs/aio.c
index 955947e..1c9c5f0 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -830,16 +830,20 @@ void exit_aio(struct mm_struct *mm)
static void put_reqs_available(struct kioctx *ctx, unsigned nr)
{
struct kioctx_cpu *kcpu;
+ unsigned long flags;
preempt_disable();
kcpu = this_cpu_ptr(ctx->cpu);
+ local_irq_save(flags);
kcpu->reqs_available += nr;
+
while (kcpu->reqs_available >= ctx->req_batch * 2) {
kcpu->reqs_available -= ctx->req_batch;
atomic_add(ctx->req_batch, &ctx->reqs_available);
}
+ local_irq_restore(flags);
preempt_enable();
}
@@ -847,10 +851,12 @@ static bool get_reqs_available(struct kioctx *ctx)
{
struct kioctx_cpu *kcpu;
bool ret = false;
+ unsigned long flags;
preempt_disable();
kcpu = this_cpu_ptr(ctx->cpu);
+ local_irq_save(flags);
if (!kcpu->reqs_available) {
int old, avail = atomic_read(&ctx->reqs_available);
@@ -869,6 +875,7 @@ static bool get_reqs_available(struct kioctx *ctx)
ret = true;
kcpu->reqs_available--;
out:
+ local_irq_restore(flags);
preempt_enable();
return ret;
}