From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Subject: [PATCH 5/8] PM: suspend_block: Add suspend_blocker stats Date: Tue, 27 Apr 2010 21:31:56 -0700 Message-ID: <1272429119-12103-6-git-send-email-arve@android.com> References: <1272429119-12103-1-git-send-email-arve@android.com> <1272429119-12103-2-git-send-email-arve@android.com> <1272429119-12103-3-git-send-email-arve@android.com> <1272429119-12103-4-git-send-email-arve@android.com> <1272429119-12103-5-git-send-email-arve@android.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1272429119-12103-5-git-send-email-arve@android.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-pm-bounces@lists.linux-foundation.org Errors-To: linux-pm-bounces@lists.linux-foundation.org To: linux-pm@lists.linux-foundation.org, linux-kernel@vger.kernel.org Cc: Len Brown , Oleg Nesterov , Jesse Barnes , Tejun Heo , Magnus Damm , Andrew Morton , Wu Fengguang List-Id: linux-pm@vger.kernel.org UmVwb3J0IHN1c3BlbmQgYmxvY2sgc3RhdHMgaW4gL3N5cy9rZXJuZWwvZGVidWcvc3VzcGVuZF9i bG9ja2Vycy4KClNpZ25lZC1vZmYtYnk6IEFydmUgSGrDuG5uZXbDpWcgPGFydmVAYW5kcm9pZC5j b20+Ci0tLQogaW5jbHVkZS9saW51eC9zdXNwZW5kX2Jsb2NrZXIuaCB8ICAgMjEgKysrKy0KIGtl cm5lbC9wb3dlci9LY29uZmlnICAgICAgICAgICAgfCAgICA3ICsrCiBrZXJuZWwvcG93ZXIvcG93 ZXIuaCAgICAgICAgICAgIHwgICAgNiArLQoga2VybmVsL3Bvd2VyL3N1c3BlbmQuYyAgICAgICAg ICB8ICAgIDQgKy0KIGtlcm5lbC9wb3dlci9zdXNwZW5kX2Jsb2NrZXIuYyAgfCAgMTkxICsrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKystLQogNSBmaWxlcyBjaGFuZ2VkLCAyMTkg aW5zZXJ0aW9ucygrKSwgMTAgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvaW5jbHVkZS9saW51 eC9zdXNwZW5kX2Jsb2NrZXIuaCBiL2luY2x1ZGUvbGludXgvc3VzcGVuZF9ibG9ja2VyLmgKaW5k ZXggZjk5MjhjYy4uYzgwNzY0YyAxMDA3NTUKLS0tIGEvaW5jbHVkZS9saW51eC9zdXNwZW5kX2Js b2NrZXIuaAorKysgYi9pbmNsdWRlL2xpbnV4L3N1c3BlbmRfYmxvY2tlci5oCkBAIC0xNywxMiAr MTcsMjEgQEAKICNkZWZpbmUgX0xJTlVYX1NVU1BFTkRfQkxPQ0tFUl9ICiAKICNpbmNsdWRlIDxs aW51eC9saXN0Lmg+CisjaW5jbHVkZSA8bGludXgva3RpbWUuaD4KIAogLyoqCiAgKiBzdHJ1Y3Qg c3VzcGVuZF9ibG9ja2VyIC0gdGhlIGJhc2ljIHN1c3BlbmRfYmxvY2tlciBzdHJ1Y3R1cmUKICAq IEBsaW5rOglMaXN0IGVudHJ5IGZvciBhY3RpdmUgb3IgaW5hY3RpdmUgbGlzdC4KLSAqIEBmbGFn czoJVHJhY2tzIGluaXRpYWxpemVkIGFuZCBhY3RpdmUgc3RhdGUuCisgKiBAZmxhZ3M6CVRyYWNr cyBpbml0aWFsaXplZCwgYWN0aXZlIGFuZCBzdGF0cyBzdGF0ZS4KICAqIEBuYW1lOglOYW1lIHVz ZWQgZm9yIGRlYnVnZ2luZy4KKyAqIEBjb3VudDoJTnVtYmVyIG9mIHRpbWVzIHRoaXMgYmxvY2tl ciBoYXMgYmVlbiBkZWFjaXZhdGVkCisgKiBAd2FrZXVwX2NvdW50OiBOdW1iZXIgb2YgdGltZXMg dGhpcyBibG9ja2VyIHdhcyB0aGUgZmlyc3QgdG8gYmxvY2sgc3VzcGVuZAorICoJCWFmdGVyIHJl c3VtZS4KKyAqIEB0b3RhbF90aW1lOglUb3RhbCB0aW1lIHRoaXMgc3VzcGVuZCBibG9ja2VyIGhh cyBwcmV2ZW50ZWQgc3VzcGVuZC4KKyAqIEBwcmV2ZW50X3N1c3BlbmRfdGltZTogVGltZSB0aGlz IHN1c3BlbmQgYmxvY2tlciBoYXMgcHJldmVudGVkIHN1c3BlbmQgd2hpbGUKKyAqCQl1c2VyLXNw YWNlIHJlcXVlc3RlZCBzdXNwZW5kLgorICogQG1heF90aW1lOglNYXggdGltZSB0aGlzIHN1c3Bl bmQgYmxvY2tlciBoYXMgYmVlbiBjb250aW51b3VzbHkgYWN0aXZlCisgKiBAbGFzdF90aW1lOglN b25vdG9uaWMgY2xvY2sgd2hlbiB0aGUgYWN0aXZlIHN0YXRlIGxhc3QgY2hhbmdlZC4KICAqCiAg KiBXaGVuIGEgc3VzcGVuZF9ibG9ja2VyIGlzIGFjdGl2ZSBpdCBwcmV2ZW50cyB0aGUgc3lzdGVt IGZyb20gZW50ZXJpbmcKICAqIG9wcG9ydHVuaXN0aWMgc3VzcGVuZC4KQEAgLTM1LDYgKzQ0LDE2 IEBAIHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgewogCXN0cnVjdCBsaXN0X2hlYWQgICAgbGluazsK IAlpbnQgICAgICAgICAgICAgICAgIGZsYWdzOwogCWNvbnN0IGNoYXIgICAgICAgICAqbmFtZTsK KyNpZmRlZiBDT05GSUdfU1VTUEVORF9CTE9DS0VSX1NUQVRTCisJc3RydWN0IHsKKwkJaW50ICAg ICAgICAgICAgIGNvdW50OworCQlpbnQgICAgICAgICAgICAgd2FrZXVwX2NvdW50OworCQlrdGlt ZV90ICAgICAgICAgdG90YWxfdGltZTsKKwkJa3RpbWVfdCAgICAgICAgIHByZXZlbnRfc3VzcGVu ZF90aW1lOworCQlrdGltZV90ICAgICAgICAgbWF4X3RpbWU7CisJCWt0aW1lX3QgICAgICAgICBs YXN0X3RpbWU7CisJfSBzdGF0OworI2VuZGlmCiAjZW5kaWYKIH07CiAKZGlmZiAtLWdpdCBhL2tl cm5lbC9wb3dlci9LY29uZmlnIGIva2VybmVsL3Bvd2VyL0tjb25maWcKaW5kZXggZmU1YTJmMi4u NGJjYmEwNyAxMDA2NDQKLS0tIGEva2VybmVsL3Bvd2VyL0tjb25maWcKKysrIGIva2VybmVsL3Bv d2VyL0tjb25maWcKQEAgLTE0Niw2ICsxNDYsMTMgQEAgY29uZmlnIE9QUE9SVFVOSVNUSUNfU1VT UEVORAogCSAgZGV0ZXJtaW5lcyB0aGUgc2xlZXAgc3RhdGUgdGhlIHN5c3RlbSB3aWxsIGJlIHB1 dCBpbnRvIHdoZW4gdGhlcmUgYXJlCiAJICBubyBhY3RpdmUgc3VzcGVuZCBibG9ja2Vycy4KIAor Y29uZmlnIFNVU1BFTkRfQkxPQ0tFUl9TVEFUUworCWJvb2wgIlN1c3BlbmQgYmxvY2sgc3RhdHMi CisJZGVwZW5kcyBvbiBPUFBPUlRVTklTVElDX1NVU1BFTkQKKwlkZWZhdWx0IHkKKwktLS1oZWxw LS0tCisJICBSZXBvcnQgc3VzcGVuZCBibG9jayBzdGF0cyBpbiAvc3lzL2tlcm5lbC9kZWJ1Zy9z dXNwZW5kX2Jsb2NrZXJzCisKIGNvbmZpZyBVU0VSX1NVU1BFTkRfQkxPQ0tFUlMKIAlib29sICJV c2Vyc3BhY2Ugc3VzcGVuZCBibG9ja2VycyIKIAlkZXBlbmRzIG9uIE9QUE9SVFVOSVNUSUNfU1VT UEVORApkaWZmIC0tZ2l0IGEva2VybmVsL3Bvd2VyL3Bvd2VyLmggYi9rZXJuZWwvcG93ZXIvcG93 ZXIuaAppbmRleCA5YjQ2OGQ3Li43NWI4ODQ5IDEwMDY0NAotLS0gYS9rZXJuZWwvcG93ZXIvcG93 ZXIuaAorKysgYi9rZXJuZWwvcG93ZXIvcG93ZXIuaApAQCAtMjQwLDQgKzI0MCw4IEBAIHN0YXRp YyBpbmxpbmUgdm9pZCBzdXNwZW5kX3RoYXdfcHJvY2Vzc2VzKHZvaWQpCiAvKiBrZXJuZWwvcG93 ZXIvc3VzcGVuZF9ibG9jay5jICovCiBleHRlcm4gaW50IHJlcXVlc3Rfc3VzcGVuZF9zdGF0ZShz dXNwZW5kX3N0YXRlX3Qgc3RhdGUpOwogZXh0ZXJuIGJvb2wgcmVxdWVzdF9zdXNwZW5kX3ZhbGlk X3N0YXRlKHN1c3BlbmRfc3RhdGVfdCBzdGF0ZSk7Ci0KKyNpZmRlZiBDT05GSUdfU1VTUEVORF9C TE9DS0VSX1NUQVRTCit2b2lkIGFib3V0X3RvX2VudGVyX3N1c3BlbmQodm9pZCk7CisjZWxzZQor c3RhdGljIGlubGluZSB2b2lkIGFib3V0X3RvX2VudGVyX3N1c3BlbmQodm9pZCkge30KKyNlbmRp ZgpkaWZmIC0tZ2l0IGEva2VybmVsL3Bvd2VyL3N1c3BlbmQuYyBiL2tlcm5lbC9wb3dlci9zdXNw ZW5kLmMKaW5kZXggZGM0MjAwNi4uNmQzMjdlYSAxMDA2NDQKLS0tIGEva2VybmVsL3Bvd2VyL3N1 c3BlbmQuYworKysgYi9rZXJuZWwvcG93ZXIvc3VzcGVuZC5jCkBAIC0xNTksOCArMTU5LDEwIEBA IHN0YXRpYyBpbnQgc3VzcGVuZF9lbnRlcihzdXNwZW5kX3N0YXRlX3Qgc3RhdGUpCiAKIAllcnJv ciA9IHN5c2Rldl9zdXNwZW5kKFBNU0dfU1VTUEVORCk7CiAJaWYgKCFlcnJvcikgewotCQlpZiAo IXN1c3BlbmRfaXNfYmxvY2tlZCgpICYmICFzdXNwZW5kX3Rlc3QoVEVTVF9DT1JFKSkKKwkJaWYg KCFzdXNwZW5kX2lzX2Jsb2NrZWQoKSAmJiAhc3VzcGVuZF90ZXN0KFRFU1RfQ09SRSkpIHsKKwkJ CWFib3V0X3RvX2VudGVyX3N1c3BlbmQoKTsKIAkJCWVycm9yID0gc3VzcGVuZF9vcHMtPmVudGVy KHN0YXRlKTsKKwkJfQogCQlzeXNkZXZfcmVzdW1lKCk7CiAJfQogCmRpZmYgLS1naXQgYS9rZXJu ZWwvcG93ZXIvc3VzcGVuZF9ibG9ja2VyLmMgYi9rZXJuZWwvcG93ZXIvc3VzcGVuZF9ibG9ja2Vy LmMKaW5kZXggZWU0MzQ5MC4uMmQ0M2YzNyAxMDA2NDQKLS0tIGEva2VybmVsL3Bvd2VyL3N1c3Bl bmRfYmxvY2tlci5jCisrKyBiL2tlcm5lbC9wb3dlci9zdXNwZW5kX2Jsb2NrZXIuYwpAQCAtMzIs NiArMzIsNyBAQCBtb2R1bGVfcGFyYW1fbmFtZWQoZGVidWdfbWFzaywgZGVidWdfbWFzaywgaW50 LCBTX0lSVUdPIHwgU19JV1VTUiB8IFNfSVdHUlApOwogCiAjZGVmaW5lIFNCX0lOSVRJQUxJWkVE ICAgICAgICAgICAgKDFVIDw8IDgpCiAjZGVmaW5lIFNCX0FDVElWRSAgICAgICAgICAgICAgICAg KDFVIDw8IDkpCisjZGVmaW5lIFNCX1BSRVZFTlRJTkdfU1VTUEVORCAgICAgKDFVIDw8IDEwKQog CiBzdGF0aWMgREVGSU5FX1NQSU5MT0NLKGxpc3RfbG9jayk7CiBzdGF0aWMgREVGSU5FX1NQSU5M T0NLKHN0YXRlX2xvY2spOwpAQCAtNDIsNiArNDMsNyBAQCBzdHJ1Y3Qgd29ya3F1ZXVlX3N0cnVj dCAqc3VzcGVuZF93b3JrX3F1ZXVlOwogc3RydWN0IHN1c3BlbmRfYmxvY2tlciBtYWluX3N1c3Bl bmRfYmxvY2tlcjsKIHN0YXRpYyBzdXNwZW5kX3N0YXRlX3QgcmVxdWVzdGVkX3N1c3BlbmRfc3Rh dGUgPSBQTV9TVVNQRU5EX01FTTsKIHN0YXRpYyBib29sIGVuYWJsZV9zdXNwZW5kX2Jsb2NrZXJz Oworc3RhdGljIHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgdW5rbm93bl93YWtldXA7CiBzdGF0aWMg c3RydWN0IGRlbnRyeSAqc3VzcGVuZF9ibG9ja2VyX3N0YXRzX2RlbnRyeTsKIAogI2RlZmluZSBw cl9pbmZvX3RpbWUoZm10LCBhcmdzLi4uKSBcCkBAIC01Niw2ICs1OCwxNTMgQEAgc3RhdGljIHN0 cnVjdCBkZW50cnkgKnN1c3BlbmRfYmxvY2tlcl9zdGF0c19kZW50cnk7CiAJCQl0bS50bV9ob3Vy LCB0bS50bV9taW4sIHRtLnRtX3NlYywgdHMudHZfbnNlYyk7IFwKIAl9IHdoaWxlICgwKTsKIAor I2lmZGVmIENPTkZJR19TVVNQRU5EX0JMT0NLRVJfU1RBVFMKK3N0YXRpYyBzdHJ1Y3Qgc3VzcGVu ZF9ibG9ja2VyIGRlbGV0ZWRfc3VzcGVuZF9ibG9ja2VyczsKK3N0YXRpYyBrdGltZV90IGxhc3Rf c2xlZXBfdGltZV91cGRhdGU7CitzdGF0aWMgYm9vbCB3YWl0X2Zvcl93YWtldXA7CisKK3N0YXRp YyBpbnQgcHJpbnRfYmxvY2tlcl9zdGF0KHN0cnVjdCBzZXFfZmlsZSAqbSwKKwkJCSAgICAgIHN0 cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJsb2NrZXIpCit7CisJaW50IGxvY2tfY291bnQgPSBibG9j a2VyLT5zdGF0LmNvdW50OworCWt0aW1lX3QgYWN0aXZlX3RpbWUgPSBrdGltZV9zZXQoMCwgMCk7 CisJa3RpbWVfdCB0b3RhbF90aW1lID0gYmxvY2tlci0+c3RhdC50b3RhbF90aW1lOworCWt0aW1l X3QgbWF4X3RpbWUgPSBibG9ja2VyLT5zdGF0Lm1heF90aW1lOworCWt0aW1lX3QgcHJldmVudF9z dXNwZW5kX3RpbWUgPSBibG9ja2VyLT5zdGF0LnByZXZlbnRfc3VzcGVuZF90aW1lOworCWlmIChi bG9ja2VyLT5mbGFncyAmIFNCX0FDVElWRSkgeworCQlrdGltZV90IG5vdywgYWRkX3RpbWU7CisJ CW5vdyA9IGt0aW1lX2dldCgpOworCQlhZGRfdGltZSA9IGt0aW1lX3N1Yihub3csIGJsb2NrZXIt PnN0YXQubGFzdF90aW1lKTsKKwkJbG9ja19jb3VudCsrOworCQlhY3RpdmVfdGltZSA9IGFkZF90 aW1lOworCQl0b3RhbF90aW1lID0ga3RpbWVfYWRkKHRvdGFsX3RpbWUsIGFkZF90aW1lKTsKKwkJ aWYgKGJsb2NrZXItPmZsYWdzICYgU0JfUFJFVkVOVElOR19TVVNQRU5EKQorCQkJcHJldmVudF9z dXNwZW5kX3RpbWUgPSBrdGltZV9hZGQocHJldmVudF9zdXNwZW5kX3RpbWUsCisJCQkJCWt0aW1l X3N1Yihub3csIGxhc3Rfc2xlZXBfdGltZV91cGRhdGUpKTsKKwkJaWYgKGFkZF90aW1lLnR2NjQg PiBtYXhfdGltZS50djY0KQorCQkJbWF4X3RpbWUgPSBhZGRfdGltZTsKKwl9CisKKwlyZXR1cm4g c2VxX3ByaW50ZihtLCAiXCIlc1wiXHQlZFx0JWRcdCVsbGRcdCVsbGRcdCVsbGRcdCVsbGRcdCVs bGRcbiIsCisJCSAgICAgICBibG9ja2VyLT5uYW1lLCBsb2NrX2NvdW50LCBibG9ja2VyLT5zdGF0 Lndha2V1cF9jb3VudCwKKwkJICAgICAgIGt0aW1lX3RvX25zKGFjdGl2ZV90aW1lKSwga3RpbWVf dG9fbnModG90YWxfdGltZSksCisJCSAgICAgICBrdGltZV90b19ucyhwcmV2ZW50X3N1c3BlbmRf dGltZSksIGt0aW1lX3RvX25zKG1heF90aW1lKSwKKwkJICAgICAgIGt0aW1lX3RvX25zKGJsb2Nr ZXItPnN0YXQubGFzdF90aW1lKSk7Cit9CisKKworc3RhdGljIGludCBzdXNwZW5kX2Jsb2NrZXJf c3RhdHNfc2hvdyhzdHJ1Y3Qgc2VxX2ZpbGUgKm0sIHZvaWQgKnVudXNlZCkKK3sKKwl1bnNpZ25l ZCBsb25nIGlycWZsYWdzOworCXN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJsb2NrZXI7CisKKwlz ZXFfcHV0cyhtLCAibmFtZVx0Y291bnRcdHdha2VfY291bnRcdGFjdGl2ZV9zaW5jZSIKKwkJICJc dHRvdGFsX3RpbWVcdHNsZWVwX3RpbWVcdG1heF90aW1lXHRsYXN0X2NoYW5nZVxuIik7CisJc3Bp bl9sb2NrX2lycXNhdmUoJmxpc3RfbG9jaywgaXJxZmxhZ3MpOworCWxpc3RfZm9yX2VhY2hfZW50 cnkoYmxvY2tlciwgJmluYWN0aXZlX2Jsb2NrZXJzLCBsaW5rKQorCQlwcmludF9ibG9ja2VyX3N0 YXQobSwgYmxvY2tlcik7CisJbGlzdF9mb3JfZWFjaF9lbnRyeShibG9ja2VyLCAmYWN0aXZlX2Js b2NrZXJzLCBsaW5rKQorCQlwcmludF9ibG9ja2VyX3N0YXQobSwgYmxvY2tlcik7CisJc3Bpbl91 bmxvY2tfaXJxcmVzdG9yZSgmbGlzdF9sb2NrLCBpcnFmbGFncyk7CisJcmV0dXJuIDA7Cit9CisK K3N0YXRpYyB2b2lkIHN1c3BlbmRfYmxvY2tlcl9zdGF0X2luaXRfbG9ja2VkKHN0cnVjdCBzdXNw ZW5kX2Jsb2NrZXIgKmJsb2NrZXIpCit7CisJYmxvY2tlci0+c3RhdC5jb3VudCA9IDA7CisJYmxv Y2tlci0+c3RhdC53YWtldXBfY291bnQgPSAwOworCWJsb2NrZXItPnN0YXQudG90YWxfdGltZSA9 IGt0aW1lX3NldCgwLCAwKTsKKwlibG9ja2VyLT5zdGF0LnByZXZlbnRfc3VzcGVuZF90aW1lID0g a3RpbWVfc2V0KDAsIDApOworCWJsb2NrZXItPnN0YXQubWF4X3RpbWUgPSBrdGltZV9zZXQoMCwg MCk7CisJYmxvY2tlci0+c3RhdC5sYXN0X3RpbWUgPSBrdGltZV9zZXQoMCwgMCk7Cit9CisKK3N0 YXRpYyB2b2lkIHN1c3BlbmRfYmxvY2tlcl9zdGF0X2Rlc3Ryb3lfbG9ja2VkKHN0cnVjdCBzdXNw ZW5kX2Jsb2NrZXIgKmJsKQoreworCWlmICghYmwtPnN0YXQuY291bnQpCisJCXJldHVybjsKKwlk ZWxldGVkX3N1c3BlbmRfYmxvY2tlcnMuc3RhdC5jb3VudCArPSBibC0+c3RhdC5jb3VudDsKKwlk ZWxldGVkX3N1c3BlbmRfYmxvY2tlcnMuc3RhdC50b3RhbF90aW1lID0ga3RpbWVfYWRkKAorCQlk ZWxldGVkX3N1c3BlbmRfYmxvY2tlcnMuc3RhdC50b3RhbF90aW1lLCBibC0+c3RhdC50b3RhbF90 aW1lKTsKKwlkZWxldGVkX3N1c3BlbmRfYmxvY2tlcnMuc3RhdC5wcmV2ZW50X3N1c3BlbmRfdGlt ZSA9IGt0aW1lX2FkZCgKKwkJZGVsZXRlZF9zdXNwZW5kX2Jsb2NrZXJzLnN0YXQucHJldmVudF9z dXNwZW5kX3RpbWUsCisJCWJsLT5zdGF0LnByZXZlbnRfc3VzcGVuZF90aW1lKTsKKwlkZWxldGVk X3N1c3BlbmRfYmxvY2tlcnMuc3RhdC5tYXhfdGltZSA9IGt0aW1lX2FkZCgKKwkJZGVsZXRlZF9z dXNwZW5kX2Jsb2NrZXJzLnN0YXQubWF4X3RpbWUsIGJsLT5zdGF0Lm1heF90aW1lKTsKK30KKwor c3RhdGljIHZvaWQgc3VzcGVuZF91bmJsb2NrX3N0YXRfbG9ja2VkKHN0cnVjdCBzdXNwZW5kX2Js b2NrZXIgKmJsb2NrZXIpCit7CisJa3RpbWVfdCBkdXJhdGlvbjsKKwlrdGltZV90IG5vdzsKKwlp ZiAoIShibG9ja2VyLT5mbGFncyAmIFNCX0FDVElWRSkpCisJCXJldHVybjsKKwlub3cgPSBrdGlt ZV9nZXQoKTsKKwlibG9ja2VyLT5zdGF0LmNvdW50Kys7CisJZHVyYXRpb24gPSBrdGltZV9zdWIo bm93LCBibG9ja2VyLT5zdGF0Lmxhc3RfdGltZSk7CisJYmxvY2tlci0+c3RhdC50b3RhbF90aW1l ID0KKwkJa3RpbWVfYWRkKGJsb2NrZXItPnN0YXQudG90YWxfdGltZSwgZHVyYXRpb24pOworCWlm IChrdGltZV90b19ucyhkdXJhdGlvbikgPiBrdGltZV90b19ucyhibG9ja2VyLT5zdGF0Lm1heF90 aW1lKSkKKwkJYmxvY2tlci0+c3RhdC5tYXhfdGltZSA9IGR1cmF0aW9uOworCWJsb2NrZXItPnN0 YXQubGFzdF90aW1lID0ga3RpbWVfZ2V0KCk7CisJaWYgKGJsb2NrZXItPmZsYWdzICYgU0JfUFJF VkVOVElOR19TVVNQRU5EKSB7CisJCWR1cmF0aW9uID0ga3RpbWVfc3ViKG5vdywgbGFzdF9zbGVl cF90aW1lX3VwZGF0ZSk7CisJCWJsb2NrZXItPnN0YXQucHJldmVudF9zdXNwZW5kX3RpbWUgPSBr dGltZV9hZGQoCisJCQlibG9ja2VyLT5zdGF0LnByZXZlbnRfc3VzcGVuZF90aW1lLCBkdXJhdGlv bik7CisJCWJsb2NrZXItPmZsYWdzICY9IH5TQl9QUkVWRU5USU5HX1NVU1BFTkQ7CisJfQorfQor CitzdGF0aWMgdm9pZCBzdXNwZW5kX2Jsb2NrX3N0YXRfbG9ja2VkKHN0cnVjdCBzdXNwZW5kX2Js b2NrZXIgKmJsb2NrZXIpCit7CisJaWYgKHdhaXRfZm9yX3dha2V1cCkgeworCQlpZiAoZGVidWdf bWFzayAmIERFQlVHX1dBS0VVUCkKKwkJCXByX2luZm8oIndha2V1cCBzdXNwZW5kIGJsb2NrZXI6 ICVzXG4iLCBibG9ja2VyLT5uYW1lKTsKKwkJd2FpdF9mb3Jfd2FrZXVwID0gZmFsc2U7CisJCWJs b2NrZXItPnN0YXQud2FrZXVwX2NvdW50Kys7CisJfQorCWlmICghKGJsb2NrZXItPmZsYWdzICYg U0JfQUNUSVZFKSkKKwkJYmxvY2tlci0+c3RhdC5sYXN0X3RpbWUgPSBrdGltZV9nZXQoKTsKK30K Kworc3RhdGljIHZvaWQgdXBkYXRlX3NsZWVwX3dhaXRfc3RhdHNfbG9ja2VkKGJvb2wgZG9uZSkK K3sKKwlzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyICpibG9ja2VyOworCWt0aW1lX3Qgbm93LCBlbGFw c2VkLCBhZGQ7CisKKwlub3cgPSBrdGltZV9nZXQoKTsKKwllbGFwc2VkID0ga3RpbWVfc3ViKG5v dywgbGFzdF9zbGVlcF90aW1lX3VwZGF0ZSk7CisJbGlzdF9mb3JfZWFjaF9lbnRyeShibG9ja2Vy LCAmYWN0aXZlX2Jsb2NrZXJzLCBsaW5rKSB7CisJCWlmIChibG9ja2VyLT5mbGFncyAmIFNCX1BS RVZFTlRJTkdfU1VTUEVORCkgeworCQkJYWRkID0gZWxhcHNlZDsKKwkJCWJsb2NrZXItPnN0YXQu cHJldmVudF9zdXNwZW5kX3RpbWUgPSBrdGltZV9hZGQoCisJCQkJYmxvY2tlci0+c3RhdC5wcmV2 ZW50X3N1c3BlbmRfdGltZSwgYWRkKTsKKwkJfQorCQlpZiAoZG9uZSkKKwkJCWJsb2NrZXItPmZs YWdzICY9IH5TQl9QUkVWRU5USU5HX1NVU1BFTkQ7CisJCWVsc2UKKwkJCWJsb2NrZXItPmZsYWdz IHw9IFNCX1BSRVZFTlRJTkdfU1VTUEVORDsKKwl9CisJbGFzdF9zbGVlcF90aW1lX3VwZGF0ZSA9 IG5vdzsKK30KKwordm9pZCBhYm91dF90b19lbnRlcl9zdXNwZW5kKHZvaWQpCit7CisJd2FpdF9m b3Jfd2FrZXVwID0gdHJ1ZTsKK30KKworI2Vsc2UKKworc3RhdGljIGlubGluZSB2b2lkIHN1c3Bl bmRfYmxvY2tlcl9zdGF0X2luaXRfbG9ja2VkKAorCQkJCQlzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2Vy ICpibG9ja2VyKSB7fQorc3RhdGljIGlubGluZSB2b2lkIHN1c3BlbmRfYmxvY2tlcl9zdGF0X2Rl c3Ryb3lfbG9ja2VkKAorCQkJCQlzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyICpibG9ja2VyKSB7fQor c3RhdGljIGlubGluZSB2b2lkIHN1c3BlbmRfYmxvY2tfc3RhdF9sb2NrZWQoCisJCQkJCXN0cnVj dCBzdXNwZW5kX2Jsb2NrZXIgKmJsb2NrZXIpIHt9CitzdGF0aWMgaW5saW5lIHZvaWQgc3VzcGVu ZF91bmJsb2NrX3N0YXRfbG9ja2VkKAorCQkJCQlzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyICpibG9j a2VyKSB7fQorc3RhdGljIGlubGluZSB2b2lkIHVwZGF0ZV9zbGVlcF93YWl0X3N0YXRzX2xvY2tl ZChib29sIGRvbmUpIHt9CisKIHN0YXRpYyBpbnQgc3VzcGVuZF9ibG9ja2VyX3N0YXRzX3Nob3co c3RydWN0IHNlcV9maWxlICptLCB2b2lkICp1bnVzZWQpCiB7CiAJdW5zaWduZWQgbG9uZyBpcnFm bGFnczsKQEAgLTcxLDYgKzIyMCw4IEBAIHN0YXRpYyBpbnQgc3VzcGVuZF9ibG9ja2VyX3N0YXRz X3Nob3coc3RydWN0IHNlcV9maWxlICptLCB2b2lkICp1bnVzZWQpCiAJcmV0dXJuIDA7CiB9CiAK KyNlbmRpZgorCiBzdGF0aWMgdm9pZCBwcmludF9hY3RpdmVfYmxvY2tlcnNfbG9ja2VkKHZvaWQp CiB7CiAJc3RydWN0IHN1c3BlbmRfYmxvY2tlciAqYmxvY2tlcjsKQEAgLTEwMSwyMCArMjUyLDMx IEBAIHN0YXRpYyB2b2lkIHN1c3BlbmRfd29ya2VyKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykK IAlpbnQgZW50cnlfZXZlbnRfbnVtOwogCiAJZW5hYmxlX3N1c3BlbmRfYmxvY2tlcnMgPSB0cnVl OwotCXdoaWxlICghc3VzcGVuZF9pc19ibG9ja2VkKCkpIHsKLQkJZW50cnlfZXZlbnRfbnVtID0g Y3VycmVudF9ldmVudF9udW07CiAKKwlpZiAoc3VzcGVuZF9pc19ibG9ja2VkKCkpIHsKIAkJaWYg KGRlYnVnX21hc2sgJiBERUJVR19TVVNQRU5EKQotCQkJcHJfaW5mbygic3VzcGVuZDogZW50ZXIg c3VzcGVuZFxuIik7CisJCQlwcl9pbmZvKCJzdXNwZW5kOiBhYm9ydCBzdXNwZW5kXG4iKTsKKwkJ Z290byBhYm9ydDsKKwl9CisKKwllbnRyeV9ldmVudF9udW0gPSBjdXJyZW50X2V2ZW50X251bTsK KworCWlmIChkZWJ1Z19tYXNrICYgREVCVUdfU1VTUEVORCkKKwkJcHJfaW5mbygic3VzcGVuZDog ZW50ZXIgc3VzcGVuZFxuIik7CiAKLQkJcmV0ID0gcG1fc3VzcGVuZChyZXF1ZXN0ZWRfc3VzcGVu ZF9zdGF0ZSk7CisJcmV0ID0gcG1fc3VzcGVuZChyZXF1ZXN0ZWRfc3VzcGVuZF9zdGF0ZSk7CiAK LQkJaWYgKGRlYnVnX21hc2sgJiBERUJVR19FWElUX1NVU1BFTkQpCi0JCQlwcl9pbmZvX3RpbWUo InN1c3BlbmQ6IGV4aXQgc3VzcGVuZCwgcmV0ID0gJWQgIiwgcmV0KTsKKwlpZiAoZGVidWdfbWFz ayAmIERFQlVHX0VYSVRfU1VTUEVORCkKKwkJcHJfaW5mb190aW1lKCJzdXNwZW5kOiBleGl0IHN1 c3BlbmQsIHJldCA9ICVkICIsIHJldCk7CiAKLQkJaWYgKGN1cnJlbnRfZXZlbnRfbnVtID09IGVu dHJ5X2V2ZW50X251bSkKKwlpZiAoY3VycmVudF9ldmVudF9udW0gPT0gZW50cnlfZXZlbnRfbnVt KSB7CisJCWlmIChkZWJ1Z19tYXNrICYgREVCVUdfU1VTUEVORCkKIAkJCXByX2luZm8oInN1c3Bl bmQ6IHBtX3N1c3BlbmQgcmV0dXJuZWQgd2l0aCBubyBldmVudFxuIik7CisKKwkJc3VzcGVuZF9i bG9jaygmdW5rbm93bl93YWtldXApOworCQlzdXNwZW5kX3VuYmxvY2soJnVua25vd25fd2FrZXVw KTsKIAl9CithYm9ydDoKIAllbmFibGVfc3VzcGVuZF9ibG9ja2VycyA9IGZhbHNlOwogfQogc3Rh dGljIERFQ0xBUkVfV09SSyhzdXNwZW5kX3dvcmssIHN1c3BlbmRfd29ya2VyKTsKQEAgLTE0MSw2 ICszMDMsNyBAQCB2b2lkIHN1c3BlbmRfYmxvY2tlcl9pbml0KHN0cnVjdCBzdXNwZW5kX2Jsb2Nr ZXIgKmJsb2NrZXIsIGNvbnN0IGNoYXIgKm5hbWUpCiAJSU5JVF9MSVNUX0hFQUQoJmJsb2NrZXIt PmxpbmspOwogCiAJc3Bpbl9sb2NrX2lycXNhdmUoJmxpc3RfbG9jaywgaXJxZmxhZ3MpOworCXN1 c3BlbmRfYmxvY2tlcl9zdGF0X2luaXRfbG9ja2VkKGJsb2NrZXIpOwogCWxpc3RfYWRkKCZibG9j a2VyLT5saW5rLCAmaW5hY3RpdmVfYmxvY2tlcnMpOwogCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUo Jmxpc3RfbG9jaywgaXJxZmxhZ3MpOwogfQpAQCAtMTYwLDYgKzMyMyw3IEBAIHZvaWQgc3VzcGVu ZF9ibG9ja2VyX2Rlc3Ryb3koc3RydWN0IHN1c3BlbmRfYmxvY2tlciAqYmxvY2tlcikKIAkJcHJf aW5mbygic3VzcGVuZF9ibG9ja2VyX2Rlc3Ryb3kgbmFtZT0lc1xuIiwgYmxvY2tlci0+bmFtZSk7 CiAKIAlzcGluX2xvY2tfaXJxc2F2ZSgmbGlzdF9sb2NrLCBpcnFmbGFncyk7CisJc3VzcGVuZF9i bG9ja2VyX3N0YXRfZGVzdHJveV9sb2NrZWQoYmxvY2tlcik7CiAJYmxvY2tlci0+ZmxhZ3MgJj0g flNCX0lOSVRJQUxJWkVEOwogCWxpc3RfZGVsKCZibG9ja2VyLT5saW5rKTsKIAlpZiAoKGJsb2Nr ZXItPmZsYWdzICYgU0JfQUNUSVZFKSAmJiBsaXN0X2VtcHR5KCZhY3RpdmVfYmxvY2tlcnMpKQpA QCAtMTgyLDYgKzM0Niw3IEBAIHZvaWQgc3VzcGVuZF9ibG9jayhzdHJ1Y3Qgc3VzcGVuZF9ibG9j a2VyICpibG9ja2VyKQogCQlyZXR1cm47CiAKIAlzcGluX2xvY2tfaXJxc2F2ZSgmbGlzdF9sb2Nr LCBpcnFmbGFncyk7CisJc3VzcGVuZF9ibG9ja19zdGF0X2xvY2tlZChibG9ja2VyKTsKIAlibG9j a2VyLT5mbGFncyB8PSBTQl9BQ1RJVkU7CiAJbGlzdF9kZWwoJmJsb2NrZXItPmxpbmspOwogCkBA IC0xOTEsNiArMzU2LDEwIEBAIHZvaWQgc3VzcGVuZF9ibG9jayhzdHJ1Y3Qgc3VzcGVuZF9ibG9j a2VyICpibG9ja2VyKQogCWxpc3RfYWRkKCZibG9ja2VyLT5saW5rLCAmYWN0aXZlX2Jsb2NrZXJz KTsKIAogCWN1cnJlbnRfZXZlbnRfbnVtKys7CisJaWYgKGJsb2NrZXIgPT0gJm1haW5fc3VzcGVu ZF9ibG9ja2VyKQorCQl1cGRhdGVfc2xlZXBfd2FpdF9zdGF0c19sb2NrZWQodHJ1ZSk7CisJZWxz ZSBpZiAoIXN1c3BlbmRfYmxvY2tlcl9pc19hY3RpdmUoJm1haW5fc3VzcGVuZF9ibG9ja2VyKSkK KwkJdXBkYXRlX3NsZWVwX3dhaXRfc3RhdHNfbG9ja2VkKGZhbHNlKTsKIAlzcGluX3VubG9ja19p cnFyZXN0b3JlKCZsaXN0X2xvY2ssIGlycWZsYWdzKTsKIH0KIEVYUE9SVF9TWU1CT0woc3VzcGVu ZF9ibG9jayk7CkBAIC0yMTIsNiArMzgxLDggQEAgdm9pZCBzdXNwZW5kX3VuYmxvY2soc3RydWN0 IHN1c3BlbmRfYmxvY2tlciAqYmxvY2tlcikKIAogCXNwaW5fbG9ja19pcnFzYXZlKCZsaXN0X2xv Y2ssIGlycWZsYWdzKTsKIAorCXN1c3BlbmRfdW5ibG9ja19zdGF0X2xvY2tlZChibG9ja2VyKTsK KwogCWlmIChkZWJ1Z19tYXNrICYgREVCVUdfU1VTUEVORF9CTE9DS0VSKQogCQlwcl9pbmZvKCJz dXNwZW5kX3VuYmxvY2s6ICVzXG4iLCBibG9ja2VyLT5uYW1lKTsKIApAQCAtMjI0LDYgKzM5NSw3 IEBAIHZvaWQgc3VzcGVuZF91bmJsb2NrKHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJsb2NrZXIp CiAJaWYgKGJsb2NrZXIgPT0gJm1haW5fc3VzcGVuZF9ibG9ja2VyKSB7CiAJCWlmIChkZWJ1Z19t YXNrICYgREVCVUdfU1VTUEVORCkKIAkJCXByaW50X2FjdGl2ZV9ibG9ja2Vyc19sb2NrZWQoKTsK KwkJdXBkYXRlX3NsZWVwX3dhaXRfc3RhdHNfbG9ja2VkKGZhbHNlKTsKIAl9CiAJc3Bpbl91bmxv Y2tfaXJxcmVzdG9yZSgmbGlzdF9sb2NrLCBpcnFmbGFncyk7CiB9CkBAIC0yOTMsNiArNDY1LDEx IEBAIHN0YXRpYyBpbnQgX19pbml0IHN1c3BlbmRfYmxvY2tfaW5pdCh2b2lkKQogCiAJc3VzcGVu ZF9ibG9ja2VyX2luaXQoJm1haW5fc3VzcGVuZF9ibG9ja2VyLCAibWFpbiIpOwogCXN1c3BlbmRf YmxvY2soJm1haW5fc3VzcGVuZF9ibG9ja2VyKTsKKwlzdXNwZW5kX2Jsb2NrZXJfaW5pdCgmdW5r bm93bl93YWtldXAsICJ1bmtub3duX3dha2V1cHMiKTsKKyNpZmRlZiBDT05GSUdfU1VTUEVORF9C TE9DS0VSX1NUQVRTCisJc3VzcGVuZF9ibG9ja2VyX2luaXQoJmRlbGV0ZWRfc3VzcGVuZF9ibG9j a2VycywKKwkJCQkiZGVsZXRlZF9zdXNwZW5kX2Jsb2NrZXJzIik7CisjZW5kaWYKIAlyZXR1cm4g MDsKIH0KIAotLSAKMS42LjUuMQoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX18KbGludXgtcG0gbWFpbGluZyBsaXN0CmxpbnV4LXBtQGxpc3RzLmxpbnV4LWZv dW5kYXRpb24ub3JnCmh0dHBzOi8vbGlzdHMubGludXgtZm91bmRhdGlvbi5vcmcvbWFpbG1hbi9s aXN0aW5mby9saW51eC1wbQ== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751696Ab0D1Ect (ORCPT ); Wed, 28 Apr 2010 00:32:49 -0400 Received: from mail-pz0-f204.google.com ([209.85.222.204]:57985 "EHLO mail-pz0-f204.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751137Ab0D1Eca (ORCPT ); Wed, 28 Apr 2010 00:32:30 -0400 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= To: linux-pm@lists.linux-foundation.org, linux-kernel@vger.kernel.org Cc: "Rafael J. Wysocki" , Alan Stern , Tejun Heo , Oleg Nesterov , =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= , Pavel Machek , Len Brown , Jesse Barnes , Magnus Damm , Wu Fengguang , Andrew Morton , Maxim Levitsky Subject: [PATCH 5/8] PM: suspend_block: Add suspend_blocker stats Date: Tue, 27 Apr 2010 21:31:56 -0700 Message-Id: <1272429119-12103-6-git-send-email-arve@android.com> X-Mailer: git-send-email 1.6.5.1 In-Reply-To: <1272429119-12103-5-git-send-email-arve@android.com> References: <1272429119-12103-1-git-send-email-arve@android.com> <1272429119-12103-2-git-send-email-arve@android.com> <1272429119-12103-3-git-send-email-arve@android.com> <1272429119-12103-4-git-send-email-arve@android.com> <1272429119-12103-5-git-send-email-arve@android.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 Report suspend block stats in /sys/kernel/debug/suspend_blockers. Signed-off-by: Arve Hjønnevåg --- include/linux/suspend_blocker.h | 21 ++++- kernel/power/Kconfig | 7 ++ kernel/power/power.h | 6 +- kernel/power/suspend.c | 4 +- kernel/power/suspend_blocker.c | 191 +++++++++++++++++++++++++++++++++++++-- 5 files changed, 219 insertions(+), 10 deletions(-) diff --git a/include/linux/suspend_blocker.h b/include/linux/suspend_blocker.h index f9928cc..c80764c 100755 --- a/include/linux/suspend_blocker.h +++ b/include/linux/suspend_blocker.h @@ -17,12 +17,21 @@ #define _LINUX_SUSPEND_BLOCKER_H #include +#include /** * struct suspend_blocker - the basic suspend_blocker structure * @link: List entry for active or inactive list. - * @flags: Tracks initialized and active state. + * @flags: Tracks initialized, active and stats state. * @name: Name used for debugging. + * @count: Number of times this blocker has been deacivated + * @wakeup_count: Number of times this blocker was the first to block suspend + * after resume. + * @total_time: Total time this suspend blocker has prevented suspend. + * @prevent_suspend_time: Time this suspend blocker has prevented suspend while + * user-space requested suspend. + * @max_time: Max time this suspend blocker has been continuously active + * @last_time: Monotonic clock when the active state last changed. * * When a suspend_blocker is active it prevents the system from entering * opportunistic suspend. @@ -35,6 +44,16 @@ struct suspend_blocker { struct list_head link; int flags; const char *name; +#ifdef CONFIG_SUSPEND_BLOCKER_STATS + struct { + int count; + int wakeup_count; + ktime_t total_time; + ktime_t prevent_suspend_time; + ktime_t max_time; + ktime_t last_time; + } stat; +#endif #endif }; diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index fe5a2f2..4bcba07 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -146,6 +146,13 @@ config OPPORTUNISTIC_SUSPEND determines the sleep state the system will be put into when there are no active suspend blockers. +config SUSPEND_BLOCKER_STATS + bool "Suspend block stats" + depends on OPPORTUNISTIC_SUSPEND + default y + ---help--- + Report suspend block stats in /sys/kernel/debug/suspend_blockers + config USER_SUSPEND_BLOCKERS bool "Userspace suspend blockers" depends on OPPORTUNISTIC_SUSPEND diff --git a/kernel/power/power.h b/kernel/power/power.h index 9b468d7..75b8849 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -240,4 +240,8 @@ static inline void suspend_thaw_processes(void) /* kernel/power/suspend_block.c */ extern int request_suspend_state(suspend_state_t state); extern bool request_suspend_valid_state(suspend_state_t state); - +#ifdef CONFIG_SUSPEND_BLOCKER_STATS +void about_to_enter_suspend(void); +#else +static inline void about_to_enter_suspend(void) {} +#endif diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index dc42006..6d327ea 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -159,8 +159,10 @@ static int suspend_enter(suspend_state_t state) error = sysdev_suspend(PMSG_SUSPEND); if (!error) { - if (!suspend_is_blocked() && !suspend_test(TEST_CORE)) + if (!suspend_is_blocked() && !suspend_test(TEST_CORE)) { + about_to_enter_suspend(); error = suspend_ops->enter(state); + } sysdev_resume(); } diff --git a/kernel/power/suspend_blocker.c b/kernel/power/suspend_blocker.c index ee43490..2d43f37 100644 --- a/kernel/power/suspend_blocker.c +++ b/kernel/power/suspend_blocker.c @@ -32,6 +32,7 @@ module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); #define SB_INITIALIZED (1U << 8) #define SB_ACTIVE (1U << 9) +#define SB_PREVENTING_SUSPEND (1U << 10) static DEFINE_SPINLOCK(list_lock); static DEFINE_SPINLOCK(state_lock); @@ -42,6 +43,7 @@ struct workqueue_struct *suspend_work_queue; struct suspend_blocker main_suspend_blocker; static suspend_state_t requested_suspend_state = PM_SUSPEND_MEM; static bool enable_suspend_blockers; +static struct suspend_blocker unknown_wakeup; static struct dentry *suspend_blocker_stats_dentry; #define pr_info_time(fmt, args...) \ @@ -56,6 +58,153 @@ static struct dentry *suspend_blocker_stats_dentry; tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec); \ } while (0); +#ifdef CONFIG_SUSPEND_BLOCKER_STATS +static struct suspend_blocker deleted_suspend_blockers; +static ktime_t last_sleep_time_update; +static bool wait_for_wakeup; + +static int print_blocker_stat(struct seq_file *m, + struct suspend_blocker *blocker) +{ + int lock_count = blocker->stat.count; + ktime_t active_time = ktime_set(0, 0); + ktime_t total_time = blocker->stat.total_time; + ktime_t max_time = blocker->stat.max_time; + ktime_t prevent_suspend_time = blocker->stat.prevent_suspend_time; + if (blocker->flags & SB_ACTIVE) { + ktime_t now, add_time; + now = ktime_get(); + add_time = ktime_sub(now, blocker->stat.last_time); + lock_count++; + active_time = add_time; + total_time = ktime_add(total_time, add_time); + if (blocker->flags & SB_PREVENTING_SUSPEND) + prevent_suspend_time = ktime_add(prevent_suspend_time, + ktime_sub(now, last_sleep_time_update)); + if (add_time.tv64 > max_time.tv64) + max_time = add_time; + } + + return seq_printf(m, "\"%s\"\t%d\t%d\t%lld\t%lld\t%lld\t%lld\t%lld\n", + blocker->name, lock_count, blocker->stat.wakeup_count, + ktime_to_ns(active_time), ktime_to_ns(total_time), + ktime_to_ns(prevent_suspend_time), ktime_to_ns(max_time), + ktime_to_ns(blocker->stat.last_time)); +} + + +static int suspend_blocker_stats_show(struct seq_file *m, void *unused) +{ + unsigned long irqflags; + struct suspend_blocker *blocker; + + seq_puts(m, "name\tcount\twake_count\tactive_since" + "\ttotal_time\tsleep_time\tmax_time\tlast_change\n"); + spin_lock_irqsave(&list_lock, irqflags); + list_for_each_entry(blocker, &inactive_blockers, link) + print_blocker_stat(m, blocker); + list_for_each_entry(blocker, &active_blockers, link) + print_blocker_stat(m, blocker); + spin_unlock_irqrestore(&list_lock, irqflags); + return 0; +} + +static void suspend_blocker_stat_init_locked(struct suspend_blocker *blocker) +{ + blocker->stat.count = 0; + blocker->stat.wakeup_count = 0; + blocker->stat.total_time = ktime_set(0, 0); + blocker->stat.prevent_suspend_time = ktime_set(0, 0); + blocker->stat.max_time = ktime_set(0, 0); + blocker->stat.last_time = ktime_set(0, 0); +} + +static void suspend_blocker_stat_destroy_locked(struct suspend_blocker *bl) +{ + if (!bl->stat.count) + return; + deleted_suspend_blockers.stat.count += bl->stat.count; + deleted_suspend_blockers.stat.total_time = ktime_add( + deleted_suspend_blockers.stat.total_time, bl->stat.total_time); + deleted_suspend_blockers.stat.prevent_suspend_time = ktime_add( + deleted_suspend_blockers.stat.prevent_suspend_time, + bl->stat.prevent_suspend_time); + deleted_suspend_blockers.stat.max_time = ktime_add( + deleted_suspend_blockers.stat.max_time, bl->stat.max_time); +} + +static void suspend_unblock_stat_locked(struct suspend_blocker *blocker) +{ + ktime_t duration; + ktime_t now; + if (!(blocker->flags & SB_ACTIVE)) + return; + now = ktime_get(); + blocker->stat.count++; + duration = ktime_sub(now, blocker->stat.last_time); + blocker->stat.total_time = + ktime_add(blocker->stat.total_time, duration); + if (ktime_to_ns(duration) > ktime_to_ns(blocker->stat.max_time)) + blocker->stat.max_time = duration; + blocker->stat.last_time = ktime_get(); + if (blocker->flags & SB_PREVENTING_SUSPEND) { + duration = ktime_sub(now, last_sleep_time_update); + blocker->stat.prevent_suspend_time = ktime_add( + blocker->stat.prevent_suspend_time, duration); + blocker->flags &= ~SB_PREVENTING_SUSPEND; + } +} + +static void suspend_block_stat_locked(struct suspend_blocker *blocker) +{ + if (wait_for_wakeup) { + if (debug_mask & DEBUG_WAKEUP) + pr_info("wakeup suspend blocker: %s\n", blocker->name); + wait_for_wakeup = false; + blocker->stat.wakeup_count++; + } + if (!(blocker->flags & SB_ACTIVE)) + blocker->stat.last_time = ktime_get(); +} + +static void update_sleep_wait_stats_locked(bool done) +{ + struct suspend_blocker *blocker; + ktime_t now, elapsed, add; + + now = ktime_get(); + elapsed = ktime_sub(now, last_sleep_time_update); + list_for_each_entry(blocker, &active_blockers, link) { + if (blocker->flags & SB_PREVENTING_SUSPEND) { + add = elapsed; + blocker->stat.prevent_suspend_time = ktime_add( + blocker->stat.prevent_suspend_time, add); + } + if (done) + blocker->flags &= ~SB_PREVENTING_SUSPEND; + else + blocker->flags |= SB_PREVENTING_SUSPEND; + } + last_sleep_time_update = now; +} + +void about_to_enter_suspend(void) +{ + wait_for_wakeup = true; +} + +#else + +static inline void suspend_blocker_stat_init_locked( + struct suspend_blocker *blocker) {} +static inline void suspend_blocker_stat_destroy_locked( + struct suspend_blocker *blocker) {} +static inline void suspend_block_stat_locked( + struct suspend_blocker *blocker) {} +static inline void suspend_unblock_stat_locked( + struct suspend_blocker *blocker) {} +static inline void update_sleep_wait_stats_locked(bool done) {} + static int suspend_blocker_stats_show(struct seq_file *m, void *unused) { unsigned long irqflags; @@ -71,6 +220,8 @@ static int suspend_blocker_stats_show(struct seq_file *m, void *unused) return 0; } +#endif + static void print_active_blockers_locked(void) { struct suspend_blocker *blocker; @@ -101,20 +252,31 @@ static void suspend_worker(struct work_struct *work) int entry_event_num; enable_suspend_blockers = true; - while (!suspend_is_blocked()) { - entry_event_num = current_event_num; + if (suspend_is_blocked()) { if (debug_mask & DEBUG_SUSPEND) - pr_info("suspend: enter suspend\n"); + pr_info("suspend: abort suspend\n"); + goto abort; + } + + entry_event_num = current_event_num; + + if (debug_mask & DEBUG_SUSPEND) + pr_info("suspend: enter suspend\n"); - ret = pm_suspend(requested_suspend_state); + ret = pm_suspend(requested_suspend_state); - if (debug_mask & DEBUG_EXIT_SUSPEND) - pr_info_time("suspend: exit suspend, ret = %d ", ret); + if (debug_mask & DEBUG_EXIT_SUSPEND) + pr_info_time("suspend: exit suspend, ret = %d ", ret); - if (current_event_num == entry_event_num) + if (current_event_num == entry_event_num) { + if (debug_mask & DEBUG_SUSPEND) pr_info("suspend: pm_suspend returned with no event\n"); + + suspend_block(&unknown_wakeup); + suspend_unblock(&unknown_wakeup); } +abort: enable_suspend_blockers = false; } static DECLARE_WORK(suspend_work, suspend_worker); @@ -141,6 +303,7 @@ void suspend_blocker_init(struct suspend_blocker *blocker, const char *name) INIT_LIST_HEAD(&blocker->link); spin_lock_irqsave(&list_lock, irqflags); + suspend_blocker_stat_init_locked(blocker); list_add(&blocker->link, &inactive_blockers); spin_unlock_irqrestore(&list_lock, irqflags); } @@ -160,6 +323,7 @@ void suspend_blocker_destroy(struct suspend_blocker *blocker) pr_info("suspend_blocker_destroy name=%s\n", blocker->name); spin_lock_irqsave(&list_lock, irqflags); + suspend_blocker_stat_destroy_locked(blocker); blocker->flags &= ~SB_INITIALIZED; list_del(&blocker->link); if ((blocker->flags & SB_ACTIVE) && list_empty(&active_blockers)) @@ -182,6 +346,7 @@ void suspend_block(struct suspend_blocker *blocker) return; spin_lock_irqsave(&list_lock, irqflags); + suspend_block_stat_locked(blocker); blocker->flags |= SB_ACTIVE; list_del(&blocker->link); @@ -191,6 +356,10 @@ void suspend_block(struct suspend_blocker *blocker) list_add(&blocker->link, &active_blockers); current_event_num++; + if (blocker == &main_suspend_blocker) + update_sleep_wait_stats_locked(true); + else if (!suspend_blocker_is_active(&main_suspend_blocker)) + update_sleep_wait_stats_locked(false); spin_unlock_irqrestore(&list_lock, irqflags); } EXPORT_SYMBOL(suspend_block); @@ -212,6 +381,8 @@ void suspend_unblock(struct suspend_blocker *blocker) spin_lock_irqsave(&list_lock, irqflags); + suspend_unblock_stat_locked(blocker); + if (debug_mask & DEBUG_SUSPEND_BLOCKER) pr_info("suspend_unblock: %s\n", blocker->name); @@ -224,6 +395,7 @@ void suspend_unblock(struct suspend_blocker *blocker) if (blocker == &main_suspend_blocker) { if (debug_mask & DEBUG_SUSPEND) print_active_blockers_locked(); + update_sleep_wait_stats_locked(false); } spin_unlock_irqrestore(&list_lock, irqflags); } @@ -293,6 +465,11 @@ static int __init suspend_block_init(void) suspend_blocker_init(&main_suspend_blocker, "main"); suspend_block(&main_suspend_blocker); + suspend_blocker_init(&unknown_wakeup, "unknown_wakeups"); +#ifdef CONFIG_SUSPEND_BLOCKER_STATS + suspend_blocker_init(&deleted_suspend_blockers, + "deleted_suspend_blockers"); +#endif return 0; } -- 1.6.5.1