From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24597 invoked by alias); 28 Aug 2008 13:49:12 -0000 Received: (qmail 24541 invoked by alias); 28 Aug 2008 13:49:11 -0000 X-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL,BAYES_00,KAM_MX,SPF_HELO_PASS X-Spam-Check-By: sourceware.org X-Spam-Checker-Version: SpamAssassin 3.2.4 (2008-01-01) on bastion.fedora.phx.redhat.com X-Spam-Level: Subject: RHEL5 - dm-log-clustered: Optimization - bundle clear/mark requests To: cluster-cvs-relay@redhat.com X-Project: Cluster Project X-Git-Module: cluster.git X-Git-Refname: refs/heads/RHEL5 X-Git-Reftype: branch X-Git-Oldrev: 9bf373dbb03a185e49e36db5075d50352436b9c1 X-Git-Newrev: 288ee1d7d73d6d4b08dc2ae0d0fb66f70d23f2fd From: Jonathan Brassow Message-Id: <20080828134805.83145120379@lists.fedorahosted.org> Date: Thu, 28 Aug 2008 14:16:00 -0000 X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254 Mailing-List: contact cluster-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: cluster-cvs-owner@sourceware.org X-SW-Source: 2008-q3/txt/msg00349.txt.bz2 Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=288ee1d7d73d6d4b08dc2ae0d0fb66f70d23f2fd Commit: 288ee1d7d73d6d4b08dc2ae0d0fb66f70d23f2fd Parent: 9bf373dbb03a185e49e36db5075d50352436b9c1 Author: Jonathan Brassow AuthorDate: Thu Aug 28 08:46:36 2008 -0500 Committer: Jonathan Brassow CommitterDate: Thu Aug 28 08:47:57 2008 -0500 dm-log-clustered: Optimization - bundle clear/mark requests The order and timing of the clear/mark region requests is not important - as long as they are completed before the next flush. So, we can group requests - sending up to ~50 at a time, reducing netlink and cluster traffic. --- cmirror-kernel/src/dm-clog.c | 72 ++++++++++++++++++++++++++++++++++++++--- 1 files changed, 66 insertions(+), 6 deletions(-) diff --git a/cmirror-kernel/src/dm-clog.c b/cmirror-kernel/src/dm-clog.c index 62ad414..fef062d 100644 --- a/cmirror-kernel/src/dm-clog.c +++ b/cmirror-kernel/src/dm-clog.c @@ -401,10 +401,12 @@ static int cluster_in_sync(struct dirty_log *log, region_t region, int can_block * * Returns: 0 on success, < 0 on failure */ +#define GROUP_SIZE 50 static int cluster_flush(struct dirty_log *log) { - int r = 0; + int size, marks, clears, m, c, r = 0; int flags; + region_t *m_ptr, *c_ptr; struct log_c *lc = (struct log_c *)log->context; LIST_HEAD(flush_list); struct flush_entry *fe, *tmp_fe; @@ -417,21 +419,74 @@ static int cluster_flush(struct dirty_log *log) return 0; /* - * FIXME: Count up requests, group request types, + * Count up requests, group request types, * allocate memory to stick all requests in and * send to server in one go. Failing the allocation, * do it one by one. */ + clears = marks = 0; + + list_for_each_entry(fe, &flush_list, list) { + if (fe->type == DM_CLOG_MARK_REGION) + marks++; + else + clears++; + } + m = marks; + c = clears; + c_ptr = m_ptr = NULL; + + if (marks > 1) + m_ptr = kmalloc(sizeof(*m_ptr)*marks, GFP_KERNEL); + + if (clears > 1) + c_ptr = kmalloc(sizeof(*c_ptr)*clears, GFP_KERNEL); + list_for_each_entry(fe, &flush_list, list) { - r = cluster_do_request(lc, lc->uuid, fe->type, - (char *)&fe->region, - sizeof(fe->region), - NULL, NULL); + if ((fe->type == DM_CLOG_MARK_REGION) && (m_ptr)) + m_ptr[--m] = fe->region; + else if ((fe->type == DM_CLOG_CLEAR_REGION) && (c_ptr)) + c_ptr[--c] = fe->region; + else + r = cluster_do_request(lc, lc->uuid, fe->type, + (char *)&fe->region, + sizeof(fe->region), + NULL, NULL); if (r) goto fail; } + if (m_ptr) { + /* If there is more than GROUP_SIZE, send in groups */ + for (m = 0; m < marks; m += GROUP_SIZE) { + size = ((marks - m) > GROUP_SIZE) ? GROUP_SIZE : (marks - m); + size *= sizeof(*m_ptr); + + r = cluster_do_request(lc, lc->uuid, + DM_CLOG_MARK_REGION, + (char *)(m_ptr + m), size, + NULL, NULL); + if (r) + goto fail; + } + } + + if (c_ptr) { + /* If there is more than GROUP_SIZE, send in groups */ + for (c = 0; c < clears; c += GROUP_SIZE) { + size = ((clears - c) > GROUP_SIZE) ? GROUP_SIZE : (clears - c); + size *= sizeof(*c_ptr); + + r = cluster_do_request(lc, lc->uuid, + DM_CLOG_CLEAR_REGION, + (char *)(c_ptr + c), size, + NULL, NULL); + if (r) + goto fail; + } + } + r = cluster_do_request(lc, lc->uuid, DM_CLOG_FLUSH, NULL, 0, NULL, NULL); @@ -441,6 +496,11 @@ fail: * Calling code will receive an error and will know that * the log facility has failed. */ + if (m_ptr) + kfree(m_ptr); + if (c_ptr) + kfree(c_ptr); + list_for_each_entry_safe(fe, tmp_fe, &flush_list, list) { list_del(&fe->list); mempool_free(fe, flush_entry_pool);