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: Thu, 13 May 2010 21:11:10 -0700 Message-ID: <1273810273-3039-6-git-send-email-arve@android.com> References: <1273810273-3039-1-git-send-email-arve@android.com> <1273810273-3039-2-git-send-email-arve@android.com> <1273810273-3039-3-git-send-email-arve@android.com> <1273810273-3039-4-git-send-email-arve@android.com> <1273810273-3039-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: <1273810273-3039-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 , Jesse Barnes , Tejun Heo , Magnus Damm , Andrew Morton , Wu Fengguang List-Id: linux-pm@vger.kernel.org UmVwb3J0IHN1c3BlbmQgYmxvY2sgc3RhdHMgaW4gL3N5cy9rZXJuZWwvZGVidWcvc3VzcGVuZF9i bG9ja2Vycy4KClNpZ25lZC1vZmYtYnk6IEFydmUgSGrDuG5uZXbDpWcgPGFydmVAYW5kcm9pZC5j b20+Ci0tLQogaW5jbHVkZS9saW51eC9zdXNwZW5kX2Jsb2NrZXIuaCAgICAgIHwgICAyNyArKysr Ky0KIGtlcm5lbC9wb3dlci9LY29uZmlnICAgICAgICAgICAgICAgICB8ICAgIDggKysKIGtlcm5l bC9wb3dlci9vcHBvcnR1bmlzdGljX3N1c3BlbmQuYyB8ICAyMDAgKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrLQoga2VybmVsL3Bvd2VyL3Bvd2VyLmggICAgICAgICAgICAgICAgIHwg ICAgNSArCiBrZXJuZWwvcG93ZXIvc3VzcGVuZC5jICAgICAgICAgICAgICAgfCAgICA0ICstCiA1 IGZpbGVzIGNoYW5nZWQsIDIzOSBpbnNlcnRpb25zKCspLCA1IGRlbGV0aW9ucygtKQoKZGlmZiAt LWdpdCBhL2luY2x1ZGUvbGludXgvc3VzcGVuZF9ibG9ja2VyLmggYi9pbmNsdWRlL2xpbnV4L3N1 c3BlbmRfYmxvY2tlci5oCmluZGV4IDg3ODgzMDIuLjI1NmFmMTUgMTAwNzU1Ci0tLSBhL2luY2x1 ZGUvbGludXgvc3VzcGVuZF9ibG9ja2VyLmgKKysrIGIvaW5jbHVkZS9saW51eC9zdXNwZW5kX2Js b2NrZXIuaApAQCAtMTcsMTEgKzE3LDM1IEBACiAjZGVmaW5lIF9MSU5VWF9TVVNQRU5EX0JMT0NL RVJfSAogCiAjaW5jbHVkZSA8bGludXgvbGlzdC5oPgorI2luY2x1ZGUgPGxpbnV4L2t0aW1lLmg+ CisKKy8qKgorICogc3RydWN0IHN1c3BlbmRfYmxvY2tlcl9zdGF0cyAtIHN0YXRpc3RpY3MgZm9y IGEgc3VzcGVuZCBibG9ja2VyCisgKgorICogQGNvdW50OiBOdW1iZXIgb2YgdGltZXMgdGhpcyBi bG9ja2VyIGhhcyBiZWVuIGRlYWNpdmF0ZWQuCisgKiBAd2FrZXVwX2NvdW50OiBOdW1iZXIgb2Yg dGltZXMgdGhpcyBibG9ja2VyIHdhcyB0aGUgZmlyc3QgdG8gYmxvY2sgc3VzcGVuZAorICoJYWZ0 ZXIgcmVzdW1lLgorICogQHRvdGFsX3RpbWU6IFRvdGFsIHRpbWUgdGhpcyBzdXNwZW5kIGJsb2Nr ZXIgaGFzIHByZXZlbnRlZCBzdXNwZW5kLgorICogQHByZXZlbnRfc3VzcGVuZF90aW1lOiBUaW1l IHRoaXMgc3VzcGVuZCBibG9ja2VyIGhhcyBwcmV2ZW50ZWQgc3VzcGVuZCB3aGlsZQorICoJdXNl ci1zcGFjZSByZXF1ZXN0ZWQgc3VzcGVuZC4KKyAqIEBtYXhfdGltZTogTWF4IHRpbWUgdGhpcyBz dXNwZW5kIGJsb2NrZXIgaGFzIGJlZW4gY29udGludW91c2x5IGFjdGl2ZS4KKyAqIEBsYXN0X3Rp bWU6IE1vbm90b25pYyBjbG9jayB3aGVuIHRoZSBhY3RpdmUgc3RhdGUgbGFzdCBjaGFuZ2VkLgor ICovCitzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyX3N0YXRzIHsKKyNpZmRlZiBDT05GSUdfU1VTUEVO RF9CTE9DS0VSX1NUQVRTCisJdW5zaWduZWQgaW50IGNvdW50OworCXVuc2lnbmVkIGludCB3YWtl dXBfY291bnQ7CisJa3RpbWVfdCB0b3RhbF90aW1lOworCWt0aW1lX3QgcHJldmVudF9zdXNwZW5k X3RpbWU7CisJa3RpbWVfdCBtYXhfdGltZTsKKwlrdGltZV90IGxhc3RfdGltZTsKKyNlbmRpZgor fTsKIAogLyoqCiAgKiBzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyIC0gdGhlIGJhc2ljIHN1c3BlbmRf YmxvY2tlciBzdHJ1Y3R1cmUKICAqIEBsaW5rOiBMaXN0IGVudHJ5IGZvciBhY3RpdmUgb3IgaW5h Y3RpdmUgbGlzdC4KLSAqIEBmbGFnczogVHJhY2tzIGluaXRpYWxpemVkIGFuZCBhY3RpdmUgc3Rh dGUuCisgKiBAZmxhZ3M6IFRyYWNrcyBpbml0aWFsaXplZCBhbmQgYWN0aXZlIHN0YXRlIGFuZCBz dGF0aXN0aWNzLgogICogQG5hbWU6IFN1c3BlbmQgYmxvY2tlciBuYW1lIHVzZWQgZm9yIGRlYnVn Z2luZy4KICAqCiAgKiBXaGVuIGEgc3VzcGVuZF9ibG9ja2VyIGlzIGFjdGl2ZSBpdCBwcmV2ZW50 cyB0aGUgc3lzdGVtIGZyb20gZW50ZXJpbmcKQEAgLTM0LDYgKzU4LDcgQEAgc3RydWN0IHN1c3Bl bmRfYmxvY2tlciB7CiAJc3RydWN0IGxpc3RfaGVhZCBsaW5rOwogCWludCBmbGFnczsKIAljb25z dCBjaGFyICpuYW1lOworCXN0cnVjdCBzdXNwZW5kX2Jsb2NrZXJfc3RhdHMgc3RhdDsKICNlbmRp ZgogfTsKIApkaWZmIC0tZ2l0IGEva2VybmVsL3Bvd2VyL0tjb25maWcgYi9rZXJuZWwvcG93ZXIv S2NvbmZpZwppbmRleCAyZTY2NWNkLi4xNmEyNTcwIDEwMDY0NAotLS0gYS9rZXJuZWwvcG93ZXIv S2NvbmZpZworKysgYi9rZXJuZWwvcG93ZXIvS2NvbmZpZwpAQCAtMTQ2LDYgKzE0NiwxNCBAQCBj b25maWcgT1BQT1JUVU5JU1RJQ19TVVNQRU5ECiAJICBkZXRlcm1pbmVzIHRoZSBzbGVlcCBzdGF0 ZSB0aGUgc3lzdGVtIHdpbGwgYmUgcHV0IGludG8gd2hlbiB0aGVyZSBhcmUKIAkgIG5vIGFjdGl2 ZSBzdXNwZW5kIGJsb2NrZXJzLgogCitjb25maWcgU1VTUEVORF9CTE9DS0VSX1NUQVRTCisJYm9v bCAiU3VzcGVuZCBibG9ja2VycyBzdGF0aXN0aWNzIgorCWRlcGVuZHMgb24gT1BQT1JUVU5JU1RJ Q19TVVNQRU5ECisJZGVmYXVsdCB5CisJLS0taGVscC0tLQorCSAgVXNlIC9zeXMva2VybmVsL2Rl YnVnL3N1c3BlbmRfYmxvY2tlcnMgdG8gcmVwb3J0IHN1c3BlbmQgYmxvY2tlcnMKKwkgIHN0YXRp c3RpY3MuCisKIGNvbmZpZyBVU0VSX1NVU1BFTkRfQkxPQ0tFUlMKIAlib29sICJVc2VyIHNwYWNl IHN1c3BlbmQgYmxvY2tlcnMiCiAJZGVwZW5kcyBvbiBPUFBPUlRVTklTVElDX1NVU1BFTkQKZGlm ZiAtLWdpdCBhL2tlcm5lbC9wb3dlci9vcHBvcnR1bmlzdGljX3N1c3BlbmQuYyBiL2tlcm5lbC9w b3dlci9vcHBvcnR1bmlzdGljX3N1c3BlbmQuYwppbmRleCBjMmRhZDc2Li4zZjAxNTNkIDEwMDY0 NAotLS0gYS9rZXJuZWwvcG93ZXIvb3Bwb3J0dW5pc3RpY19zdXNwZW5kLmMKKysrIGIva2VybmVs L3Bvd2VyL29wcG9ydHVuaXN0aWNfc3VzcGVuZC5jCkBAIC0zNSw2ICszNSw3IEBAIG1vZHVsZV9w YXJhbV9uYW1lZChkZWJ1Z19tYXNrLCBkZWJ1Z19tYXNrLCBpbnQsIFNfSVJVR08gfCBTX0lXVVNS IHwgU19JV0dSUCk7CiAKICNkZWZpbmUgU0JfSU5JVElBTElaRUQgICAgICAgICAgICAoMVUgPDwg OCkKICNkZWZpbmUgU0JfQUNUSVZFICAgICAgICAgICAgICAgICAoMVUgPDwgOSkKKyNkZWZpbmUg U0JfUFJFVkVOVElOR19TVVNQRU5EICAgICAoMVUgPDwgMTApCiAKIERFRklORV9TVVNQRU5EX0JM T0NLRVIobWFpbl9zdXNwZW5kX2Jsb2NrZXIsIG1haW4pOwogCkBAIC00NSw2ICs0NiwxMTggQEAg c3RhdGljIExJU1RfSEVBRChhY3RpdmVfYmxvY2tlcnMpOwogc3RhdGljIGludCBjdXJyZW50X2V2 ZW50X251bTsKIHN0YXRpYyBzdXNwZW5kX3N0YXRlX3QgcmVxdWVzdGVkX3N1c3BlbmRfc3RhdGUg PSBQTV9TVVNQRU5EX01FTTsKIHN0YXRpYyBib29sIGVuYWJsZV9zdXNwZW5kX2Jsb2NrZXJzOwor c3RhdGljIERFRklORV9TVVNQRU5EX0JMT0NLRVIodW5rbm93bl93YWtldXAsIHVua25vd25fd2Fr ZXVwcyk7CisKKyNpZmRlZiBDT05GSUdfU1VTUEVORF9CTE9DS0VSX1NUQVRTCitzdGF0aWMgc3Ry dWN0IHN1c3BlbmRfYmxvY2tlcl9zdGF0cyBkcm9wcGVkX3N1c3BlbmRfYmxvY2tlcnM7CitzdGF0 aWMga3RpbWVfdCBsYXN0X3NsZWVwX3RpbWVfdXBkYXRlOworc3RhdGljIGJvb2wgd2FpdF9mb3Jf d2FrZXVwOworCitzdGF0aWMgdm9pZCBzdXNwZW5kX2Jsb2NrZXJfc3RhdF9pbml0KHN0cnVjdCBz dXNwZW5kX2Jsb2NrZXJfc3RhdHMgKnN0YXQpCit7CisJc3RhdC0+Y291bnQgPSAwOworCXN0YXQt Pndha2V1cF9jb3VudCA9IDA7CisJc3RhdC0+dG90YWxfdGltZSA9IGt0aW1lX3NldCgwLCAwKTsK KwlzdGF0LT5wcmV2ZW50X3N1c3BlbmRfdGltZSA9IGt0aW1lX3NldCgwLCAwKTsKKwlzdGF0LT5t YXhfdGltZSA9IGt0aW1lX3NldCgwLCAwKTsKKwlzdGF0LT5sYXN0X3RpbWUgPSBrdGltZV9zZXQo MCwgMCk7Cit9CisKK3N0YXRpYyB2b2lkIGluaXRfZHJvcHBlZF9zdXNwZW5kX2Jsb2NrZXJzKHZv aWQpCit7CisJc3VzcGVuZF9ibG9ja2VyX3N0YXRfaW5pdCgmZHJvcHBlZF9zdXNwZW5kX2Jsb2Nr ZXJzKTsKK30KKworc3RhdGljIHZvaWQgc3VzcGVuZF9ibG9ja2VyX3N0YXRfZHJvcChzdHJ1Y3Qg c3VzcGVuZF9ibG9ja2VyX3N0YXRzICpzdGF0KQoreworCWlmICghc3RhdC0+Y291bnQpCisJCXJl dHVybjsKKworCWRyb3BwZWRfc3VzcGVuZF9ibG9ja2Vycy5jb3VudCArPSBzdGF0LT5jb3VudDsK Kwlkcm9wcGVkX3N1c3BlbmRfYmxvY2tlcnMudG90YWxfdGltZSA9IGt0aW1lX2FkZCgKKwkJZHJv cHBlZF9zdXNwZW5kX2Jsb2NrZXJzLnRvdGFsX3RpbWUsIHN0YXQtPnRvdGFsX3RpbWUpOworCWRy b3BwZWRfc3VzcGVuZF9ibG9ja2Vycy5wcmV2ZW50X3N1c3BlbmRfdGltZSA9IGt0aW1lX2FkZCgK KwkJZHJvcHBlZF9zdXNwZW5kX2Jsb2NrZXJzLnByZXZlbnRfc3VzcGVuZF90aW1lLAorCQlzdGF0 LT5wcmV2ZW50X3N1c3BlbmRfdGltZSk7CisJZHJvcHBlZF9zdXNwZW5kX2Jsb2NrZXJzLm1heF90 aW1lID0ga3RpbWVfYWRkKAorCQlkcm9wcGVkX3N1c3BlbmRfYmxvY2tlcnMubWF4X3RpbWUsIHN0 YXQtPm1heF90aW1lKTsKK30KKworc3RhdGljIHZvaWQgc3VzcGVuZF91bmJsb2NrX3N0YXQoc3Ry dWN0IHN1c3BlbmRfYmxvY2tlciAqYmxvY2tlcikKK3sKKwlzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2Vy X3N0YXRzICpzdGF0ID0gJmJsb2NrZXItPnN0YXQ7CisJa3RpbWVfdCBkdXJhdGlvbjsKKwlrdGlt ZV90IG5vdzsKKworCWlmICghKGJsb2NrZXItPmZsYWdzICYgU0JfQUNUSVZFKSkKKwkJcmV0dXJu OworCisJbm93ID0ga3RpbWVfZ2V0KCk7CisJc3RhdC0+Y291bnQrKzsKKwlkdXJhdGlvbiA9IGt0 aW1lX3N1Yihub3csIHN0YXQtPmxhc3RfdGltZSk7CisJc3RhdC0+dG90YWxfdGltZSA9IGt0aW1l X2FkZChzdGF0LT50b3RhbF90aW1lLCBkdXJhdGlvbik7CisJaWYgKGt0aW1lX3RvX25zKGR1cmF0 aW9uKSA+IGt0aW1lX3RvX25zKHN0YXQtPm1heF90aW1lKSkKKwkJc3RhdC0+bWF4X3RpbWUgPSBk dXJhdGlvbjsKKworCXN0YXQtPmxhc3RfdGltZSA9IGt0aW1lX2dldCgpOworCWlmIChibG9ja2Vy LT5mbGFncyAmIFNCX1BSRVZFTlRJTkdfU1VTUEVORCkgeworCQlkdXJhdGlvbiA9IGt0aW1lX3N1 Yihub3csIGxhc3Rfc2xlZXBfdGltZV91cGRhdGUpOworCQlzdGF0LT5wcmV2ZW50X3N1c3BlbmRf dGltZSA9IGt0aW1lX2FkZCgKKwkJCXN0YXQtPnByZXZlbnRfc3VzcGVuZF90aW1lLCBkdXJhdGlv bik7CisJCWJsb2NrZXItPmZsYWdzICY9IH5TQl9QUkVWRU5USU5HX1NVU1BFTkQ7CisJfQorfQor CitzdGF0aWMgdm9pZCBzdXNwZW5kX2Jsb2NrX3N0YXQoc3RydWN0IHN1c3BlbmRfYmxvY2tlciAq YmxvY2tlcikKK3sKKwlpZiAod2FpdF9mb3Jfd2FrZXVwKSB7CisJCWlmIChkZWJ1Z19tYXNrICYg REVCVUdfV0FLRVVQKQorCQkJcHJfaW5mbygid2FrZXVwIHN1c3BlbmQgYmxvY2tlcjogJXNcbiIs IGJsb2NrZXItPm5hbWUpOworCisJCXdhaXRfZm9yX3dha2V1cCA9IGZhbHNlOworCQlibG9ja2Vy LT5zdGF0Lndha2V1cF9jb3VudCsrOworCX0KKwlpZiAoIShibG9ja2VyLT5mbGFncyAmIFNCX0FD VElWRSkpCisJCWJsb2NrZXItPnN0YXQubGFzdF90aW1lID0ga3RpbWVfZ2V0KCk7Cit9CisKK3N0 YXRpYyB2b2lkIHVwZGF0ZV9zbGVlcF93YWl0X3N0YXRzKGJvb2wgZG9uZSkKK3sKKwlzdHJ1Y3Qg c3VzcGVuZF9ibG9ja2VyICpibG9ja2VyOworCWt0aW1lX3Qgbm93LCBlbGFwc2VkLCBhZGQ7CisK Kwlub3cgPSBrdGltZV9nZXQoKTsKKwllbGFwc2VkID0ga3RpbWVfc3ViKG5vdywgbGFzdF9zbGVl cF90aW1lX3VwZGF0ZSk7CisJbGlzdF9mb3JfZWFjaF9lbnRyeShibG9ja2VyLCAmYWN0aXZlX2Js b2NrZXJzLCBsaW5rKSB7CisJCXN0cnVjdCBzdXNwZW5kX2Jsb2NrZXJfc3RhdHMgKnN0YXQgPSAm YmxvY2tlci0+c3RhdDsKKworCQlpZiAoYmxvY2tlci0+ZmxhZ3MgJiBTQl9QUkVWRU5USU5HX1NV U1BFTkQpIHsKKwkJCWFkZCA9IGVsYXBzZWQ7CisJCQlzdGF0LT5wcmV2ZW50X3N1c3BlbmRfdGlt ZSA9IGt0aW1lX2FkZCgKKwkJCQlzdGF0LT5wcmV2ZW50X3N1c3BlbmRfdGltZSwgYWRkKTsKKwkJ fQorCQlpZiAoZG9uZSkKKwkJCWJsb2NrZXItPmZsYWdzICY9IH5TQl9QUkVWRU5USU5HX1NVU1BF TkQ7CisJCWVsc2UKKwkJCWJsb2NrZXItPmZsYWdzIHw9IFNCX1BSRVZFTlRJTkdfU1VTUEVORDsK Kwl9CisJbGFzdF9zbGVlcF90aW1lX3VwZGF0ZSA9IG5vdzsKK30KKwordm9pZCBhYm91dF90b19l bnRlcl9zdXNwZW5kKHZvaWQpCit7CisJd2FpdF9mb3Jfd2FrZXVwID0gdHJ1ZTsKK30KKworI2Vs c2UgLyogIUNPTkZJR19TVVNQRU5EX0JMT0NLRVJfU1RBVFMgKi8KKworc3RhdGljIGlubGluZSB2 b2lkIGluaXRfZHJvcHBlZF9zdXNwZW5kX2Jsb2NrZXJzKHZvaWQpIHt9CitzdGF0aWMgaW5saW5l IHZvaWQgc3VzcGVuZF9ibG9ja2VyX3N0YXRfaW5pdChzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyX3N0 YXRzICpzKSB7fQorc3RhdGljIGlubGluZSB2b2lkIHN1c3BlbmRfYmxvY2tlcl9zdGF0X2Ryb3Ao c3RydWN0IHN1c3BlbmRfYmxvY2tlcl9zdGF0cyAqcykge30KK3N0YXRpYyBpbmxpbmUgdm9pZCBz dXNwZW5kX3VuYmxvY2tfc3RhdChzdHJ1Y3Qgc3VzcGVuZF9ibG9ja2VyICpibG9ja2VyKSB7fQor c3RhdGljIGlubGluZSB2b2lkIHN1c3BlbmRfYmxvY2tfc3RhdChzdHJ1Y3Qgc3VzcGVuZF9ibG9j a2VyICpibG9ja2VyKSB7fQorc3RhdGljIGlubGluZSB2b2lkIHVwZGF0ZV9zbGVlcF93YWl0X3N0 YXRzKGJvb2wgZG9uZSkge30KKyNlbmRpZiAvKiAhQ09ORklHX1NVU1BFTkRfQkxPQ0tFUl9TVEFU UyAqLwogCiAjZGVmaW5lIHByX2luZm9fdGltZShmbXQsIGFyZ3MuLi4pIFwKIAlkbyB7IFwKQEAg LTEwMyw3ICsyMTYsOCBAQCBzdGF0aWMgdm9pZCBzdXNwZW5kX3dvcmtlcihzdHJ1Y3Qgd29ya19z dHJ1Y3QgKndvcmspCiAJaWYgKGN1cnJlbnRfZXZlbnRfbnVtID09IGVudHJ5X2V2ZW50X251bSkg ewogCQlpZiAoZGVidWdfbWFzayAmIERFQlVHX1NVU1BFTkQpCiAJCQlwcl9pbmZvKCJQTTogcG1f c3VzcGVuZCgpIHJldHVybmVkIHdpdGggbm8gZXZlbnRcbiIpOwotCQlxdWV1ZV93b3JrKHBtX3dx LCB3b3JrKTsKKwkJc3VzcGVuZF9ibG9jaygmdW5rbm93bl93YWtldXApOworCQlzdXNwZW5kX3Vu YmxvY2soJnVua25vd25fd2FrZXVwKTsKIAl9CiAKIGFib3J0OgpAQCAtMTI3LDYgKzI0MSw4IEBA IHZvaWQgc3VzcGVuZF9ibG9ja2VyX3JlZ2lzdGVyKHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJs b2NrZXIpCiAJaWYgKGRlYnVnX21hc2sgJiBERUJVR19TVVNQRU5EX0JMT0NLRVIpCiAJCXByX2lu Zm8oIiVzOiBSZWdpc3RlcmluZyAlc1xuIiwgX19mdW5jX18sIGJsb2NrZXItPm5hbWUpOwogCisJ c3VzcGVuZF9ibG9ja2VyX3N0YXRfaW5pdCgmYmxvY2tlci0+c3RhdCk7CisKIAlibG9ja2VyLT5m bGFncyA9IFNCX0lOSVRJQUxJWkVEOwogCUlOSVRfTElTVF9IRUFEKCZibG9ja2VyLT5saW5rKTsK IApAQCAtMTY0LDYgKzI4MCwxMCBAQCB2b2lkIHN1c3BlbmRfYmxvY2tlcl91bnJlZ2lzdGVyKHN0 cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJsb2NrZXIpCiAJCXJldHVybjsKIAogCXNwaW5fbG9ja19p cnFzYXZlKCZsaXN0X2xvY2ssIGlycWZsYWdzKTsKKworCXN1c3BlbmRfdW5ibG9ja19zdGF0KGJs b2NrZXIpOworCXN1c3BlbmRfYmxvY2tlcl9zdGF0X2Ryb3AoJmJsb2NrZXItPnN0YXQpOworCiAJ YmxvY2tlci0+ZmxhZ3MgJj0gflNCX0lOSVRJQUxJWkVEOwogCWxpc3RfZGVsKCZibG9ja2VyLT5s aW5rKTsKIAlpZiAoKGJsb2NrZXItPmZsYWdzICYgU0JfQUNUSVZFKSAmJiBsaXN0X2VtcHR5KCZh Y3RpdmVfYmxvY2tlcnMpKQpAQCAtMTkzLDExICszMTMsMTggQEAgdm9pZCBzdXNwZW5kX2Jsb2Nr KHN0cnVjdCBzdXNwZW5kX2Jsb2NrZXIgKmJsb2NrZXIpCiAJaWYgKGRlYnVnX21hc2sgJiBERUJV R19TVVNQRU5EX0JMT0NLRVIpCiAJCXByX2luZm8oIiVzOiAlc1xuIiwgX19mdW5jX18sIGJsb2Nr ZXItPm5hbWUpOwogCisJc3VzcGVuZF9ibG9ja19zdGF0KGJsb2NrZXIpOworCiAJYmxvY2tlci0+ ZmxhZ3MgfD0gU0JfQUNUSVZFOwogCWxpc3RfbW92ZSgmYmxvY2tlci0+bGluaywgJmFjdGl2ZV9i bG9ja2Vycyk7CiAKIAljdXJyZW50X2V2ZW50X251bSsrOwogCisJaWYgKGJsb2NrZXIgPT0gJm1h aW5fc3VzcGVuZF9ibG9ja2VyKQorCQl1cGRhdGVfc2xlZXBfd2FpdF9zdGF0cyh0cnVlKTsKKwll bHNlIGlmICghc3VzcGVuZF9ibG9ja2VyX2lzX2FjdGl2ZSgmbWFpbl9zdXNwZW5kX2Jsb2NrZXIp KQorCQl1cGRhdGVfc2xlZXBfd2FpdF9zdGF0cyhmYWxzZSk7CisKIAlzcGluX3VubG9ja19pcnFy ZXN0b3JlKCZsaXN0X2xvY2ssIGlycWZsYWdzKTsKIH0KIEVYUE9SVF9TWU1CT0woc3VzcGVuZF9i bG9jayk7CkBAIC0yMjIsMTMgKzM0OSwxOSBAQCB2b2lkIHN1c3BlbmRfdW5ibG9jayhzdHJ1Y3Qg c3VzcGVuZF9ibG9ja2VyICpibG9ja2VyKQogCWlmIChkZWJ1Z19tYXNrICYgREVCVUdfU1VTUEVO RF9CTE9DS0VSKQogCQlwcl9pbmZvKCIlczogJXNcbiIsIF9fZnVuY19fLCBibG9ja2VyLT5uYW1l KTsKIAorCXN1c3BlbmRfdW5ibG9ja19zdGF0KGJsb2NrZXIpOworCiAJbGlzdF9tb3ZlKCZibG9j a2VyLT5saW5rLCAmaW5hY3RpdmVfYmxvY2tlcnMpOwogCWlmICgoYmxvY2tlci0+ZmxhZ3MgJiBT Ql9BQ1RJVkUpICYmIGxpc3RfZW1wdHkoJmFjdGl2ZV9ibG9ja2VycykpCiAJCXF1ZXVlX3dvcmso cG1fd3EsICZzdXNwZW5kX3dvcmspOwogCWJsb2NrZXItPmZsYWdzICY9IH4oU0JfQUNUSVZFKTsK IAotCWlmICgoZGVidWdfbWFzayAmIERFQlVHX1NVU1BFTkQpICYmIGJsb2NrZXIgPT0gJm1haW5f c3VzcGVuZF9ibG9ja2VyKQotCQlwcmludF9hY3RpdmVfc3VzcGVuZF9ibG9ja2VycygpOworCWlm IChibG9ja2VyID09ICZtYWluX3N1c3BlbmRfYmxvY2tlcikgeworCQlpZiAoZGVidWdfbWFzayAm IERFQlVHX1NVU1BFTkQpCisJCQlwcmludF9hY3RpdmVfc3VzcGVuZF9ibG9ja2VycygpOworCisJ CXVwZGF0ZV9zbGVlcF93YWl0X3N0YXRzKGZhbHNlKTsKKwl9CiAKIAlzcGluX3VubG9ja19pcnFy ZXN0b3JlKCZsaXN0X2xvY2ssIGlycWZsYWdzKTsKIH0KQEAgLTI4MywxMCArNDE2LDY5IEBAIHZv aWQgX19pbml0IG9wcG9ydHVuaXN0aWNfc3VzcGVuZF9pbml0KHZvaWQpCiB7CiAJc3VzcGVuZF9i bG9ja2VyX3JlZ2lzdGVyKCZtYWluX3N1c3BlbmRfYmxvY2tlcik7CiAJc3VzcGVuZF9ibG9jaygm bWFpbl9zdXNwZW5kX2Jsb2NrZXIpOworCXN1c3BlbmRfYmxvY2tlcl9yZWdpc3RlcigmdW5rbm93 bl93YWtldXApOworCWluaXRfZHJvcHBlZF9zdXNwZW5kX2Jsb2NrZXJzKCk7CiB9CiAKIHN0YXRp YyBzdHJ1Y3QgZGVudHJ5ICpzdXNwZW5kX2Jsb2NrZXJfc3RhdHNfZGVudHJ5OwogCisjaWZkZWYg Q09ORklHX1NVU1BFTkRfQkxPQ0tFUl9TVEFUUworc3RhdGljIGludCBwcmludF9ibG9ja2VyX3N0 YXRzKHN0cnVjdCBzZXFfZmlsZSAqbSwgY29uc3QgY2hhciAqbmFtZSwKKwkJCQlzdHJ1Y3Qgc3Vz cGVuZF9ibG9ja2VyX3N0YXRzICpzdGF0LCBpbnQgZmxhZ3MpCit7CisJaW50IGxvY2tfY291bnQg PSBzdGF0LT5jb3VudDsKKwlrdGltZV90IGFjdGl2ZV90aW1lID0ga3RpbWVfc2V0KDAsIDApOwor CWt0aW1lX3QgdG90YWxfdGltZSA9IHN0YXQtPnRvdGFsX3RpbWU7CisJa3RpbWVfdCBtYXhfdGlt ZSA9IHN0YXQtPm1heF90aW1lOworCWt0aW1lX3QgcHJldmVudF9zdXNwZW5kX3RpbWUgPSBzdGF0 LT5wcmV2ZW50X3N1c3BlbmRfdGltZTsKKworCWlmIChmbGFncyAmIFNCX0FDVElWRSkgeworCQlr dGltZV90IG5vdywgYWRkX3RpbWU7CisKKwkJbm93ID0ga3RpbWVfZ2V0KCk7CisJCWFkZF90aW1l ID0ga3RpbWVfc3ViKG5vdywgc3RhdC0+bGFzdF90aW1lKTsKKwkJbG9ja19jb3VudCsrOworCQlh Y3RpdmVfdGltZSA9IGFkZF90aW1lOworCQl0b3RhbF90aW1lID0ga3RpbWVfYWRkKHRvdGFsX3Rp bWUsIGFkZF90aW1lKTsKKwkJaWYgKGZsYWdzICYgU0JfUFJFVkVOVElOR19TVVNQRU5EKQorCQkJ cHJldmVudF9zdXNwZW5kX3RpbWUgPSBrdGltZV9hZGQocHJldmVudF9zdXNwZW5kX3RpbWUsCisJ CQkJCWt0aW1lX3N1Yihub3csIGxhc3Rfc2xlZXBfdGltZV91cGRhdGUpKTsKKwkJaWYgKGFkZF90 aW1lLnR2NjQgPiBtYXhfdGltZS50djY0KQorCQkJbWF4X3RpbWUgPSBhZGRfdGltZTsKKwl9CisK KwlyZXR1cm4gc2VxX3ByaW50ZihtLCAiXCIlc1wiXHQlZFx0JWRcdCVsbGRcdCVsbGRcdCVsbGRc dCVsbGRcdCVsbGRcbiIsCisJCQluYW1lLCBsb2NrX2NvdW50LCBzdGF0LT53YWtldXBfY291bnQs CisJCQlrdGltZV90b19ucyhhY3RpdmVfdGltZSksIGt0aW1lX3RvX25zKHRvdGFsX3RpbWUpLAor CQkJa3RpbWVfdG9fbnMocHJldmVudF9zdXNwZW5kX3RpbWUpLAorCQkJa3RpbWVfdG9fbnMobWF4 X3RpbWUpLAorCQkJa3RpbWVfdG9fbnMoc3RhdC0+bGFzdF90aW1lKSk7Cit9CisKK3N0YXRpYyBp bnQgc3VzcGVuZF9ibG9ja2VyX3N0YXRzX3Nob3coc3RydWN0IHNlcV9maWxlICptLCB2b2lkICp1 bnVzZWQpCit7CisJdW5zaWduZWQgbG9uZyBpcnFmbGFnczsKKwlzdHJ1Y3Qgc3VzcGVuZF9ibG9j a2VyICpibG9ja2VyOworCisJc2VxX3B1dHMobSwgIm5hbWVcdGNvdW50XHR3YWtlX2NvdW50XHRh Y3RpdmVfc2luY2UiCisJCSAiXHR0b3RhbF90aW1lXHRzbGVlcF90aW1lXHRtYXhfdGltZVx0bGFz dF9jaGFuZ2VcbiIpOworCisJc3Bpbl9sb2NrX2lycXNhdmUoJmxpc3RfbG9jaywgaXJxZmxhZ3Mp OworCWxpc3RfZm9yX2VhY2hfZW50cnkoYmxvY2tlciwgJmFjdGl2ZV9ibG9ja2VycywgbGluaykK KwkJcHJpbnRfYmxvY2tlcl9zdGF0cyhtLAorCQkJCWJsb2NrZXItPm5hbWUsICZibG9ja2VyLT5z dGF0LCBibG9ja2VyLT5mbGFncyk7CisKKwlsaXN0X2Zvcl9lYWNoX2VudHJ5KGJsb2NrZXIsICZp bmFjdGl2ZV9ibG9ja2VycywgbGluaykKKwkJcHJpbnRfYmxvY2tlcl9zdGF0cyhtLAorCQkJCWJs b2NrZXItPm5hbWUsICZibG9ja2VyLT5zdGF0LCBibG9ja2VyLT5mbGFncyk7CisKKwlwcmludF9i bG9ja2VyX3N0YXRzKG0sICJkZWxldGVkIiwgJmRyb3BwZWRfc3VzcGVuZF9ibG9ja2VycywgMCk7 CisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbGlzdF9sb2NrLCBpcnFmbGFncyk7CisJcmV0dXJu IDA7Cit9CisKKyNlbHNlCisKIHN0YXRpYyBpbnQgc3VzcGVuZF9ibG9ja2VyX3N0YXRzX3Nob3co c3RydWN0IHNlcV9maWxlICptLCB2b2lkICp1bnVzZWQpCiB7CiAJdW5zaWduZWQgbG9uZyBpcnFm bGFnczsKQEAgLTMwMiw2ICs0OTQsOCBAQCBzdGF0aWMgaW50IHN1c3BlbmRfYmxvY2tlcl9zdGF0 c19zaG93KHN0cnVjdCBzZXFfZmlsZSAqbSwgdm9pZCAqdW51c2VkKQogCXJldHVybiAwOwogfQog CisjZW5kaWYKKwogc3RhdGljIGludCBzdXNwZW5kX2Jsb2NrZXJfc3RhdHNfb3BlbihzdHJ1Y3Qg aW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKIHsKIAlyZXR1cm4gc2luZ2xlX29wZW4o ZmlsZSwgc3VzcGVuZF9ibG9ja2VyX3N0YXRzX3Nob3csIE5VTEwpOwpkaWZmIC0tZ2l0IGEva2Vy bmVsL3Bvd2VyL3Bvd2VyLmggYi9rZXJuZWwvcG93ZXIvcG93ZXIuaAppbmRleCAyZTljZmQ1Li5l MTNjOTc1IDEwMDY0NAotLS0gYS9rZXJuZWwvcG93ZXIvcG93ZXIuaAorKysgYi9rZXJuZWwvcG93 ZXIvcG93ZXIuaApAQCAtMjQ1LDMgKzI0NSw4IEBAIGV4dGVybiB2b2lkIF9faW5pdCBvcHBvcnR1 bmlzdGljX3N1c3BlbmRfaW5pdCh2b2lkKTsKICNlbHNlCiBzdGF0aWMgaW5saW5lIHZvaWQgb3Bw b3J0dW5pc3RpY19zdXNwZW5kX2luaXQodm9pZCkge30KICNlbmRpZgorI2lmZGVmIENPTkZJR19T VVNQRU5EX0JMT0NLRVJfU1RBVFMKK3ZvaWQgYWJvdXRfdG9fZW50ZXJfc3VzcGVuZCh2b2lkKTsK KyNlbHNlCitzdGF0aWMgaW5saW5lIHZvaWQgYWJvdXRfdG9fZW50ZXJfc3VzcGVuZCh2b2lkKSB7 fQorI2VuZGlmCmRpZmYgLS1naXQgYS9rZXJuZWwvcG93ZXIvc3VzcGVuZC5jIGIva2VybmVsL3Bv d2VyL3N1c3BlbmQuYwppbmRleCA5ZWIzODc2Li5kZjY5NGU3IDEwMDY0NAotLS0gYS9rZXJuZWwv cG93ZXIvc3VzcGVuZC5jCisrKyBiL2tlcm5lbC9wb3dlci9zdXNwZW5kLmMKQEAgLTE1OCw4ICsx NTgsMTAgQEAgc3RhdGljIGludCBzdXNwZW5kX2VudGVyKHN1c3BlbmRfc3RhdGVfdCBzdGF0ZSkK IAogCWVycm9yID0gc3lzZGV2X3N1c3BlbmQoUE1TR19TVVNQRU5EKTsKIAlpZiAoIWVycm9yKSB7 Ci0JCWlmICghc3VzcGVuZF9pc19ibG9ja2VkKCkgJiYgIXN1c3BlbmRfdGVzdChURVNUX0NPUkUp KQorCQlpZiAoIXN1c3BlbmRfaXNfYmxvY2tlZCgpICYmICFzdXNwZW5kX3Rlc3QoVEVTVF9DT1JF KSkgeworCQkJYWJvdXRfdG9fZW50ZXJfc3VzcGVuZCgpOwogCQkJZXJyb3IgPSBzdXNwZW5kX29w cy0+ZW50ZXIoc3RhdGUpOworCQl9CiAJCXN5c2Rldl9yZXN1bWUoKTsKIAl9CiAKLS0gCjEuNi41 LjEKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4 LXBtIG1haWxpbmcgbGlzdApsaW51eC1wbUBsaXN0cy5saW51eC1mb3VuZGF0aW9uLm9yZwpodHRw czovL2xpc3RzLmxpbnV4LWZvdW5kYXRpb24ub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtcG0= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752855Ab0ENEMk (ORCPT ); Fri, 14 May 2010 00:12:40 -0400 Received: from mail-px0-f174.google.com ([209.85.212.174]:52482 "EHLO mail-px0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751834Ab0ENELj (ORCPT ); Fri, 14 May 2010 00:11:39 -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" , =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= , Pavel Machek , Tejun Heo , Len Brown , Jesse Barnes , Magnus Damm , Wu Fengguang , Andrew Morton , Maxim Levitsky Subject: [PATCH 5/8] PM: suspend_block: Add suspend_blocker stats Date: Thu, 13 May 2010 21:11:10 -0700 Message-Id: <1273810273-3039-6-git-send-email-arve@android.com> X-Mailer: git-send-email 1.6.5.1 In-Reply-To: <1273810273-3039-5-git-send-email-arve@android.com> References: <1273810273-3039-1-git-send-email-arve@android.com> <1273810273-3039-2-git-send-email-arve@android.com> <1273810273-3039-3-git-send-email-arve@android.com> <1273810273-3039-4-git-send-email-arve@android.com> <1273810273-3039-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 | 27 +++++- kernel/power/Kconfig | 8 ++ kernel/power/opportunistic_suspend.c | 200 +++++++++++++++++++++++++++++++++- kernel/power/power.h | 5 + kernel/power/suspend.c | 4 +- 5 files changed, 239 insertions(+), 5 deletions(-) diff --git a/include/linux/suspend_blocker.h b/include/linux/suspend_blocker.h index 8788302..256af15 100755 --- a/include/linux/suspend_blocker.h +++ b/include/linux/suspend_blocker.h @@ -17,11 +17,35 @@ #define _LINUX_SUSPEND_BLOCKER_H #include +#include + +/** + * struct suspend_blocker_stats - statistics for a suspend blocker + * + * @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. + */ +struct suspend_blocker_stats { +#ifdef CONFIG_SUSPEND_BLOCKER_STATS + unsigned int count; + unsigned int wakeup_count; + ktime_t total_time; + ktime_t prevent_suspend_time; + ktime_t max_time; + ktime_t last_time; +#endif +}; /** * 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 and active state and statistics. * @name: Suspend blocker name used for debugging. * * When a suspend_blocker is active it prevents the system from entering @@ -34,6 +58,7 @@ struct suspend_blocker { struct list_head link; int flags; const char *name; + struct suspend_blocker_stats stat; #endif }; diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 2e665cd..16a2570 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -146,6 +146,14 @@ 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 blockers statistics" + depends on OPPORTUNISTIC_SUSPEND + default y + ---help--- + Use /sys/kernel/debug/suspend_blockers to report suspend blockers + statistics. + config USER_SUSPEND_BLOCKERS bool "User space suspend blockers" depends on OPPORTUNISTIC_SUSPEND diff --git a/kernel/power/opportunistic_suspend.c b/kernel/power/opportunistic_suspend.c index c2dad76..3f0153d 100644 --- a/kernel/power/opportunistic_suspend.c +++ b/kernel/power/opportunistic_suspend.c @@ -35,6 +35,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) DEFINE_SUSPEND_BLOCKER(main_suspend_blocker, main); @@ -45,6 +46,118 @@ static LIST_HEAD(active_blockers); static int current_event_num; static suspend_state_t requested_suspend_state = PM_SUSPEND_MEM; static bool enable_suspend_blockers; +static DEFINE_SUSPEND_BLOCKER(unknown_wakeup, unknown_wakeups); + +#ifdef CONFIG_SUSPEND_BLOCKER_STATS +static struct suspend_blocker_stats dropped_suspend_blockers; +static ktime_t last_sleep_time_update; +static bool wait_for_wakeup; + +static void suspend_blocker_stat_init(struct suspend_blocker_stats *stat) +{ + stat->count = 0; + stat->wakeup_count = 0; + stat->total_time = ktime_set(0, 0); + stat->prevent_suspend_time = ktime_set(0, 0); + stat->max_time = ktime_set(0, 0); + stat->last_time = ktime_set(0, 0); +} + +static void init_dropped_suspend_blockers(void) +{ + suspend_blocker_stat_init(&dropped_suspend_blockers); +} + +static void suspend_blocker_stat_drop(struct suspend_blocker_stats *stat) +{ + if (!stat->count) + return; + + dropped_suspend_blockers.count += stat->count; + dropped_suspend_blockers.total_time = ktime_add( + dropped_suspend_blockers.total_time, stat->total_time); + dropped_suspend_blockers.prevent_suspend_time = ktime_add( + dropped_suspend_blockers.prevent_suspend_time, + stat->prevent_suspend_time); + dropped_suspend_blockers.max_time = ktime_add( + dropped_suspend_blockers.max_time, stat->max_time); +} + +static void suspend_unblock_stat(struct suspend_blocker *blocker) +{ + struct suspend_blocker_stats *stat = &blocker->stat; + ktime_t duration; + ktime_t now; + + if (!(blocker->flags & SB_ACTIVE)) + return; + + now = ktime_get(); + stat->count++; + duration = ktime_sub(now, stat->last_time); + stat->total_time = ktime_add(stat->total_time, duration); + if (ktime_to_ns(duration) > ktime_to_ns(stat->max_time)) + stat->max_time = duration; + + stat->last_time = ktime_get(); + if (blocker->flags & SB_PREVENTING_SUSPEND) { + duration = ktime_sub(now, last_sleep_time_update); + stat->prevent_suspend_time = ktime_add( + stat->prevent_suspend_time, duration); + blocker->flags &= ~SB_PREVENTING_SUSPEND; + } +} + +static void suspend_block_stat(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(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) { + struct suspend_blocker_stats *stat = &blocker->stat; + + if (blocker->flags & SB_PREVENTING_SUSPEND) { + add = elapsed; + stat->prevent_suspend_time = ktime_add( + 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 /* !CONFIG_SUSPEND_BLOCKER_STATS */ + +static inline void init_dropped_suspend_blockers(void) {} +static inline void suspend_blocker_stat_init(struct suspend_blocker_stats *s) {} +static inline void suspend_blocker_stat_drop(struct suspend_blocker_stats *s) {} +static inline void suspend_unblock_stat(struct suspend_blocker *blocker) {} +static inline void suspend_block_stat(struct suspend_blocker *blocker) {} +static inline void update_sleep_wait_stats(bool done) {} +#endif /* !CONFIG_SUSPEND_BLOCKER_STATS */ #define pr_info_time(fmt, args...) \ do { \ @@ -103,7 +216,8 @@ static void suspend_worker(struct work_struct *work) if (current_event_num == entry_event_num) { if (debug_mask & DEBUG_SUSPEND) pr_info("PM: pm_suspend() returned with no event\n"); - queue_work(pm_wq, work); + suspend_block(&unknown_wakeup); + suspend_unblock(&unknown_wakeup); } abort: @@ -127,6 +241,8 @@ void suspend_blocker_register(struct suspend_blocker *blocker) if (debug_mask & DEBUG_SUSPEND_BLOCKER) pr_info("%s: Registering %s\n", __func__, blocker->name); + suspend_blocker_stat_init(&blocker->stat); + blocker->flags = SB_INITIALIZED; INIT_LIST_HEAD(&blocker->link); @@ -164,6 +280,10 @@ void suspend_blocker_unregister(struct suspend_blocker *blocker) return; spin_lock_irqsave(&list_lock, irqflags); + + suspend_unblock_stat(blocker); + suspend_blocker_stat_drop(&blocker->stat); + blocker->flags &= ~SB_INITIALIZED; list_del(&blocker->link); if ((blocker->flags & SB_ACTIVE) && list_empty(&active_blockers)) @@ -193,11 +313,18 @@ void suspend_block(struct suspend_blocker *blocker) if (debug_mask & DEBUG_SUSPEND_BLOCKER) pr_info("%s: %s\n", __func__, blocker->name); + suspend_block_stat(blocker); + blocker->flags |= SB_ACTIVE; list_move(&blocker->link, &active_blockers); current_event_num++; + if (blocker == &main_suspend_blocker) + update_sleep_wait_stats(true); + else if (!suspend_blocker_is_active(&main_suspend_blocker)) + update_sleep_wait_stats(false); + spin_unlock_irqrestore(&list_lock, irqflags); } EXPORT_SYMBOL(suspend_block); @@ -222,13 +349,19 @@ void suspend_unblock(struct suspend_blocker *blocker) if (debug_mask & DEBUG_SUSPEND_BLOCKER) pr_info("%s: %s\n", __func__, blocker->name); + suspend_unblock_stat(blocker); + list_move(&blocker->link, &inactive_blockers); if ((blocker->flags & SB_ACTIVE) && list_empty(&active_blockers)) queue_work(pm_wq, &suspend_work); blocker->flags &= ~(SB_ACTIVE); - if ((debug_mask & DEBUG_SUSPEND) && blocker == &main_suspend_blocker) - print_active_suspend_blockers(); + if (blocker == &main_suspend_blocker) { + if (debug_mask & DEBUG_SUSPEND) + print_active_suspend_blockers(); + + update_sleep_wait_stats(false); + } spin_unlock_irqrestore(&list_lock, irqflags); } @@ -283,10 +416,69 @@ void __init opportunistic_suspend_init(void) { suspend_blocker_register(&main_suspend_blocker); suspend_block(&main_suspend_blocker); + suspend_blocker_register(&unknown_wakeup); + init_dropped_suspend_blockers(); } static struct dentry *suspend_blocker_stats_dentry; +#ifdef CONFIG_SUSPEND_BLOCKER_STATS +static int print_blocker_stats(struct seq_file *m, const char *name, + struct suspend_blocker_stats *stat, int flags) +{ + int lock_count = stat->count; + ktime_t active_time = ktime_set(0, 0); + ktime_t total_time = stat->total_time; + ktime_t max_time = stat->max_time; + ktime_t prevent_suspend_time = stat->prevent_suspend_time; + + if (flags & SB_ACTIVE) { + ktime_t now, add_time; + + now = ktime_get(); + add_time = ktime_sub(now, stat->last_time); + lock_count++; + active_time = add_time; + total_time = ktime_add(total_time, add_time); + if (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", + name, lock_count, 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(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, &active_blockers, link) + print_blocker_stats(m, + blocker->name, &blocker->stat, blocker->flags); + + list_for_each_entry(blocker, &inactive_blockers, link) + print_blocker_stats(m, + blocker->name, &blocker->stat, blocker->flags); + + print_blocker_stats(m, "deleted", &dropped_suspend_blockers, 0); + spin_unlock_irqrestore(&list_lock, irqflags); + return 0; +} + +#else + static int suspend_blocker_stats_show(struct seq_file *m, void *unused) { unsigned long irqflags; @@ -302,6 +494,8 @@ static int suspend_blocker_stats_show(struct seq_file *m, void *unused) return 0; } +#endif + static int suspend_blocker_stats_open(struct inode *inode, struct file *file) { return single_open(file, suspend_blocker_stats_show, NULL); diff --git a/kernel/power/power.h b/kernel/power/power.h index 2e9cfd5..e13c975 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -245,3 +245,8 @@ extern void __init opportunistic_suspend_init(void); #else static inline void opportunistic_suspend_init(void) {} #endif +#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 9eb3876..df694e7 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -158,8 +158,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(); } -- 1.6.5.1