From: Philipp Reisner <philipp.reisner@linbit.com>
To: linux-kernel@vger.kernel.org
Cc: Jens Axboe <axboe@kernel.dk>,
drbd-dev@lists.linbit.com, lars.ellenberg@linbit.com
Subject: [PATCH 14/18] lru_cache: introduce lc_get_cumulative()
Date: Tue, 19 Mar 2013 18:16:55 +0100 [thread overview]
Message-ID: <1363713419-17803-15-git-send-email-philipp.reisner@linbit.com> (raw)
In-Reply-To: <1363713419-17803-1-git-send-email-philipp.reisner@linbit.com>
From: Lars Ellenberg <lars.ellenberg@linbit.com>
New helper to be able to consolidate more updates
into a single transaction.
Without this, we can only grab a single refcount
on an updated element while preparing a transaction.
lc_get_cumulative - like lc_get; also finds to-be-changed elements
@lc: the lru cache to operate on
@enr: the label to look up
Unlike lc_get this also returns the element for @enr, if it is belonging to
a pending transaction, so the return values are like for lc_get(),
plus:
pointer to an element already on the "to_be_changed" list.
In this case, the cache was already marked %LC_DIRTY.
Caller needs to make sure that the pending transaction is completed,
before proceeding to actually use this element.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
---
include/linux/lru_cache.h | 1 +
lib/lru_cache.c | 55 ++++++++++++++++++++++++++++++++++++---------
2 files changed, 46 insertions(+), 10 deletions(-)
diff --git a/include/linux/lru_cache.h b/include/linux/lru_cache.h
index 4019013..4626228 100644
--- a/include/linux/lru_cache.h
+++ b/include/linux/lru_cache.h
@@ -256,6 +256,7 @@ extern void lc_destroy(struct lru_cache *lc);
extern void lc_set(struct lru_cache *lc, unsigned int enr, int index);
extern void lc_del(struct lru_cache *lc, struct lc_element *element);
+extern struct lc_element *lc_get_cumulative(struct lru_cache *lc, unsigned int enr);
extern struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr);
extern struct lc_element *lc_find(struct lru_cache *lc, unsigned int enr);
extern struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr);
diff --git a/lib/lru_cache.c b/lib/lru_cache.c
index d71d894..e8d5003 100644
--- a/lib/lru_cache.c
+++ b/lib/lru_cache.c
@@ -366,7 +366,13 @@ static int lc_unused_element_available(struct lru_cache *lc)
return 0;
}
-static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, bool may_change)
+/* used as internal flags to __lc_get */
+enum {
+ LC_GET_MAY_CHANGE = 1,
+ LC_GET_MAY_USE_UNCOMMITTED = 2,
+};
+
+static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, unsigned int flags)
{
struct lc_element *e;
@@ -381,22 +387,31 @@ static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, bool
* this enr is currently being pulled in already,
* and will be available once the pending transaction
* has been committed. */
- if (e && e->lc_new_number == e->lc_number) {
+ if (e) {
+ if (e->lc_new_number != e->lc_number) {
+ /* It has been found above, but on the "to_be_changed"
+ * list, not yet committed. Don't pull it in twice,
+ * wait for the transaction, then try again...
+ */
+ if (!(flags & LC_GET_MAY_USE_UNCOMMITTED))
+ RETURN(NULL);
+ /* ... unless the caller is aware of the implications,
+ * probably preparing a cumulative transaction. */
+ ++e->refcnt;
+ ++lc->hits;
+ RETURN(e);
+ }
+ /* else: lc_new_number == lc_number; a real hit. */
++lc->hits;
if (e->refcnt++ == 0)
lc->used++;
list_move(&e->list, &lc->in_use); /* Not evictable... */
RETURN(e);
}
+ /* e == NULL */
++lc->misses;
- if (!may_change)
- RETURN(NULL);
-
- /* It has been found above, but on the "to_be_changed" list, not yet
- * committed. Don't pull it in twice, wait for the transaction, then
- * try again */
- if (e)
+ if (!(flags & LC_GET_MAY_CHANGE))
RETURN(NULL);
/* To avoid races with lc_try_lock(), first, mark us dirty
@@ -478,7 +493,27 @@ static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, bool
*/
struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr)
{
- return __lc_get(lc, enr, 1);
+ return __lc_get(lc, enr, LC_GET_MAY_CHANGE);
+}
+
+/**
+ * lc_get_cumulative - like lc_get; also finds to-be-changed elements
+ * @lc: the lru cache to operate on
+ * @enr: the label to look up
+ *
+ * Unlike lc_get this also returns the element for @enr, if it is belonging to
+ * a pending transaction, so the return values are like for lc_get(),
+ * plus:
+ *
+ * pointer to an element already on the "to_be_changed" list.
+ * In this case, the cache was already marked %LC_DIRTY.
+ *
+ * Caller needs to make sure that the pending transaction is completed,
+ * before proceeding to actually use this element.
+ */
+struct lc_element *lc_get_cumulative(struct lru_cache *lc, unsigned int enr)
+{
+ return __lc_get(lc, enr, LC_GET_MAY_CHANGE|LC_GET_MAY_USE_UNCOMMITTED);
}
/**
--
1.7.9.5
next prev parent reply other threads:[~2013-03-19 17:18 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-19 17:16 [PATCH 00/18] RFC: Non blocking submit for activity log misses Philipp Reisner
2013-03-19 17:16 ` [PATCH 01/18] drbd: cleanup bogus assert message Philipp Reisner
2013-03-19 17:16 ` [PATCH 02/18] drbd: cleanup ondisk meta data layout calculations and defines Philipp Reisner
2013-03-19 17:16 ` [PATCH 03/18] drbd: prepare for new striped layout of activity log Philipp Reisner
2013-03-19 17:16 ` [PATCH 04/18] drbd: use the cached meta_dev_idx Philipp Reisner
2013-03-19 17:16 ` [PATCH 05/18] drbd: mechanically rename la_size to la_size_sect Philipp Reisner
2013-03-19 17:16 ` [PATCH 06/18] drbd: read meta data early, base on-disk offsets on super block Philipp Reisner
2013-03-19 17:16 ` [PATCH 07/18] drbd: Clarify when activity log I/O is delegated to the worker thread Philipp Reisner
2013-03-19 17:16 ` [PATCH 08/18] drbd: drbd_al_being_io: short circuit to reduce latency Philipp Reisner
2013-03-19 17:16 ` [PATCH 09/18] drbd: split __drbd_make_request in before and after drbd_al_begin_io Philipp Reisner
2013-03-19 17:16 ` [PATCH 10/18] drbd: prepare to queue write requests on a submit worker Philipp Reisner
2013-03-22 20:22 ` [Drbd-dev] [PATCH 10/18, update] " lars.ellenberg
2013-03-23 0:15 ` Jens Axboe
2013-03-19 17:16 ` [PATCH 11/18] drbd: split drbd_al_begin_io into fastpath, prepare, and commit Philipp Reisner
2013-03-19 17:16 ` [PATCH 12/18] drbd: split out some helper functions to drbd_al_begin_io Philipp Reisner
2013-03-19 17:16 ` [PATCH 13/18] drbd: queue writes on submitter thread, unless they pass the activity log fastpath Philipp Reisner
2013-03-19 17:16 ` Philipp Reisner [this message]
2013-03-19 17:16 ` [PATCH 15/18] drbd: consolidate as many updates as possible into one AL transaction Philipp Reisner
2013-03-19 17:16 ` [PATCH 16/18] drbd: move start io accounting before activity log transaction Philipp Reisner
2013-03-19 17:16 ` [PATCH 17/18] drbd: try hard to max out the updates per AL transaction Philipp Reisner
2013-03-19 17:16 ` [PATCH 18/18] drbd: adjust upper limit for activity log extents Philipp Reisner
2013-03-22 17:17 ` [PATCH 00/18] RFC: Non blocking submit for activity log misses Jens Axboe
2013-03-22 20:03 ` [Drbd-dev] " lars.ellenberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1363713419-17803-15-git-send-email-philipp.reisner@linbit.com \
--to=philipp.reisner@linbit.com \
--cc=axboe@kernel.dk \
--cc=drbd-dev@lists.linbit.com \
--cc=lars.ellenberg@linbit.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®