Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 230669
b: refs/heads/master
c: 909cc4f
h: refs/heads/master
i:
  230667: 8383e89
v: v3
  • Loading branch information
Jonathan Brassow authored and Alasdair G Kergon committed Jan 13, 2011
1 parent f30cf92 commit 96b70b1
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 10 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: 8d35d3e37eed884ba15229a146df846f399909b4
refs/heads/master: 909cc4fb48dd9870f6ebe4bd32cfbe37c102df62
41 changes: 32 additions & 9 deletions trunk/drivers/md/dm-log-userspace-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,15 @@ struct log_c {
*/
uint64_t in_sync_hint;

/*
* Mark and clear requests are held until a flush is issued
* so that we can group, and thereby limit, the amount of
* network traffic between kernel and userspace. The 'flush_lock'
* is used to protect these lists.
*/
spinlock_t flush_lock;
struct list_head flush_list; /* only for clear and mark requests */
struct list_head mark_list;
struct list_head clear_list;
};

static mempool_t *flush_entry_pool;
Expand Down Expand Up @@ -169,7 +176,8 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,

strncpy(lc->uuid, argv[0], DM_UUID_LEN);
spin_lock_init(&lc->flush_lock);
INIT_LIST_HEAD(&lc->flush_list);
INIT_LIST_HEAD(&lc->mark_list);
INIT_LIST_HEAD(&lc->clear_list);

str_size = build_constructor_string(ti, argc - 1, argv + 1, &ctr_str);
if (str_size < 0) {
Expand Down Expand Up @@ -362,14 +370,16 @@ static int userspace_flush(struct dm_dirty_log *log)
int r = 0;
unsigned long flags;
struct log_c *lc = log->context;
LIST_HEAD(flush_list);
LIST_HEAD(mark_list);
LIST_HEAD(clear_list);
struct flush_entry *fe, *tmp_fe;

spin_lock_irqsave(&lc->flush_lock, flags);
list_splice_init(&lc->flush_list, &flush_list);
list_splice_init(&lc->mark_list, &mark_list);
list_splice_init(&lc->clear_list, &clear_list);
spin_unlock_irqrestore(&lc->flush_lock, flags);

if (list_empty(&flush_list))
if (list_empty(&mark_list) && list_empty(&clear_list))
return 0;

/*
Expand All @@ -379,7 +389,16 @@ static int userspace_flush(struct dm_dirty_log *log)
* do it one by one.
*/

list_for_each_entry(fe, &flush_list, list) {
list_for_each_entry(fe, &mark_list, list) {
r = userspace_do_request(lc, lc->uuid, fe->type,
(char *)&fe->region,
sizeof(fe->region),
NULL, NULL);
if (r)
goto fail;
}

list_for_each_entry(fe, &clear_list, list) {
r = userspace_do_request(lc, lc->uuid, fe->type,
(char *)&fe->region,
sizeof(fe->region),
Expand All @@ -397,7 +416,11 @@ static int userspace_flush(struct dm_dirty_log *log)
* Calling code will receive an error and will know that
* the log facility has failed.
*/
list_for_each_entry_safe(fe, tmp_fe, &flush_list, list) {
list_for_each_entry_safe(fe, tmp_fe, &mark_list, list) {
list_del(&fe->list);
mempool_free(fe, flush_entry_pool);
}
list_for_each_entry_safe(fe, tmp_fe, &clear_list, list) {
list_del(&fe->list);
mempool_free(fe, flush_entry_pool);
}
Expand Down Expand Up @@ -427,7 +450,7 @@ static void userspace_mark_region(struct dm_dirty_log *log, region_t region)
spin_lock_irqsave(&lc->flush_lock, flags);
fe->type = DM_ULOG_MARK_REGION;
fe->region = region;
list_add(&fe->list, &lc->flush_list);
list_add(&fe->list, &lc->mark_list);
spin_unlock_irqrestore(&lc->flush_lock, flags);

return;
Expand Down Expand Up @@ -464,7 +487,7 @@ static void userspace_clear_region(struct dm_dirty_log *log, region_t region)
spin_lock_irqsave(&lc->flush_lock, flags);
fe->type = DM_ULOG_CLEAR_REGION;
fe->region = region;
list_add(&fe->list, &lc->flush_list);
list_add(&fe->list, &lc->clear_list);
spin_unlock_irqrestore(&lc->flush_lock, flags);

return;
Expand Down

0 comments on commit 96b70b1

Please sign in to comment.