From patchwork Sun Mar 28 17:06:16 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Vainman X-Patchwork-Id: 88787 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o2SH6MRc028928 for ; Sun, 28 Mar 2010 17:06:22 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753814Ab0C1RGV (ORCPT ); Sun, 28 Mar 2010 13:06:21 -0400 Received: from fwil.voltaire.com ([193.47.165.2]:52279 "EHLO exil.voltaire.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752930Ab0C1RGV (ORCPT ); Sun, 28 Mar 2010 13:06:21 -0400 Received: from [172.25.5.1] ([172.25.5.1]) by exil.voltaire.com with Microsoft SMTPSVC(6.0.3790.3959); Sun, 28 Mar 2010 20:06:16 +0300 Message-ID: <4BAF8C88.80909@gmail.com> Date: Sun, 28 Mar 2010 20:06:16 +0300 From: Alex Vainman Reply-To: alexv@voltaire.com User-Agent: Thunderbird 2.0.0.23 (Windows/20090812) MIME-Version: 1.0 To: Roland Dreier , roland CC: linux-rdma@vger.kernel.org, alexr@voltaire.com Subject: [PATCH v3 4/4] libibverbs: Undo changes in memory range tree when madvise() fails X-OriginalArrivalTime: 28 Mar 2010 17:06:16.0580 (UTC) FILETIME=[FA74F440:01CACE98] Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Sun, 28 Mar 2010 17:06:22 +0000 (UTC) diff --git a/src/memory.c b/src/memory.c index 03f49c8..14f5bc5 100644 --- a/src/memory.c +++ b/src/memory.c @@ -527,18 +527,19 @@ static int ibv_madvise_range(void *base, size_t size, int advice) uintptr_t start, end; struct ibv_mem_node *node, *tmp; int inc; + int rolling_back = 0; int ret = 0; if (!size) return 0; - inc = advice == MADV_DONTFORK ? 1 : -1; - start = (uintptr_t) base & ~(page_size - 1); end = ((uintptr_t) (base + size + page_size - 1) & ~(page_size - 1)) - 1; pthread_mutex_lock(&mm_mutex); +again: + inc = advice == MADV_DONTFORK ? 1 : -1; node = get_start_node(start, end, inc); if (!node) { @@ -576,7 +577,19 @@ static int ibv_madvise_range(void *base, size_t size, int advice) advice); if (ret) { node = undo_node(node, start, inc); - goto out; + + if (rolling_back || !node) + goto out; + + /* madvise failed, roll back previous changes */ + rolling_back = 1; + advice = advice == MADV_DONTFORK ? MADV_DOFORK : + MADV_DONTFORK; + tmp = __mm_prev(node); + if (!tmp || start > tmp->end) + goto out; + end = tmp->end; + goto again; } } @@ -591,6 +604,8 @@ static int ibv_madvise_range(void *base, size_t size, int advice) } out: + if (rolling_back) + ret = -1; pthread_mutex_unlock(&mm_mutex); return ret;