Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 168826
b: refs/heads/master
c: 5753c44
h: refs/heads/master
v: v3
  • Loading branch information
David Howells committed Nov 19, 2009
1 parent ad45b18 commit 2cce470
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 40 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b34df792b4e9e311db47fad27949095d0629c197
refs/heads/master: 5753c441889253e4323eee85f791a1d64cf08196
2 changes: 2 additions & 0 deletions trunk/Documentation/filesystems/caching/fscache.txt
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ proc files.
ok=N Number of successful alloc reqs
wt=N Number of alloc reqs that waited on lookup completion
nbf=N Number of alloc reqs rejected -ENOBUFS
int=N Number of alloc reqs aborted -ERESTARTSYS
ops=N Number of alloc reqs submitted
owt=N Number of alloc reqs waited for CPU time
Retrvls n=N Number of retrieval (read) requests seen
Expand All @@ -271,6 +272,7 @@ proc files.
Ops pend=N Number of times async ops added to pending queues
run=N Number of times async ops given CPU time
enq=N Number of times async ops queued for processing
can=N Number of async ops cancelled
dfr=N Number of async ops queued for deferred release
rel=N Number of async ops released
gc=N Number of deferred-release async ops garbage collected
Expand Down
3 changes: 3 additions & 0 deletions trunk/fs/fscache/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ extern int fscache_submit_exclusive_op(struct fscache_object *,
struct fscache_operation *);
extern int fscache_submit_op(struct fscache_object *,
struct fscache_operation *);
extern int fscache_cancel_op(struct fscache_operation *);
extern void fscache_abort_object(struct fscache_object *);
extern void fscache_start_operations(struct fscache_object *);
extern void fscache_operation_gc(struct work_struct *);
Expand Down Expand Up @@ -140,6 +141,7 @@ extern atomic_t fscache_n_op_enqueue;
extern atomic_t fscache_n_op_deferred_release;
extern atomic_t fscache_n_op_release;
extern atomic_t fscache_n_op_gc;
extern atomic_t fscache_n_op_cancelled;

extern atomic_t fscache_n_attr_changed;
extern atomic_t fscache_n_attr_changed_ok;
Expand All @@ -151,6 +153,7 @@ extern atomic_t fscache_n_allocs;
extern atomic_t fscache_n_allocs_ok;
extern atomic_t fscache_n_allocs_wait;
extern atomic_t fscache_n_allocs_nobufs;
extern atomic_t fscache_n_allocs_intr;
extern atomic_t fscache_n_alloc_ops;
extern atomic_t fscache_n_alloc_op_waits;

Expand Down
82 changes: 54 additions & 28 deletions trunk/fs/fscache/operation.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,32 +34,31 @@ void fscache_enqueue_operation(struct fscache_operation *op)

fscache_set_op_state(op, "EnQ");

ASSERT(list_empty(&op->pend_link));
ASSERT(op->processor != NULL);
ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE);
ASSERTCMP(atomic_read(&op->usage), >, 0);

if (list_empty(&op->pend_link)) {
switch (op->flags & FSCACHE_OP_TYPE) {
case FSCACHE_OP_FAST:
_debug("queue fast");
atomic_inc(&op->usage);
if (!schedule_work(&op->fast_work))
fscache_put_operation(op);
break;
case FSCACHE_OP_SLOW:
_debug("queue slow");
slow_work_enqueue(&op->slow_work);
break;
case FSCACHE_OP_MYTHREAD:
_debug("queue for caller's attention");
break;
default:
printk(KERN_ERR "FS-Cache: Unexpected op type %lx",
op->flags);
BUG();
break;
}
fscache_stat(&fscache_n_op_enqueue);
fscache_stat(&fscache_n_op_enqueue);
switch (op->flags & FSCACHE_OP_TYPE) {
case FSCACHE_OP_FAST:
_debug("queue fast");
atomic_inc(&op->usage);
if (!schedule_work(&op->fast_work))
fscache_put_operation(op);
break;
case FSCACHE_OP_SLOW:
_debug("queue slow");
slow_work_enqueue(&op->slow_work);
break;
case FSCACHE_OP_MYTHREAD:
_debug("queue for caller's attention");
break;
default:
printk(KERN_ERR "FS-Cache: Unexpected op type %lx",
op->flags);
BUG();
break;
}
}
EXPORT_SYMBOL(fscache_enqueue_operation);
Expand Down Expand Up @@ -97,6 +96,7 @@ int fscache_submit_exclusive_op(struct fscache_object *object,
spin_lock(&object->lock);
ASSERTCMP(object->n_ops, >=, object->n_in_progress);
ASSERTCMP(object->n_ops, >=, object->n_exclusive);
ASSERT(list_empty(&op->pend_link));

ret = -ENOBUFS;
if (fscache_object_is_active(object)) {
Expand Down Expand Up @@ -202,6 +202,7 @@ int fscache_submit_op(struct fscache_object *object,
spin_lock(&object->lock);
ASSERTCMP(object->n_ops, >=, object->n_in_progress);
ASSERTCMP(object->n_ops, >=, object->n_exclusive);
ASSERT(list_empty(&op->pend_link));

ostate = object->state;
smp_rmb();
Expand Down Expand Up @@ -273,12 +274,7 @@ void fscache_start_operations(struct fscache_object *object)
stop = true;
}
list_del_init(&op->pend_link);
object->n_in_progress++;

if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
if (op->processor)
fscache_enqueue_operation(op);
fscache_run_op(object, op);

/* the pending queue was holding a ref on the object */
fscache_put_operation(op);
Expand All @@ -290,6 +286,36 @@ void fscache_start_operations(struct fscache_object *object)
object->n_in_progress, object->debug_id);
}

/*
* cancel an operation that's pending on an object
*/
int fscache_cancel_op(struct fscache_operation *op)
{
struct fscache_object *object = op->object;
int ret;

_enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id);

spin_lock(&object->lock);

ret = -EBUSY;
if (!list_empty(&op->pend_link)) {
fscache_stat(&fscache_n_op_cancelled);
list_del_init(&op->pend_link);
object->n_ops--;
if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
object->n_exclusive--;
if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
fscache_put_operation(op);
ret = 0;
}

spin_unlock(&object->lock);
_leave(" = %d", ret);
return ret;
}

/*
* release an operation
* - queues pending ops if this is the last in-progress op
Expand Down
55 changes: 48 additions & 7 deletions trunk/fs/fscache/page.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,20 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
_debug(">>> WT");
fscache_stat(&fscache_n_retrieval_op_waits);
wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
fscache_wait_bit, TASK_UNINTERRUPTIBLE);
if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
fscache_wait_bit_interruptible,
TASK_INTERRUPTIBLE) < 0) {
ret = fscache_cancel_op(&op->op);
if (ret == 0) {
ret = -ERESTARTSYS;
goto error;
}

/* it's been removed from the pending queue by another
* party, so we should get to run shortly */
wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
fscache_wait_bit, TASK_UNINTERRUPTIBLE);
}
_debug("<<< GO");
}

Expand All @@ -313,6 +325,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
fscache_stat_d(&fscache_n_cop_read_or_alloc_page);
}

error:
if (ret == -ENOMEM)
fscache_stat(&fscache_n_retrievals_nomem);
else if (ret == -ERESTARTSYS)
Expand Down Expand Up @@ -412,8 +425,20 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
_debug(">>> WT");
fscache_stat(&fscache_n_retrieval_op_waits);
wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
fscache_wait_bit, TASK_UNINTERRUPTIBLE);
if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
fscache_wait_bit_interruptible,
TASK_INTERRUPTIBLE) < 0) {
ret = fscache_cancel_op(&op->op);
if (ret == 0) {
ret = -ERESTARTSYS;
goto error;
}

/* it's been removed from the pending queue by another
* party, so we should get to run shortly */
wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
fscache_wait_bit, TASK_UNINTERRUPTIBLE);
}
_debug("<<< GO");
}

Expand All @@ -430,6 +455,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
fscache_stat_d(&fscache_n_cop_read_or_alloc_pages);
}

error:
if (ret == -ENOMEM)
fscache_stat(&fscache_n_retrievals_nomem);
else if (ret == -ERESTARTSYS)
Expand Down Expand Up @@ -505,8 +531,20 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
_debug(">>> WT");
fscache_stat(&fscache_n_alloc_op_waits);
wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
fscache_wait_bit, TASK_UNINTERRUPTIBLE);
if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
fscache_wait_bit_interruptible,
TASK_INTERRUPTIBLE) < 0) {
ret = fscache_cancel_op(&op->op);
if (ret == 0) {
ret = -ERESTARTSYS;
goto error;
}

/* it's been removed from the pending queue by another
* party, so we should get to run shortly */
wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
fscache_wait_bit, TASK_UNINTERRUPTIBLE);
}
_debug("<<< GO");
}

Expand All @@ -515,7 +553,10 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
ret = object->cache->ops->allocate_page(op, page, gfp);
fscache_stat_d(&fscache_n_cop_allocate_page);

if (ret < 0)
error:
if (ret == -ERESTARTSYS)
fscache_stat(&fscache_n_allocs_intr);
else if (ret < 0)
fscache_stat(&fscache_n_allocs_nobufs);
else
fscache_stat(&fscache_n_allocs_ok);
Expand Down
12 changes: 8 additions & 4 deletions trunk/fs/fscache/stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ atomic_t fscache_n_op_requeue;
atomic_t fscache_n_op_deferred_release;
atomic_t fscache_n_op_release;
atomic_t fscache_n_op_gc;
atomic_t fscache_n_op_cancelled;

atomic_t fscache_n_attr_changed;
atomic_t fscache_n_attr_changed_ok;
Expand All @@ -36,6 +37,7 @@ atomic_t fscache_n_allocs;
atomic_t fscache_n_allocs_ok;
atomic_t fscache_n_allocs_wait;
atomic_t fscache_n_allocs_nobufs;
atomic_t fscache_n_allocs_intr;
atomic_t fscache_n_alloc_ops;
atomic_t fscache_n_alloc_op_waits;

Expand Down Expand Up @@ -169,11 +171,12 @@ static int fscache_stats_show(struct seq_file *m, void *v)
atomic_read(&fscache_n_attr_changed_nomem),
atomic_read(&fscache_n_attr_changed_calls));

seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u\n",
seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u int=%u\n",
atomic_read(&fscache_n_allocs),
atomic_read(&fscache_n_allocs_ok),
atomic_read(&fscache_n_allocs_wait),
atomic_read(&fscache_n_allocs_nobufs));
atomic_read(&fscache_n_allocs_nobufs),
atomic_read(&fscache_n_allocs_intr));
seq_printf(m, "Allocs : ops=%u owt=%u\n",
atomic_read(&fscache_n_alloc_ops),
atomic_read(&fscache_n_alloc_op_waits));
Expand Down Expand Up @@ -201,10 +204,11 @@ static int fscache_stats_show(struct seq_file *m, void *v)
atomic_read(&fscache_n_store_ops),
atomic_read(&fscache_n_store_calls));

seq_printf(m, "Ops : pend=%u run=%u enq=%u\n",
seq_printf(m, "Ops : pend=%u run=%u enq=%u can=%u\n",
atomic_read(&fscache_n_op_pend),
atomic_read(&fscache_n_op_run),
atomic_read(&fscache_n_op_enqueue));
atomic_read(&fscache_n_op_enqueue),
atomic_read(&fscache_n_op_cancelled));
seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n",
atomic_read(&fscache_n_op_deferred_release),
atomic_read(&fscache_n_op_release),
Expand Down

0 comments on commit 2cce470

Please sign in to comment.