From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id oAT0Zh4M071378 for ; Sun, 28 Nov 2010 18:35:43 -0600 Received: from mail.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id E770F1C7CBC2 for ; Sun, 28 Nov 2010 16:37:23 -0800 (PST) Received: from mail.internode.on.net (bld-mail16.adl2.internode.on.net [150.101.137.101]) by cuda.sgi.com with ESMTP id 9CdzTAsTQxNw8WYG for ; Sun, 28 Nov 2010 16:37:23 -0800 (PST) From: Dave Chinner Subject: =?UTF-8?q?=5BPATCH=201/3=5D=20lib=3A=20percpu=20counter=20add=20unless=20less=20than=20functionality?= Date: Mon, 29 Nov 2010 11:36:39 +1100 Message-Id: <1290991002-18680-2-git-send-email-david@fromorbit.com> In-Reply-To: <1290991002-18680-1-git-send-email-david@fromorbit.com> References: <1290991002-18680-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 List-Id: XFS Filesystem from SGI List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: xfs-bounces@oss.sgi.com Errors-To: xfs-bounces@oss.sgi.com To: xfs@oss.sgi.com Cc: linux-kernel@vger.kernel.org, a.p.zijlstra@chello.nl RnJvbTogRGF2ZSBDaGlubmVyIDxkY2hpbm5lckByZWRoYXQuY29tPgoKVG8gdXNlIHRoZSBnZW5l cmljIHBlcmNwdSBjb3VudGVyIGluZnJhc3RydWN0dXJlIGZvciBjb3VudGVycyB0aGF0CnJlcXVp cmUgY29uZGl0aW9uYWwgYWRkaXRpb24gYmFzZWQgb24gYSB0aHJlc2hvbGQgdmFsdWUgd2UgbmVl ZApzcGVjaWFsIGhhbmRsaW5nIG9mIHRoZSBjb3VudGVyLiBGdXJ0aGVyLCB0aGUgY2FsbGVyIG5l ZWRzIHRvIGtub3cKdGhlIHN0YXR1cyBvZiB0aGUgY29uZGl0aW9uYWwgYWRkaXRpb24gdG8gZGV0 ZXJtaW5lIHdoYXQgYWN0aW9uIHRvCnRha2UgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIGFkZGl0 aW9uIG9jY3VycmVkIG9yIG5vdC4gIEV4YW1wbGVzIG9mCnRoaXMgc29ydCBvZiB1c2FnZSBhcmUg cmVzb3VyY2UgY291bnRlcnMgdGhhdCBjYW5ub3QgZ28gYmVsb3cgemVybwooZS5nLiBmaWxlc3lz dGVtIGZyZWUgYmxvY2tzKS4KClRvIGFsbG93IFhGUyB0byByZXBsYWNlIGl0J3MgY29tcGxleCBy b2xsLXlvdXItb3duIHBlci1jcHUKc3VwZXJibG9jayBjb3VudGVycywgYSBzaW5nbGUgZ2VuZXJp YyBjb25kaXRpb25hbCBmdW5jdGlvbiBpcwpyZXF1aXJlZDogcGVyY3B1X2NvdW50ZXJfYWRkX3Vu bGVzc19sdCgpLiBUaGlzIHdpbGwgYWRkIHRoZSBhbW91bnQKdG8gdGhlIGNvdW50ZXIgdW5sZXNz IHRoZSByZXN1bHQgd291bGQgYmUgbGVzcyB0aGFuIHRoZSBnaXZlbgp0aHJlc2hvbGQuIEEgY2Fs bGVyIHN1cHBsaWVkIHRocmVzaG9sZCBpcyByZXF1aXJlZCBiZWNhdXNlIFhGUyBkb2VzCm5vdCBu ZWNlc3NhcmlseSB1c2UgdGhlIHNhbWUgdGhyZXNob2xkIGZvciBldmVyeSBjb3VudGVyLgoKcGVy Y3B1X2NvdW50ZXJfYWRkX3VubGVzc19sdCgpIGF0dGVtcHRzIHRvIG1pbmltaXNlIGNvdW50ZXIg bG9jawp0cmF2ZXJzYWxzIGJ5IG9ubHkgdGFraW5nIHRoZSBjb3VudGVyIGxvY2sgd2hlbiB0aGUg dGhyZXNob2xkIGlzCndpdGhpbiB0aGUgZXJyb3IgcmFuZ2Ugb2YgdGhlIGN1cnJlbnQgY291bnRl ciB2YWx1ZS4gSGVuY2Ugd2hlbiB0aGUKdGhyZXNob2xkIGlzIG5vdCB3aXRoaW4gdGhlIGNvdW50 ZXIgZXJyb3IgcmFuZ2UsIHRoZSBjb3VudGVyIHdpbGwKc3RpbGwgaGF2ZSB0aGUgc2FtZSBzY2Fs YWJpbGl0eSBjaGFyYWN0ZXJpc3RpY3MgYXMgdGhlIG5vcm1hbApwZXJjcHVfY291bnRlcl9hZGQo KSBmdW5jdGlvbi4KCkFkZGluZyB0aGlzIGZ1bmN0aW9uYWxpdHkgdG8gdGhlIGdlbmVyaWMgcGVy Y3B1IGNvdW50ZXJzIGFsbG93cyB1cwp0byByZW1vdmUgdGhlIG11Y2ggbW9yZSBjb21wbGV4IGFu ZCBsZXNzIGVmZmljaWVudCBYRlMgcGVyY3B1CmNvdW50ZXIgY29kZSAofjcwMCBsaW5lcyBvZiBj b2RlKSBhbmQgcmVwbGFjZSBpdCB3aXRoIGdlbmVyaWMKcGVyY3B1IGNvdW50ZXJzLgoKU2lnbmVk LW9mZi1ieTogRGF2ZSBDaGlubmVyIDxkY2hpbm5lckByZWRoYXQuY29tPgotLS0KIGluY2x1ZGUv bGludXgvcGVyY3B1X2NvdW50ZXIuaCB8ICAgMjAgKysrKysrKysrKwogbGliL3BlcmNwdV9jb3Vu dGVyLmMgICAgICAgICAgIHwgICA3OCArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrCiAyIGZpbGVzIGNoYW5nZWQsIDk4IGluc2VydGlvbnMoKyksIDAgZGVsZXRpb25zKC0p CgpkaWZmIC0tZ2l0IGEvaW5jbHVkZS9saW51eC9wZXJjcHVfY291bnRlci5oIGIvaW5jbHVkZS9s aW51eC9wZXJjcHVfY291bnRlci5oCmluZGV4IDQ2ZjZiYTUuLjQ2NWI2NThmIDEwMDY0NAotLS0g YS9pbmNsdWRlL2xpbnV4L3BlcmNwdV9jb3VudGVyLmgKKysrIGIvaW5jbHVkZS9saW51eC9wZXJj cHVfY291bnRlci5oCkBAIC00MSw2ICs0MSw4IEBAIHZvaWQgcGVyY3B1X2NvdW50ZXJfc2V0KHN0 cnVjdCBwZXJjcHVfY291bnRlciAqZmJjLCBzNjQgYW1vdW50KTsKIHZvaWQgX19wZXJjcHVfY291 bnRlcl9hZGQoc3RydWN0IHBlcmNwdV9jb3VudGVyICpmYmMsIHM2NCBhbW91bnQsIHMzMiBiYXRj aCk7CiBzNjQgX19wZXJjcHVfY291bnRlcl9zdW0oc3RydWN0IHBlcmNwdV9jb3VudGVyICpmYmMp OwogaW50IHBlcmNwdV9jb3VudGVyX2NvbXBhcmUoc3RydWN0IHBlcmNwdV9jb3VudGVyICpmYmMs IHM2NCByaHMpOworaW50IHBlcmNwdV9jb3VudGVyX2FkZF91bmxlc3NfbHQoc3RydWN0IHBlcmNw dV9jb3VudGVyICpmYmMsIHM2NCBhbW91bnQsCisJCQkJCQkJczY0IHRocmVzaG9sZCk7CiAKIHN0 YXRpYyBpbmxpbmUgdm9pZCBwZXJjcHVfY291bnRlcl9hZGQoc3RydWN0IHBlcmNwdV9jb3VudGVy ICpmYmMsIHM2NCBhbW91bnQpCiB7CkBAIC0xNTMsNiArMTU1LDI0IEBAIHN0YXRpYyBpbmxpbmUg aW50IHBlcmNwdV9jb3VudGVyX2luaXRpYWxpemVkKHN0cnVjdCBwZXJjcHVfY291bnRlciAqZmJj KQogCXJldHVybiAxOwogfQogCitzdGF0aWMgaW5saW5lIGludCBwZXJjcHVfY291bnRlcl9hZGRf dW5sZXNzX2x0KHN0cnVjdCBwZXJjcHVfY291bnRlciAqZmJjLCBzNjQgYW1vdW50LAorCQkJCQkJ CXM2NCB0aHJlc2hvbGQpCit7CisJczY0IGNvdW50OworCWludCByZXQgPSDigJAxOworCisJcHJl ZW1wdF9kaXNhYmxlKCk7CisJY291bnQgPSBmYmMtPmNvdW50ICsgYW1vdW50OworCWlmIChjb3Vu dCA8IHRocmVzaG9sZCkKKwkJZ290byBvdXQ7CisJZmJjLT5jb3VudCA9IGNvdW50OworCXJldCA9 IGNvdW50ID09IHRocmVzaG9sZCA/IDAgOiAxOworb3V0OgorCXByZWVtcHRfZW5hYmxlKCk7CisJ cmV0dXJuIHJldDsKK30KKworCiAjZW5kaWYJLyogQ09ORklHX1NNUCAqLwogCiBzdGF0aWMgaW5s aW5lIHZvaWQgcGVyY3B1X2NvdW50ZXJfaW5jKHN0cnVjdCBwZXJjcHVfY291bnRlciAqZmJjKQpk aWZmIC0tZ2l0IGEvbGliL3BlcmNwdV9jb3VudGVyLmMgYi9saWIvcGVyY3B1X2NvdW50ZXIuYwpp bmRleCA2MDQ2NzhkLi5iYTYyNWI3IDEwMDY0NAotLS0gYS9saWIvcGVyY3B1X2NvdW50ZXIuYwor KysgYi9saWIvcGVyY3B1X2NvdW50ZXIuYwpAQCAtMjEzLDYgKzIxMyw4NCBAQCBpbnQgcGVyY3B1 X2NvdW50ZXJfY29tcGFyZShzdHJ1Y3QgcGVyY3B1X2NvdW50ZXIgKmZiYywgczY0IHJocykKIH0K IEVYUE9SVF9TWU1CT0wocGVyY3B1X2NvdW50ZXJfY29tcGFyZSk7CiAKKy8qKgorICogcGVyY3B1 X2NvdW50ZXJfYWRkX3VubGVzc19sdCAtIGFkZCB0byBhIGNvdW50ZXIgYXZvaWRpbmcgdW5kZXJy dW5zCisgKiBAZmJjOgljb3VudGVyCisgKiBAYW1vdW50OglhbW91bnQgdG8gYWRkCisgKiBAdGhy ZXNob2xkOgl1bmRlcnJ1biB0aHJlc2hvbGQKKyAqCisgKiBBZGQgQGFtb3VudCB0byBAZmRjIGlm IGFuZCBvbmx5IGlmIHJlc3VsdCBvZiBhZGRpdGlvbiBpcyBncmVhdGVyIHRoYW4gb3IKKyAqIGVx dWFsIHRvIEB0aHJlc2hvbGQgIFJldHVybiAxIGlmIGdyZWF0ZXIgYW5kIGFkZGVkLCAwIGlmIGVx dWFsIGFuZCBhZGRlZAorICogYW5kIC0xIGlmIGFuZCB1bmRlcnJ1biB3b3VsZCBoYXZlIG9jY3Vy ZWQuCisgKgorICogVGhpcyBpcyB1c2VmdWwgZm9yIG9wZXJhdGlvbnMgdGhhdCBtdXN0IGFjY3Vy YXRlbHkgYW5kIGF0b21pY2FsbHkgb25seSBhZGQgYQorICogZGVsdGEgdG8gYSBjb3VudGVyIGlm IHRoZSByZXN1bHQgaXMgZ3JlYXRlciB0aGFuIGEgZ2l2ZW4gKGUuZy4gZm9yIGZyZWVzcGFjZQor ICogYWNjb3VudGluZyB3aXRoIEVOT1NQQyBjaGVja2luZyBpbiBmaWxlc3lzdGVtcykuCisgKi8K K2ludCBwZXJjcHVfY291bnRlcl9hZGRfdW5sZXNzX2x0KHN0cnVjdCBwZXJjcHVfY291bnRlciAq ZmJjLCBzNjQgYW1vdW50LAorCQkJCQkJczY0IHRocmVzaG9sZCkKK3sKKwlzNjQJY291bnQ7CisJ czY0CWVycm9yID0gMiAqIHBlcmNwdV9jb3VudGVyX2JhdGNoICogbnVtX29ubGluZV9jcHVzKCk7 CisJaW50CWNwdTsKKwlpbnQJcmV0ID0gLTE7CisKKwlwcmVlbXB0X2Rpc2FibGUoKTsKKworCS8q IENoZWNrIHRvIHNlZSBpZiByb3VnaCBjb3VudCB3aWxsIGJlIHN1ZmZpY2llbnQgZm9yIGNvbXBh cmlzb24gKi8KKwljb3VudCA9IHBlcmNwdV9jb3VudGVyX3JlYWQoZmJjKTsKKwlpZiAoY291bnQg KyBhbW91bnQgPCB0aHJlc2hvbGQgLSBlcnJvcikKKwkJZ290byBvdXQ7CisKKwkvKgorCSAqIElm IHRoZSBjb3VudGVyIGlzIG92ZXIgdGhlIHRocmVzaG9sZCBhbmQgdGhlIGNoYW5nZSBpcyBsZXNz IHRoYW4gdGhlCisJICogYmF0Y2ggc2l6ZSwgd2UgbWlnaHQgYmUgYWJsZSB0byBhdm9pZCBsb2Nr aW5nLgorCSAqLworCWlmIChjb3VudCA+IHRocmVzaG9sZCArIGVycm9yICYmIGFicyhhbW91bnQp IDwgcGVyY3B1X2NvdW50ZXJfYmF0Y2gpIHsKKwkJX19wZXJjcHVfY291bnRlcl9hZGQoZmJjLCBh bW91bnQsIHBlcmNwdV9jb3VudGVyX2JhdGNoKTsKKwkJcmV0ID0gMTsKKwkJZ290byBvdXQ7CisJ fQorCisJLyoKKwkgKiBJZiB0aGUgcmVzdWx0IGlzIGlzIG92ZXIgdGhlIGVycm9yIHRocmVzaG9s ZCwgd2UgY2FuIGp1c3QgYWRkIGl0CisJICogaW50byB0aGUgZ2xvYmFsIGNvdW50ZXIgaWdub3Jp bmcgd2hhdCBpcyBpbiB0aGUgcGVyLWNwdSBjb3VudGVycworCSAqIGFzIHRoZXkgd2lsbCBub3Qg Y2hhbmdlIHRoZSByZXN1bHQgb2YgdGhlIGNhbGN1bGF0aW9uLgorCSAqLworCXNwaW5fbG9jaygm ZmJjLT5sb2NrKTsKKwlpZiAoZmJjLT5jb3VudCArIGFtb3VudCA+IHRocmVzaG9sZCArIGVycm9y KSB7CisJCWZiYy0+Y291bnQgKz0gYW1vdW50OworCQlyZXQgPSAxOworCQlnb3RvIG91dF91bmxv Y2s7CisJfQorCisJLyoKKwkgKiBSZXN1bHQgaXMgd2l0aGluZyB0aGUgZXJyb3IgbWFyZ2luLiBS dW4gYW4gb3Blbi1jb2RlZCBzdW0gb2YgdGhlCisJICogcGVyLWNwdSBjb3VudGVycyB0byBnZXQg dGhlIGV4YWN0IHZhbHVlIGF0IHRoaXMgcG9pbnQgaW4gdGltZSwKKwkgKiBhbmQgaWYgdGhlIHJl c3VsdCB3b3VsIGRiZSBhYm92ZSB0aGUgdGhyZXNob2xkLCBhZGQgdGhlIGFtb3VudCB0bworCSAq IHRoZSBnbG9iYWwgY291bnRlci4KKwkgKi8KKwljb3VudCA9IGZiYy0+Y291bnQ7CisJZm9yX2Vh Y2hfb25saW5lX2NwdShjcHUpIHsKKwkJczMyICpwY291bnQgPSBwZXJfY3B1X3B0cihmYmMtPmNv dW50ZXJzLCBjcHUpOworCQljb3VudCArPSAqcGNvdW50OworCX0KKwlXQVJOX09OKGNvdW50IDwg dGhyZXNob2xkKTsKKworCWlmIChjb3VudCArIGFtb3VudCA+PSB0aHJlc2hvbGQpIHsKKwkJcmV0 ID0gMDsKKwkJaWYgKGNvdW50ICsgYW1vdW50ID4gdGhyZXNob2xkKQorCQkJcmV0ID0gMTsKKwkJ ZmJjLT5jb3VudCArPSBhbW91bnQ7CisJfQorb3V0X3VubG9jazoKKwlzcGluX3VubG9jaygmZmJj LT5sb2NrKTsKK291dDoKKwlwcmVlbXB0X2VuYWJsZSgpOworCXJldHVybiByZXQ7Cit9CitFWFBP UlRfU1lNQk9MKHBlcmNwdV9jb3VudGVyX2FkZF91bmxlc3NfbHQpOworCiBzdGF0aWMgaW50IF9f aW5pdCBwZXJjcHVfY291bnRlcl9zdGFydHVwKHZvaWQpCiB7CiAJY29tcHV0ZV9iYXRjaF92YWx1 ZSgpOwotLSAKMS43LjIuMwoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX18KeGZzIG1haWxpbmcgbGlzdAp4ZnNAb3NzLnNnaS5jb20KaHR0cDovL29zcy5zZ2ku Y29tL21haWxtYW4vbGlzdGluZm8veGZzCg== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754511Ab0K2AhY (ORCPT ); Sun, 28 Nov 2010 19:37:24 -0500 Received: from bld-mail16.adl2.internode.on.net ([150.101.137.101]:39765 "EHLO mail.internode.on.net" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754496Ab0K2AhU (ORCPT ); Sun, 28 Nov 2010 19:37:20 -0500 From: Dave Chinner To: xfs@oss.sgi.com Cc: linux-kernel@vger.kernel.org, a.p.zijlstra@chello.nl Subject: =?UTF-8?q?=5BPATCH=201/3=5D=20lib=3A=20percpu=20counter=20add=20unless=20less=20than=20functionality?= Date: Mon, 29 Nov 2010 11:36:39 +1100 Message-Id: <1290991002-18680-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1290991002-18680-1-git-send-email-david@fromorbit.com> References: <1290991002-18680-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dave Chinner To use the generic percpu counter infrastructure for counters that require conditional addition based on a threshold value we need special handling of the counter. Further, the caller needs to know the status of the conditional addition to determine what action to take depending on whether the addition occurred or not. Examples of this sort of usage are resource counters that cannot go below zero (e.g. filesystem free blocks). To allow XFS to replace it's complex roll-your-own per-cpu superblock counters, a single generic conditional function is required: percpu_counter_add_unless_lt(). This will add the amount to the counter unless the result would be less than the given threshold. A caller supplied threshold is required because XFS does not necessarily use the same threshold for every counter. percpu_counter_add_unless_lt() attempts to minimise counter lock traversals by only taking the counter lock when the threshold is within the error range of the current counter value. Hence when the threshold is not within the counter error range, the counter will still have the same scalability characteristics as the normal percpu_counter_add() function. Adding this functionality to the generic percpu counters allows us to remove the much more complex and less efficient XFS percpu counter code (~700 lines of code) and replace it with generic percpu counters. Signed-off-by: Dave Chinner --- include/linux/percpu_counter.h | 20 ++++++++++ lib/percpu_counter.c | 78 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 0 deletions(-) diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 46f6ba5..465b658f 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -41,6 +41,8 @@ void percpu_counter_set(struct percpu_counter *fbc, s64 amount); void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); s64 __percpu_counter_sum(struct percpu_counter *fbc); int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs); +int percpu_counter_add_unless_lt(struct percpu_counter *fbc, s64 amount, + s64 threshold); static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) { @@ -153,6 +155,24 @@ static inline int percpu_counter_initialized(struct percpu_counter *fbc) return 1; } +static inline int percpu_counter_add_unless_lt(struct percpu_counter *fbc, s64 amount, + s64 threshold) +{ + s64 count; + int ret = ‐1; + + preempt_disable(); + count = fbc->count + amount; + if (count < threshold) + goto out; + fbc->count = count; + ret = count == threshold ? 0 : 1; +out: + preempt_enable(); + return ret; +} + + #endif /* CONFIG_SMP */ static inline void percpu_counter_inc(struct percpu_counter *fbc) diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index 604678d..ba625b7 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c @@ -213,6 +213,84 @@ int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) } EXPORT_SYMBOL(percpu_counter_compare); +/** + * percpu_counter_add_unless_lt - add to a counter avoiding underruns + * @fbc: counter + * @amount: amount to add + * @threshold: underrun threshold + * + * Add @amount to @fdc if and only if result of addition is greater than or + * equal to @threshold Return 1 if greater and added, 0 if equal and added + * and -1 if and underrun would have occured. + * + * This is useful for operations that must accurately and atomically only add a + * delta to a counter if the result is greater than a given (e.g. for freespace + * accounting with ENOSPC checking in filesystems). + */ +int percpu_counter_add_unless_lt(struct percpu_counter *fbc, s64 amount, + s64 threshold) +{ + s64 count; + s64 error = 2 * percpu_counter_batch * num_online_cpus(); + int cpu; + int ret = -1; + + preempt_disable(); + + /* Check to see if rough count will be sufficient for comparison */ + count = percpu_counter_read(fbc); + if (count + amount < threshold - error) + goto out; + + /* + * If the counter is over the threshold and the change is less than the + * batch size, we might be able to avoid locking. + */ + if (count > threshold + error && abs(amount) < percpu_counter_batch) { + __percpu_counter_add(fbc, amount, percpu_counter_batch); + ret = 1; + goto out; + } + + /* + * If the result is is over the error threshold, we can just add it + * into the global counter ignoring what is in the per-cpu counters + * as they will not change the result of the calculation. + */ + spin_lock(&fbc->lock); + if (fbc->count + amount > threshold + error) { + fbc->count += amount; + ret = 1; + goto out_unlock; + } + + /* + * Result is withing the error margin. Run an open-coded sum of the + * per-cpu counters to get the exact value at this point in time, + * and if the result woul dbe above the threshold, add the amount to + * the global counter. + */ + count = fbc->count; + for_each_online_cpu(cpu) { + s32 *pcount = per_cpu_ptr(fbc->counters, cpu); + count += *pcount; + } + WARN_ON(count < threshold); + + if (count + amount >= threshold) { + ret = 0; + if (count + amount > threshold) + ret = 1; + fbc->count += amount; + } +out_unlock: + spin_unlock(&fbc->lock); +out: + preempt_enable(); + return ret; +} +EXPORT_SYMBOL(percpu_counter_add_unless_lt); + static int __init percpu_counter_startup(void) { compute_batch_value(); -- 1.7.2.3