From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 0BDB9221E0684 for ; Wed, 13 Dec 2017 18:05:54 -0800 (PST) From: Ross Zwisler Subject: [PATCH v3 3/3] hmat: add performance attributes Date: Wed, 13 Dec 2017 19:10:19 -0700 Message-Id: <20171214021019.13579-4-ross.zwisler@linux.intel.com> In-Reply-To: <20171214021019.13579-1-ross.zwisler@linux.intel.com> References: <20171214021019.13579-1-ross.zwisler@linux.intel.com> MIME-Version: 1.0 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" To: linux-kernel@vger.kernel.org Cc: "Box, David E" , Dave Hansen , "Zheng, Lv" , linux-nvdimm@lists.01.org, "Rafael J. Wysocki" , Anaczkowski,, Robert, Lukasz, "Erik , Len Brown" , John Hubbard , Jerome Glisse , devel@acpica.org, Kogut,, "Marcin , Brice Goglin , Nachimuthu, Murugasamy" , "Rafael J. Wysocki" , Koziej,, "Joonas , Andrew Morton , Tim Chen" List-ID: QWRkIHBlcmZvcm1hbmNlIGluZm9ybWF0aW9uIGZvdW5kIGluIHRoZSBITUFUIHRvIHRoZSBzeXNm cyByZXByZXNlbnRhdGlvbi4KVGhpcyBpbmZvcm1hdGlvbiBsaXZlcyBhcyBhbiBhdHRyaWJ1dGUg Z3JvdXAgbmFtZWQgImxvY2FsX2luaXQiIGluIHRoZQptZW1vcnkgdGFyZ2V0OgoKICAjIHRyZWUg bWVtX3RndDIKICBtZW1fdGd0MgogIOKUnOKUgOKUgCBmaXJtd2FyZV9pZAogIOKUnOKUgOKUgCBp c19jYWNoZWQKICDilJzilIDilIAgbG9jYWxfaW5pdAogIOKUgsKgwqAg4pSc4pSA4pSAIG1lbV9p bml0MCAtPiAuLi8uLi9tZW1faW5pdDAKICDilILCoMKgIOKUnOKUgOKUgCBtZW1faW5pdDEgLT4g Li4vLi4vbWVtX2luaXQxCiAg4pSCwqDCoCDilJzilIDilIAgcmVhZF9id19NQnBzCiAg4pSCwqDC oCDilJzilIDilIAgcmVhZF9sYXRfbnNlYwogIOKUgsKgwqAg4pSc4pSA4pSAIHdyaXRlX2J3X01C cHMKICDilILCoMKgIOKUlOKUgOKUgCB3cml0ZV9sYXRfbnNlYwogIOKUnOKUgOKUgCBub2RlMiAt PiAuLi8uLi9ub2RlL25vZGUyCiAg4pSc4pSA4pSAIHBvd2VyCiAg4pSCwqDCoCDilJzilIDilIAg YXN5bmMKICDilILCoMKgIC4uLgogIOKUnOKUgOKUgCBzdWJzeXN0ZW0gLT4gLi4vLi4vLi4vLi4v YnVzL2htYXQKICDilJTilIDilIAgdWV2ZW50CgpUaGlzIGF0dHJpYnV0ZSBncm91cCBzdXJmYWNl cyBsYXRlbmN5IGFuZCBiYW5kd2lkdGggcGVyZm9ybWFuY2UgZm9yIGEKbWVtb3J5IHRhcmdldCBh bmQgaXRzIGxvY2FsIGluaXRpYXRvcnMuICBGb3IgZXhhbXBsZToKCiAgIyBncmVwIC4gbWVtX3Rn dDIvbG9jYWxfaW5pdC8qIDI+L2Rldi9udWxsCiAgbWVtX3RndDIvbG9jYWxfaW5pdC9yZWFkX2J3 X01CcHM6MzA3MjAKICBtZW1fdGd0Mi9sb2NhbF9pbml0L3JlYWRfbGF0X25zZWM6MTAwCiAgbWVt X3RndDIvbG9jYWxfaW5pdC93cml0ZV9id19NQnBzOjMwNzIwCiAgbWVtX3RndDIvbG9jYWxfaW5p dC93cml0ZV9sYXRfbnNlYzoxMDAKClRoZSBpbml0aWF0b3JzIGFsc28gaGF2ZSBhIHN5bWxpbmsg dG8gdGhlaXIgbG9jYWwgdGFyZ2V0czoKCiAgIyBscyAtbCBtZW1faW5pdDAvbWVtX3RndDIKICBs cnd4cnd4cnd4LiAxIHJvb3Qgcm9vdCAwIERlYyAxMyAxNjo0NSBtZW1faW5pdDAvbWVtX3RndDIg LT4gLi4vbWVtX3RndDIKCldlIGNyZWF0ZSBwZXJmb3JtYW5jZSBhdHRyaWJ1dGUgZ3JvdXBzIG9u bHkgZm9yIGxvY2FsIChpbml0aWF0b3IsdGFyZ2V0KQpwYWlyaW5ncywgd2hlcmUgdGhlIGZpcnN0 IGxvY2FsIGluaXRpYXRvciBmb3IgYSBnaXZlbiB0YXJnZXQgaXMgZGVmaW5lZCBieQp0aGUgIlBy b2Nlc3NvciBQcm94aW1pdHkgRG9tYWluIiBmaWVsZCBpbiB0aGUgSE1BVCdzIE1lbW9yeSBTdWJz eXN0ZW0KQWRkcmVzcyBSYW5nZSBTdHJ1Y3R1cmUgdGFibGUuICBBZnRlciB3ZSBoYXZlIG9uZSBs b2NhbCBpbml0aWF0b3Igd2Ugc2Nhbgp0aGUgcGVyZm9ybWFuY2UgZGF0YSB0byBsaW5rIHRvIGFu eSBvdGhlciAibG9jYWwiIGluaXRpYXRvcnMgd2l0aCB0aGUgc2FtZQpsb2NhbCBwZXJmb3JtYW5j ZSB0byBhIGdpdmVuIG1lbW9yeSB0YXJnZXQuCgpBIGdpdmVuIHRhcmdldCBvbmx5IGhhcyBvbmUg c2V0IG9mIGxvY2FsIHBlcmZvcm1hbmNlIHZhbHVlcywgc28gZWFjaCB0YXJnZXQKd2lsbCBoYXZl IGF0IG1vc3Qgb25lICJsb2NhbF9pbml0IiBhdHRyaWJ1dGUgZ3JvdXAsIHRob3VnaCB0aGF0IGdy b3VwIGNhbgpjb250YWluIGxpbmtzIHRvIG11bHRpcGxlIGluaXRpYXRvcnMgdGhhdCBhbGwgaGF2 ZSBsb2NhbCBwZXJmb3JtYW5jZS4gIEEKZ2l2ZW4gbWVtb3J5IGluaXRpYXRvciBtYXkgaGF2ZSBt dWx0aXBsZSBsb2NhbCBtZW1vcnkgdGFyZ2V0cywgc28gbXVsdGlwbGUKIm1lbV90Z3RYIiBsaW5r cyBtYXkgZXhpc3QgZm9yIGEgZ2l2ZW4gaW5pdGlhdG9yLgoKSWYgYSBnaXZlbiBtZW1vcnkgdGFy Z2V0IGlzIGNhY2hlZCB3ZSBnaXZlIHBlcmZvcm1hbmNlIG51bWJlcnMgb25seSBmb3IgdGhlCm1l ZGlhIGl0c2VsZiwgYW5kIHJlbHkgb24gdGhlICJpc19jYWNoZWQiIGF0dHJpYnV0ZSB0byByZXBy ZXNlbnQgdGhlCmZhY3QgdGhhdCB0aGVyZSBpcyBhIGNhY2hpbmcgbGF5ZXIuCgpUaGUgZmFjdCB0 aGF0IHdlIG9ubHkgZXhwb3NlIGEgc3Vic2V0IG9mIHRoZSBwZXJmb3JtYW5jZSBpbmZvcm1hdGlv bgpwcmVzZW50ZWQgaW4gdGhlIEhNQVQgdmlhIHN5c2ZzIGFzIGEgY29tcHJvbWlzZSwgZHJpdmVu IGJ5IGZhY3QgdGhhdCB0aG9zZQp1c2FnZXMgd2lsbCBiZSB0aGUgaGlnaGVzdCBwZXJmb3JtaW5n IGFuZCBiZWNhdXNlIHRvIHJlcHJlc2VudCBhbGwgcG9zc2libGUKcGF0aHMgY291bGQgY2F1c2Ug YW4gdW5tYW5hZ2VhYmxlIGV4cGxvc2lvbiBvZiBzeXNmcyBlbnRyaWVzLgoKSWYgd2UgZHVtcCBl dmVyeXRoaW5nIGZyb20gdGhlIEhNQVQgaW50byBzeXNmcyB3ZSBlbmQgdXAgd2l0aApPKG51bV90 YXJnZXRzICogbnVtX2luaXRpYXRvcnMgKiBudW1fY2FjaGluZ19sZXZlbHMpIGF0dHJpYnV0ZXMu ICBFYWNoIG9mCnRoZXNlIGF0dHJpYnV0ZXMgb25seSB0YWtlcyB1cCAyIGJ5dGVzIGluIGEgU3lz dGVtIExvY2FsaXR5IExhdGVuY3kgYW5kCkJhbmR3aWR0aCBJbmZvcm1hdGlvbiBTdHJ1Y3R1cmUs IGJ1dCBpZiB3ZSBoYXZlIHRvIGNyZWF0ZSBhIGRpcmVjdG9yeSBlbnRyeQpmb3IgZWFjaCBpdCBi ZWNvbWVzIG11Y2ggbW9yZSBleHBlbnNpdmUuCgpGb3IgZXhhbXBsZSwgdmVyeSBsYXJnZSBzeXN0 ZW1zIHRvZGF5IGNhbiBoYXZlIG9uIHRoZSBvcmRlciBvZiB0aG91c2FuZHMgb2YKTlVNQSBub2Rl cy4gIFNheSB3ZSBoYXZlIGEgc3lzdGVtIHdoaWNoIHVzZWQgdG8gaGF2ZSAxLDAwMCBOVU1BIG5v ZGVzIHRoYXQKZWFjaCBoYWQgYm90aCBhIENQVSBhbmQgbG9jYWwgbWVtb3J5LiAgVGhlIEhNQVQg YWxsb3dzIHVzIHRvIHNlcGFyYXRlIHRoZQpDUFVzIGFuZCBtZW1vcnkgaW50byBzZXBhcmF0ZSBO VU1BIG5vZGVzLCBzbyB3ZSBjYW4gZW5kIHVwIHdpdGggMSwwMDAgQ1BVCmluaXRpYXRvciBOVU1B IG5vZGVzIGFuZCAxLDAwMCBtZW1vcnkgdGFyZ2V0IE5VTUEgbm9kZXMuICBJZiB3ZSByZXByZXNl bnRlZAp0aGUgcGVyZm9ybWFuY2UgaW5mb3JtYXRpb24gZm9yIGVhY2ggcG9zc2libGUgQ1BVL21l bW9yeSBwYWlyIGluIHN5c2ZzIHdlCndvdWxkIGVuZCB1cCB3aXRoIDEsMDAwLDAwMCBhdHRyaWJ1 dGUgZ3JvdXBzLgoKVGhpcyBpcyBhIGxvdCB0byBwYXNzIGluIGEgc2V0IG9mIHBhY2tlZCBkYXRh IHRhYmxlcywgYnV0IEkgdGhpbmsgd2UnbGwKYnJlYWsgc3lzZnMgaWYgd2UgdHJ5IHRvIGNyZWF0 ZSBtaWxsaW9ucyBvZiBhdHRyaWJ1dGVzLCByZWdhcmRsZXNzIG9mIGhvdwp3ZSBuZXN0IHRoZW0g aW4gYSBkaXJlY3RvcnkgaGllcmFyY2h5LgoKQnkgb25seSByZXByZXNlbnRpbmcgcGVyZm9ybWFu Y2UgaW5mb3JtYXRpb24gZm9yIGxvY2FsIChpbml0aWF0b3IsdGFyZ2V0KQpwYWlyaW5ncywgd2Ug cmVkdWNlIHRoZSBudW1iZXIgb2Ygc3lzZnMgZW50cmllcyB0byBPKG51bV90YXJnZXRzKS4KClNp Z25lZC1vZmYtYnk6IFJvc3MgWndpc2xlciA8cm9zcy56d2lzbGVyQGxpbnV4LmludGVsLmNvbT4K LS0tCiBkcml2ZXJzL2FjcGkvaG1hdC9NYWtlZmlsZSAgICAgICAgICB8ICAgMiArLQogZHJpdmVy cy9hY3BpL2htYXQvY29yZS5jICAgICAgICAgICAgfCAyNjMgKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKystCiBkcml2ZXJzL2FjcGkvaG1hdC9obWF0LmggICAgICAgICAgICB8ICAx NyArKysKIGRyaXZlcnMvYWNwaS9obWF0L3BlcmZfYXR0cmlidXRlcy5jIHwgIDU2ICsrKysrKysr CiA0IGZpbGVzIGNoYW5nZWQsIDMzNiBpbnNlcnRpb25zKCspLCAyIGRlbGV0aW9ucygtKQogY3Jl YXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvYWNwaS9obWF0L3BlcmZfYXR0cmlidXRlcy5jCgpkaWZm IC0tZ2l0IGEvZHJpdmVycy9hY3BpL2htYXQvTWFrZWZpbGUgYi9kcml2ZXJzL2FjcGkvaG1hdC9N YWtlZmlsZQppbmRleCBlZGY0YmNiMWM5N2QuLmI1ZDFkODM2ODRkYSAxMDA2NDQKLS0tIGEvZHJp dmVycy9hY3BpL2htYXQvTWFrZWZpbGUKKysrIGIvZHJpdmVycy9hY3BpL2htYXQvTWFrZWZpbGUK QEAgLTEsMiArMSwyIEBACiBvYmotJChDT05GSUdfQUNQSV9ITUFUKSA6PSBobWF0Lm8KLWhtYXQt eSA6PSBjb3JlLm8gaW5pdGlhdG9yLm8gdGFyZ2V0Lm8KK2htYXQteSA6PSBjb3JlLm8gaW5pdGlh dG9yLm8gdGFyZ2V0Lm8gcGVyZl9hdHRyaWJ1dGVzLm8KZGlmZiAtLWdpdCBhL2RyaXZlcnMvYWNw aS9obWF0L2NvcmUuYyBiL2RyaXZlcnMvYWNwaS9obWF0L2NvcmUuYwppbmRleCA2MWI5MGRhZGY4 NGIuLjg5ZTg0NjU4ZmM3MyAxMDA2NDQKLS0tIGEvZHJpdmVycy9hY3BpL2htYXQvY29yZS5jCisr KyBiL2RyaXZlcnMvYWNwaS9obWF0L2NvcmUuYwpAQCAtMjMsMTEgKzIzLDIyNSBAQAogI2luY2x1 ZGUgPGxpbnV4L3NsYWIuaD4KICNpbmNsdWRlICJobWF0LmgiCiAKKyNkZWZpbmUgTk9fVkFMVUUJ LTEKKyNkZWZpbmUgTE9DQUxfSU5JVAkibG9jYWxfaW5pdCIKKwogc3RhdGljIExJU1RfSEVBRCh0 YXJnZXRfbGlzdCk7CiBzdGF0aWMgTElTVF9IRUFEKGluaXRpYXRvcl9saXN0KTsKK0xJU1RfSEVB RChsb2NhbGl0eV9saXN0KTsKIAogc3RhdGljIGJvb2wgYmFkX2htYXQ7CiAKKy8qIFBlcmZvcm1h bmNlIGF0dHJpYnV0ZXMgZm9yIGFuIGluaXRpYXRvci90YXJnZXQgcGFpci4gKi8KK3N0YXRpYyBp bnQgZ2V0X3BlcmZvcm1hbmNlX2RhdGEodTMyIGluaXRfcHhtLCB1MzIgdGd0X3B4bSwKKwkJc3Ry dWN0IGFjcGlfaG1hdF9sb2NhbGl0eSAqaG1hdF9sb2MpCit7CisJaW50IG51bV9pbml0ID0gaG1h dF9sb2MtPm51bWJlcl9vZl9pbml0aWF0b3JfUGRzOworCWludCBudW1fdGd0ID0gaG1hdF9sb2Mt Pm51bWJlcl9vZl90YXJnZXRfUGRzOworCWludCBpbml0X2lkeCA9IE5PX1ZBTFVFOworCWludCB0 Z3RfaWR4ID0gTk9fVkFMVUU7CisJdTMyICppbml0aWF0b3JzLCAqdGFyZ2V0czsKKwl1MTYgKmVu dHJpZXMsIHZhbDsKKwlpbnQgaTsKKworCS8qIHRoZSBpbml0aWF0b3IgYXJyYXkgaXMgYWZ0ZXIg dGhlIHN0cnVjdCBhY3BpX2htYXRfbG9jYWxpdHkgZmllbGRzICovCisJaW5pdGlhdG9ycyA9ICh1 MzIgKikoaG1hdF9sb2MgKyAxKTsKKwl0YXJnZXRzID0gJmluaXRpYXRvcnNbbnVtX2luaXRdOwor CWVudHJpZXMgPSAodTE2ICopJnRhcmdldHNbbnVtX3RndF07CisKKwlmb3IgKGkgPSAwOyBpIDwg bnVtX2luaXQ7IGkrKykgeworCQlpZiAoaW5pdGlhdG9yc1tpXSA9PSBpbml0X3B4bSkgeworCQkJ aW5pdF9pZHggPSBpOworCQkJYnJlYWs7CisJCX0KKwl9CisKKwlpZiAoaW5pdF9pZHggPT0gTk9f VkFMVUUpCisJCXJldHVybiBOT19WQUxVRTsKKworCWZvciAoaSA9IDA7IGkgPCBudW1fdGd0OyBp KyspIHsKKwkJaWYgKHRhcmdldHNbaV0gPT0gdGd0X3B4bSkgeworCQkJdGd0X2lkeCA9IGk7CisJ CQlicmVhazsKKwkJfQorCX0KKworCWlmICh0Z3RfaWR4ID09IE5PX1ZBTFVFKQorCQlyZXR1cm4g Tk9fVkFMVUU7CisKKwl2YWwgPSBlbnRyaWVzW2luaXRfaWR4Km51bV90Z3QgKyB0Z3RfaWR4XTsK KwlpZiAodmFsIDwgMTAgfHwgdmFsID09IDB4RkZGRikKKwkJcmV0dXJuIE5PX1ZBTFVFOworCisJ cmV0dXJuIChpbnQpKHZhbCAqIGhtYXRfbG9jLT5lbnRyeV9iYXNlX3VuaXQpIC8gMTA7Cit9CisK Ky8qCisgKiAnZGlyZWN0aW9uJyBpcyBlaXRoZXIgUkVBRCBvciBXUklURQorICogTGF0ZW5jeSBp cyByZXBvcnRlZCBpbiBuYW5vc2Vjb25kcyBhbmQgYmFuZHdpZHRoIGlzIHJlcG9ydGVkIGluIE1C L3MuCisgKi8KK3N0YXRpYyBpbnQgaG1hdF9nZXRfYXR0cmlidXRlKGludCBpbml0X3B4bSwgaW50 IHRndF9weG0sIGludCBkaXJlY3Rpb24sCisJCWVudW0gaG1hdF9hdHRyX3R5cGUgdHlwZSkKK3sK KwlzdHJ1Y3QgbWVtb3J5X2xvY2FsaXR5ICpsb2M7CisJaW50IHZhbHVlOworCisJbGlzdF9mb3Jf ZWFjaF9lbnRyeShsb2MsICZsb2NhbGl0eV9saXN0LCBsaXN0KSB7CisJCXN0cnVjdCBhY3BpX2ht YXRfbG9jYWxpdHkgKmhtYXRfbG9jID0gbG9jLT5obWF0X2xvYzsKKworCQlpZiAoZGlyZWN0aW9u ID09IFJFQUQgJiYgdHlwZSA9PSBMQVRFTkNZICYmCisJCSAgICAoaG1hdF9sb2MtPmRhdGFfdHlw ZSA9PSBBQ1BJX0hNQVRfQUNDRVNTX0xBVEVOQ1kgfHwKKwkJICAgICBobWF0X2xvYy0+ZGF0YV90 eXBlID09IEFDUElfSE1BVF9SRUFEX0xBVEVOQ1kpKSB7CisJCQl2YWx1ZSA9IGdldF9wZXJmb3Jt YW5jZV9kYXRhKGluaXRfcHhtLCB0Z3RfcHhtLAorCQkJCQlobWF0X2xvYyk7CisJCQlpZiAodmFs dWUgIT0gTk9fVkFMVUUpCisJCQkJcmV0dXJuIHZhbHVlOworCQl9CisKKwkJaWYgKGRpcmVjdGlv biA9PSBXUklURSAmJiB0eXBlID09IExBVEVOQ1kgJiYKKwkJICAgIChobWF0X2xvYy0+ZGF0YV90 eXBlID09IEFDUElfSE1BVF9BQ0NFU1NfTEFURU5DWSB8fAorCQkgICAgIGhtYXRfbG9jLT5kYXRh X3R5cGUgPT0gQUNQSV9ITUFUX1dSSVRFX0xBVEVOQ1kpKSB7CisJCQl2YWx1ZSA9IGdldF9wZXJm b3JtYW5jZV9kYXRhKGluaXRfcHhtLCB0Z3RfcHhtLAorCQkJCQlobWF0X2xvYyk7CisJCQlpZiAo dmFsdWUgIT0gTk9fVkFMVUUpCisJCQkJcmV0dXJuIHZhbHVlOworCQl9CisKKwkJaWYgKGRpcmVj dGlvbiA9PSBSRUFEICYmIHR5cGUgPT0gQkFORFdJRFRIICYmCisJCSAgICAoaG1hdF9sb2MtPmRh dGFfdHlwZSA9PSBBQ1BJX0hNQVRfQUNDRVNTX0JBTkRXSURUSCB8fAorCQkgICAgIGhtYXRfbG9j LT5kYXRhX3R5cGUgPT0gQUNQSV9ITUFUX1JFQURfQkFORFdJRFRIKSkgeworCQkJdmFsdWUgPSBn ZXRfcGVyZm9ybWFuY2VfZGF0YShpbml0X3B4bSwgdGd0X3B4bSwKKwkJCQkJaG1hdF9sb2MpOwor CQkJaWYgKHZhbHVlICE9IE5PX1ZBTFVFKQorCQkJCXJldHVybiB2YWx1ZTsKKwkJfQorCisJCWlm IChkaXJlY3Rpb24gPT0gV1JJVEUgJiYgdHlwZSA9PSBCQU5EV0lEVEggJiYKKwkJICAgIChobWF0 X2xvYy0+ZGF0YV90eXBlID09IEFDUElfSE1BVF9BQ0NFU1NfQkFORFdJRFRIIHx8CisJCSAgICAg aG1hdF9sb2MtPmRhdGFfdHlwZSA9PSBBQ1BJX0hNQVRfV1JJVEVfQkFORFdJRFRIKSkgeworCQkJ dmFsdWUgPSBnZXRfcGVyZm9ybWFuY2VfZGF0YShpbml0X3B4bSwgdGd0X3B4bSwKKwkJCQkJaG1h dF9sb2MpOworCQkJaWYgKHZhbHVlICE9IE5PX1ZBTFVFKQorCQkJCXJldHVybiB2YWx1ZTsKKwkJ fQorCX0KKworCXJldHVybiBOT19WQUxVRTsKK30KKworLyoKKyAqICdkaXJlY3Rpb24nIGlzIGVp dGhlciBSRUFEIG9yIFdSSVRFCisgKiBMYXRlbmN5IGlzIHJlcG9ydGVkIGluIG5hbm9zZWNvbmRz IGFuZCBiYW5kd2lkdGggaXMgcmVwb3J0ZWQgaW4gTUIvcy4KKyAqLworaW50IGhtYXRfbG9jYWxf YXR0cmlidXRlKHN0cnVjdCBkZXZpY2UgKnRndF9kZXYsIGludCBkaXJlY3Rpb24sCisJCWVudW0g aG1hdF9hdHRyX3R5cGUgdHlwZSkKK3sKKwlzdHJ1Y3QgbWVtb3J5X3RhcmdldCAqdGd0ID0gdG9f bWVtb3J5X3RhcmdldCh0Z3RfZGV2KTsKKwlpbnQgdGd0X3B4bSA9IHRndC0+bWEtPnByb3hpbWl0 eV9kb21haW47CisJaW50IGluaXRfcHhtOworCisJaWYgKCF0Z3QtPmxvY2FsX2luaXQpCisJCXJl dHVybiBOT19WQUxVRTsKKworCWluaXRfcHhtID0gdGd0LT5sb2NhbF9pbml0LT5weG07CisJcmV0 dXJuIGhtYXRfZ2V0X2F0dHJpYnV0ZShpbml0X3B4bSwgdGd0X3B4bSwgZGlyZWN0aW9uLCB0eXBl KTsKK30KKworc3RhdGljIGJvb2wgaXNfbG9jYWxfaW5pdChpbnQgaW5pdF9weG0sIGludCB0Z3Rf cHhtLCBpbnQgcmVhZF9sYXQsCisJCWludCB3cml0ZV9sYXQsIGludCByZWFkX2J3LCBpbnQgd3Jp dGVfYncpCit7CisJaWYgKHJlYWRfbGF0ICE9IGhtYXRfZ2V0X2F0dHJpYnV0ZShpbml0X3B4bSwg dGd0X3B4bSwgUkVBRCwgTEFURU5DWSkpCisJCXJldHVybiBmYWxzZTsKKworCWlmICh3cml0ZV9s YXQgIT0gaG1hdF9nZXRfYXR0cmlidXRlKGluaXRfcHhtLCB0Z3RfcHhtLCBXUklURSwgTEFURU5D WSkpCisJCXJldHVybiBmYWxzZTsKKworCWlmIChyZWFkX2J3ICE9IGhtYXRfZ2V0X2F0dHJpYnV0 ZShpbml0X3B4bSwgdGd0X3B4bSwgUkVBRCwgQkFORFdJRFRIKSkKKwkJcmV0dXJuIGZhbHNlOwor CisJaWYgKHdyaXRlX2J3ICE9IGhtYXRfZ2V0X2F0dHJpYnV0ZShpbml0X3B4bSwgdGd0X3B4bSwg V1JJVEUsIEJBTkRXSURUSCkpCisJCXJldHVybiBmYWxzZTsKKworCXJldHVybiB0cnVlOworfQor CitzdGF0aWMgY29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCBwZXJmb3JtYW5jZV9hdHRyaWJ1 dGVfZ3JvdXAgPSB7CisJLmF0dHJzID0gcGVyZm9ybWFuY2VfYXR0cmlidXRlcywKKwkubmFtZSA9 IExPQ0FMX0lOSVQsCit9OworCitzdGF0aWMgdm9pZCByZW1vdmVfcGVyZm9ybWFuY2VfYXR0cmli dXRlcyhzdHJ1Y3QgbWVtb3J5X3RhcmdldCAqdGd0KQoreworCWlmICghdGd0LT5sb2NhbF9pbml0 KQorCQlyZXR1cm47CisKKwkvKgorCSAqIEZJWE1FOiBOZWVkIHRvIGVuaGFuY2UgdGhlIGNvcmUg c3lzZnMgY29kZSB0byByZW1vdmUgYWxsIHRoZSBsaW5rcworCSAqIGluIGJvdGggdGhlIGF0dHJp YnV0ZSBncm91cCBhbmQgaW4gdGhlIGRldmljZSBpdHNlbGYgd2hlbiB0aG9zZSBhcmUKKwkgKiBy ZW1vdmVkLgorCSAqLworCXN5c2ZzX3JlbW92ZV9ncm91cCgmdGd0LT5kZXYua29iaiwgJnBlcmZv cm1hbmNlX2F0dHJpYnV0ZV9ncm91cCk7Cit9CisKK3N0YXRpYyBpbnQgYWRkX3BlcmZvcm1hbmNl X2F0dHJpYnV0ZXMoc3RydWN0IG1lbW9yeV90YXJnZXQgKnRndCkKK3sKKwlpbnQgcmVhZF9sYXQs IHdyaXRlX2xhdCwgcmVhZF9idywgd3JpdGVfYnc7CisJaW50IHRndF9weG0gPSB0Z3QtPm1hLT5w cm94aW1pdHlfZG9tYWluOworCXN0cnVjdCBrb2JqZWN0ICppbml0X2tvYmosICp0Z3Rfa29iajsK KwlzdHJ1Y3QgZGV2aWNlICppbml0X2RldiwgKnRndF9kZXY7CisJc3RydWN0IG1lbW9yeV9pbml0 aWF0b3IgKmluaXQ7CisJaW50IHJldDsKKworCWlmICghdGd0LT5sb2NhbF9pbml0KQorCQlyZXR1 cm4gMDsKKworCXRndF9kZXYgPSAmdGd0LT5kZXY7CisJdGd0X2tvYmogPSAmdGd0X2Rldi0+a29i ajsKKworCS8qIENyZWF0ZSBlbnRyaWVzIGZvciBpbml0aWF0b3IvdGFyZ2V0IHBhaXIgaW4gdGhl IHRhcmdldC4gICovCisJcmV0ID0gc3lzZnNfY3JlYXRlX2dyb3VwKHRndF9rb2JqLCAmcGVyZm9y bWFuY2VfYXR0cmlidXRlX2dyb3VwKTsKKwlpZiAocmV0IDwgMCkKKwkJcmV0dXJuIHJldDsKKwor CS8qCisJICogSXRlcmF0ZSB0aHJvdWdoIGluaXRpYXRvcnMgYW5kIGZpbmQgYWxsIHRoZSBvbmVz IHRoYXQgaGF2ZSB0aGUgc2FtZQorCSAqIHBlcmZvcm1hbmNlIGFzIHRoZSBsb2NhbCBpbml0aWF0 b3IuCisJICovCisJcmVhZF9sYXQgPSBobWF0X2xvY2FsX2F0dHJpYnV0ZSh0Z3RfZGV2LCBSRUFE LCBMQVRFTkNZKTsKKwl3cml0ZV9sYXQgPSBobWF0X2xvY2FsX2F0dHJpYnV0ZSh0Z3RfZGV2LCBX UklURSwgTEFURU5DWSk7CisJcmVhZF9idyA9IGhtYXRfbG9jYWxfYXR0cmlidXRlKHRndF9kZXYs IFJFQUQsIEJBTkRXSURUSCk7CisJd3JpdGVfYncgPSBobWF0X2xvY2FsX2F0dHJpYnV0ZSh0Z3Rf ZGV2LCBXUklURSwgQkFORFdJRFRIKTsKKworCWxpc3RfZm9yX2VhY2hfZW50cnkoaW5pdCwgJmlu aXRpYXRvcl9saXN0LCBsaXN0KSB7CisJCWluaXRfZGV2ID0gJmluaXQtPmRldjsKKwkJaW5pdF9r b2JqID0gJmluaXRfZGV2LT5rb2JqOworCisJCWlmIChpbml0ID09IHRndC0+bG9jYWxfaW5pdCB8 fAorCQkJaXNfbG9jYWxfaW5pdChpbml0LT5weG0sIHRndF9weG0sIHJlYWRfbGF0LAorCQkJCXdy aXRlX2xhdCwgcmVhZF9idywgd3JpdGVfYncpKSB7CisJCQlyZXQgPSBzeXNmc19hZGRfbGlua190 b19ncm91cCh0Z3Rfa29iaiwgTE9DQUxfSU5JVCwKKwkJCQkJaW5pdF9rb2JqLCBkZXZfbmFtZShp bml0X2RldikpOworCQkJaWYgKHJldCA8IDApCisJCQkJZ290byBlcnI7CisKKwkJCS8qCisJCQkg KiBDcmVhdGUgYSBsaW5rIGluIHRoZSBsb2NhbCBpbml0aWF0b3IgdG8gdGhpcworCQkJICogdGFy Z2V0LgorCQkJICovCisJCQlyZXQgPSBzeXNmc19jcmVhdGVfbGluayhpbml0X2tvYmosIHRndF9r b2JqLAorCQkJCQlrb2JqZWN0X25hbWUodGd0X2tvYmopKTsKKwkJCWlmIChyZXQgPCAwKQorCQkJ CWdvdG8gZXJyOworCQl9CisKKwl9CisJdGd0LT5oYXNfcGVyZl9hdHRyaWJ1dGVzID0gdHJ1ZTsK KwlyZXR1cm4gMDsKK2VycjoKKwlyZW1vdmVfcGVyZm9ybWFuY2VfYXR0cmlidXRlcyh0Z3QpOwor CXJldHVybiByZXQ7Cit9CisKIHN0YXRpYyBpbnQgbGlua19ub2RlX2Zvcl9rb2JqKHVuc2lnbmVk IGludCBub2RlLCBzdHJ1Y3Qga29iamVjdCAqa29iaikKIHsKIAlpZiAobm9kZV9kZXZpY2VzW25v ZGVdKQpAQCAtMTMyLDYgKzM0Niw5IEBAIHN0YXRpYyB2b2lkIHJlbGVhc2VfbWVtb3J5X3Rhcmdl dChzdHJ1Y3QgZGV2aWNlICpkZXYpCiAKIHN0YXRpYyB2b2lkIF9faW5pdCByZW1vdmVfbWVtb3J5 X3RhcmdldChzdHJ1Y3QgbWVtb3J5X3RhcmdldCAqdGd0KQogeworCWlmICh0Z3QtPmhhc19wZXJm X2F0dHJpYnV0ZXMpCisJCXJlbW92ZV9wZXJmb3JtYW5jZV9hdHRyaWJ1dGVzKHRndCk7CisKIAlp ZiAodGd0LT5pc19yZWdpc3RlcmVkKSB7CiAJCXJlbW92ZV9ub2RlX2Zvcl9rb2JqKHB4bV90b19u b2RlKHRndC0+bWEtPnByb3hpbWl0eV9kb21haW4pLAogCQkJCSZ0Z3QtPmRldi5rb2JqKTsKQEAg LTI3Niw2ICs0OTMsMzggQEAgaG1hdF9wYXJzZV9hZGRyZXNzX3JhbmdlKHN0cnVjdCBhY3BpX3N1 YnRhYmxlX2hlYWRlciAqaGVhZGVyLAogCXJldHVybiAtRUlOVkFMOwogfQogCitzdGF0aWMgaW50 IF9faW5pdCBobWF0X3BhcnNlX2xvY2FsaXR5KHN0cnVjdCBhY3BpX3N1YnRhYmxlX2hlYWRlciAq aGVhZGVyLAorCQljb25zdCB1bnNpZ25lZCBsb25nIGVuZCkKK3sKKwlzdHJ1Y3QgYWNwaV9obWF0 X2xvY2FsaXR5ICpobWF0X2xvYzsKKwlzdHJ1Y3QgbWVtb3J5X2xvY2FsaXR5ICpsb2M7CisKKwlp ZiAoYmFkX2htYXQpCisJCXJldHVybiAwOworCisJaG1hdF9sb2MgPSAoc3RydWN0IGFjcGlfaG1h dF9sb2NhbGl0eSAqKWhlYWRlcjsKKwlpZiAoIWhtYXRfbG9jKSB7CisJCXByX2VycigiSE1BVDog TlVMTCB0YWJsZSBlbnRyeVxuIik7CisJCWJhZF9obWF0ID0gdHJ1ZTsKKwkJcmV0dXJuIC1FSU5W QUw7CisJfQorCisJLyogV2UgZG9uJ3QgcmVwb3J0IGNhY2hlZCBwZXJmb3JtYW5jZSBpbmZvcm1h dGlvbiBpbiBzeXNmcy4gKi8KKwlpZiAoaG1hdF9sb2MtPmZsYWdzID09IEFDUElfSE1BVF9NRU1P UlkgfHwKKwkJCWhtYXRfbG9jLT5mbGFncyA9PSBBQ1BJX0hNQVRfTEFTVF9MRVZFTF9DQUNIRSkg eworCQlsb2MgPSBremFsbG9jKHNpemVvZigqbG9jKSwgR0ZQX0tFUk5FTCk7CisJCWlmICghbG9j KSB7CisJCQliYWRfaG1hdCA9IHRydWU7CisJCQlyZXR1cm4gLUVOT01FTTsKKwkJfQorCisJCWxv Yy0+aG1hdF9sb2MgPSBobWF0X2xvYzsKKwkJbGlzdF9hZGRfdGFpbCgmbG9jLT5saXN0LCAmbG9j YWxpdHlfbGlzdCk7CisJfQorCisJcmV0dXJuIDA7Cit9CisKIHN0YXRpYyBpbnQgX19pbml0IGht YXRfcGFyc2VfY2FjaGUoc3RydWN0IGFjcGlfc3VidGFibGVfaGVhZGVyICpoZWFkZXIsCiAJCWNv bnN0IHVuc2lnbmVkIGxvbmcgZW5kKQogewpAQCAtNDMxLDYgKzY4MCw3IEBAIHNyYXRfcGFyc2Vf bWVtb3J5X2FmZmluaXR5KHN0cnVjdCBhY3BpX3N1YnRhYmxlX2hlYWRlciAqaGVhZGVyLAogc3Rh dGljIHZvaWQgaG1hdF9jbGVhbnVwKHZvaWQpCiB7CiAJc3RydWN0IG1lbW9yeV9pbml0aWF0b3Ig KmluaXQsICppbml0X2l0ZXI7CisJc3RydWN0IG1lbW9yeV9sb2NhbGl0eSAqbG9jLCAqbG9jX2l0 ZXI7CiAJc3RydWN0IG1lbW9yeV90YXJnZXQgKnRndCwgKnRndF9pdGVyOwogCiAJbGlzdF9mb3Jf ZWFjaF9lbnRyeV9zYWZlKHRndCwgdGd0X2l0ZXIsICZ0YXJnZXRfbGlzdCwgbGlzdCkKQEAgLTQz OCw2ICs2ODgsMTEgQEAgc3RhdGljIHZvaWQgaG1hdF9jbGVhbnVwKHZvaWQpCiAKIAlsaXN0X2Zv cl9lYWNoX2VudHJ5X3NhZmUoaW5pdCwgaW5pdF9pdGVyLCAmaW5pdGlhdG9yX2xpc3QsIGxpc3Qp CiAJCXJlbW92ZV9tZW1vcnlfaW5pdGlhdG9yKGluaXQpOworCisJbGlzdF9mb3JfZWFjaF9lbnRy eV9zYWZlKGxvYywgbG9jX2l0ZXIsICZsb2NhbGl0eV9saXN0LCBsaXN0KSB7CisJCWxpc3RfZGVs KCZsb2MtPmxpc3QpOworCQlrZnJlZShsb2MpOworCX0KIH0KIAogc3RhdGljIGludCBfX2luaXQg aG1hdF9pbml0KHZvaWQpCkBAIC00ODgsMTMgKzc0MywxNSBAQCBzdGF0aWMgaW50IF9faW5pdCBo bWF0X2luaXQodm9pZCkKIAl9CiAKIAlpZiAoIWFjcGlfdGFibGVfcGFyc2UoQUNQSV9TSUdfSE1B VCwgaG1hdF9ub29wX3BhcnNlKSkgewotCQlzdHJ1Y3QgYWNwaV9zdWJ0YWJsZV9wcm9jIGhtYXRf cHJvY1syXTsKKwkJc3RydWN0IGFjcGlfc3VidGFibGVfcHJvYyBobWF0X3Byb2NbM107CiAKIAkJ bWVtc2V0KGhtYXRfcHJvYywgMCwgc2l6ZW9mKGhtYXRfcHJvYykpOwogCQlobWF0X3Byb2NbMF0u aWQgPSBBQ1BJX0hNQVRfVFlQRV9BRERSRVNTX1JBTkdFOwogCQlobWF0X3Byb2NbMF0uaGFuZGxl ciA9IGhtYXRfcGFyc2VfYWRkcmVzc19yYW5nZTsKIAkJaG1hdF9wcm9jWzFdLmlkID0gQUNQSV9I TUFUX1RZUEVfQ0FDSEU7CiAJCWhtYXRfcHJvY1sxXS5oYW5kbGVyID0gaG1hdF9wYXJzZV9jYWNo ZTsKKwkJaG1hdF9wcm9jWzJdLmlkID0gQUNQSV9ITUFUX1RZUEVfTE9DQUxJVFk7CisJCWhtYXRf cHJvY1syXS5oYW5kbGVyID0gaG1hdF9wYXJzZV9sb2NhbGl0eTsKIAogCQlhY3BpX3RhYmxlX3Bh cnNlX2VudHJpZXNfYXJyYXkoQUNQSV9TSUdfSE1BVCwKIAkJCQkJc2l6ZW9mKHN0cnVjdCBhY3Bp X3RhYmxlX2htYXQpLApAQCAtNTE2LDYgKzc3MywxMCBAQCBzdGF0aWMgaW50IF9faW5pdCBobWF0 X2luaXQodm9pZCkKIAkJcmV0ID0gcmVnaXN0ZXJfbWVtb3J5X3RhcmdldCh0Z3QpOwogCQlpZiAo cmV0KQogCQkJZ290byBlcnI7CisKKwkJcmV0ID0gYWRkX3BlcmZvcm1hbmNlX2F0dHJpYnV0ZXMo dGd0KTsKKwkJaWYgKHJldCkKKwkJCWdvdG8gZXJyOwogCX0KIAogCXJldHVybiAwOwpkaWZmIC0t Z2l0IGEvZHJpdmVycy9hY3BpL2htYXQvaG1hdC5oIGIvZHJpdmVycy9hY3BpL2htYXQvaG1hdC5o CmluZGV4IDEwOGFhZDFmOGFkNy4uODkyMDBmNWM0YjM4IDEwMDY0NAotLS0gYS9kcml2ZXJzL2Fj cGkvaG1hdC9obWF0LmgKKysrIGIvZHJpdmVycy9hY3BpL2htYXQvaG1hdC5oCkBAIC0xNiw2ICsx NiwxMSBAQAogI2lmbmRlZiBfQUNQSV9ITUFUX0hfCiAjZGVmaW5lIF9BQ1BJX0hNQVRfSF8KIAor ZW51bSBobWF0X2F0dHJfdHlwZSB7CisJTEFURU5DWSwKKwlCQU5EV0lEVEgsCit9OworCiBzdHJ1 Y3QgbWVtb3J5X2luaXRpYXRvciB7CiAJc3RydWN0IGxpc3RfaGVhZCBsaXN0OwogCXN0cnVjdCBk ZXZpY2UgZGV2OwpAQCAtMzksOSArNDQsMjEgQEAgc3RydWN0IG1lbW9yeV90YXJnZXQgewogCiAJ Ym9vbCBpc19jYWNoZWQ7CiAJYm9vbCBpc19yZWdpc3RlcmVkOworCWJvb2wgaGFzX3BlcmZfYXR0 cmlidXRlczsKIH07CiAjZGVmaW5lIHRvX21lbW9yeV90YXJnZXQoZCkgY29udGFpbmVyX29mKChk KSwgc3RydWN0IG1lbW9yeV90YXJnZXQsIGRldikKIAorc3RydWN0IG1lbW9yeV9sb2NhbGl0eSB7 CisJc3RydWN0IGxpc3RfaGVhZCBsaXN0OworCXN0cnVjdCBhY3BpX2htYXRfbG9jYWxpdHkgKmht YXRfbG9jOworfTsKKwogZXh0ZXJuIGNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKm1lbW9y eV9pbml0aWF0b3JfYXR0cmlidXRlX2dyb3Vwc1tdOwogZXh0ZXJuIGNvbnN0IHN0cnVjdCBhdHRy aWJ1dGVfZ3JvdXAgKm1lbW9yeV90YXJnZXRfYXR0cmlidXRlX2dyb3Vwc1tdOworZXh0ZXJuIHN0 cnVjdCBhdHRyaWJ1dGUgKnBlcmZvcm1hbmNlX2F0dHJpYnV0ZXNbXTsKKworZXh0ZXJuIHN0cnVj dCBsaXN0X2hlYWQgbG9jYWxpdHlfbGlzdDsKKworaW50IGhtYXRfbG9jYWxfYXR0cmlidXRlKHN0 cnVjdCBkZXZpY2UgKnRndF9kZXYsIGludCBkaXJlY3Rpb24sCisJCWVudW0gaG1hdF9hdHRyX3R5 cGUgdHlwZSk7CiAjZW5kaWYgLyogX0FDUElfSE1BVF9IXyAqLwpkaWZmIC0tZ2l0IGEvZHJpdmVy cy9hY3BpL2htYXQvcGVyZl9hdHRyaWJ1dGVzLmMgYi9kcml2ZXJzL2FjcGkvaG1hdC9wZXJmX2F0 dHJpYnV0ZXMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLjYwZjEw N2I1ODgyMgotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvYWNwaS9obWF0L3BlcmZfYXR0cmli dXRlcy5jCkBAIC0wLDAgKzEsNTYgQEAKKy8qCisgKiBIZXRlcm9nZW5lb3VzIE1lbW9yeSBBdHRy aWJ1dGVzIFRhYmxlIChITUFUKSBzeXNmcyBwZXJmb3JtYW5jZSBhdHRyaWJ1dGVzCisgKgorICog Q29weXJpZ2h0IChjKSAyMDE3LCBJbnRlbCBDb3Jwb3JhdGlvbi4KKyAqCisgKiBUaGlzIHByb2dy YW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlm eSBpdAorICogdW5kZXIgdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHRoZSBHTlUgR2VuZXJh bCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVl IFNvZnR3YXJlIEZvdW5kYXRpb24uCisgKgorICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVk IGluIHRoZSBob3BlIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAorICogQU5ZIFdBUlJB TlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZ IG9yCisgKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdl bmVyYWwgUHVibGljIExpY2Vuc2UgZm9yCisgKiBtb3JlIGRldGFpbHMuCisgKi8KKworI2luY2x1 ZGUgPGxpbnV4L2FjcGkuaD4KKyNpbmNsdWRlIDxsaW51eC9kZXZpY2UuaD4KKyNpbmNsdWRlIDxs aW51eC9zeXNmcy5oPgorI2luY2x1ZGUgImhtYXQuaCIKKworc3RhdGljIHNzaXplX3QgcmVhZF9s YXRfbnNlY19zaG93KHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJCXN0cnVjdCBkZXZpY2VfYXR0cmli dXRlICphdHRyLCBjaGFyICpidWYpCit7CisJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIGht YXRfbG9jYWxfYXR0cmlidXRlKGRldiwgUkVBRCwgTEFURU5DWSkpOworfQorc3RhdGljIERFVklD RV9BVFRSX1JPKHJlYWRfbGF0X25zZWMpOworCitzdGF0aWMgc3NpemVfdCB3cml0ZV9sYXRfbnNl Y19zaG93KHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICph dHRyLCBjaGFyICpidWYpCit7CisJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIGhtYXRfbG9j YWxfYXR0cmlidXRlKGRldiwgV1JJVEUsIExBVEVOQ1kpKTsKK30KK3N0YXRpYyBERVZJQ0VfQVRU Ul9STyh3cml0ZV9sYXRfbnNlYyk7CisKK3N0YXRpYyBzc2l6ZV90IHJlYWRfYndfTUJwc19zaG93 KHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBj aGFyICpidWYpCit7CisJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIGhtYXRfbG9jYWxfYXR0 cmlidXRlKGRldiwgUkVBRCwgQkFORFdJRFRIKSk7Cit9CitzdGF0aWMgREVWSUNFX0FUVFJfUk8o cmVhZF9id19NQnBzKTsKKworc3RhdGljIHNzaXplX3Qgd3JpdGVfYndfTUJwc19zaG93KHN0cnVj dCBkZXZpY2UgKmRldiwKKwkJCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpi dWYpCit7CisJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsCisJCQlobWF0X2xvY2FsX2F0dHJp YnV0ZShkZXYsIFdSSVRFLCBCQU5EV0lEVEgpKTsKK30KK3N0YXRpYyBERVZJQ0VfQVRUUl9STyh3 cml0ZV9id19NQnBzKTsKKworc3RydWN0IGF0dHJpYnV0ZSAqcGVyZm9ybWFuY2VfYXR0cmlidXRl c1tdID0geworCSZkZXZfYXR0cl9yZWFkX2xhdF9uc2VjLmF0dHIsCisJJmRldl9hdHRyX3dyaXRl X2xhdF9uc2VjLmF0dHIsCisJJmRldl9hdHRyX3JlYWRfYndfTUJwcy5hdHRyLAorCSZkZXZfYXR0 cl93cml0ZV9id19NQnBzLmF0dHIsCisJTlVMTAorfTsKLS0gCjIuMTQuMwoKX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KTGludXgtbnZkaW1tIG1haWxpbmcg bGlzdApMaW51eC1udmRpbW1AbGlzdHMuMDEub3JnCmh0dHBzOi8vbGlzdHMuMDEub3JnL21haWxt YW4vbGlzdGluZm8vbGludXgtbnZkaW1tCg== From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ross Zwisler Subject: [PATCH v3 3/3] hmat: add performance attributes Date: Wed, 13 Dec 2017 19:10:19 -0700 Message-ID: <20171214021019.13579-4-ross.zwisler@linux.intel.com> References: <20171214021019.13579-1-ross.zwisler@linux.intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20171214021019.13579-1-ross.zwisler-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-nvdimm-bounces-hn68Rpc1hR1g9hUCZPvPmw@public.gmane.org Sender: "Linux-nvdimm" To: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Cc: "Box, David E" , Dave Hansen , "Zheng, Lv" , linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw@public.gmane.org, "Rafael J. Wysocki" , "Anaczkowski, Lukasz" , "Moore, Robert" , linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, "Odzioba, Lukasz" , "Schmauss, Erik" , Len Brown , John Hubbard , Jerome Glisse , devel-E0kO6a4B6psdnm+yROfE0A@public.gmane.org, "Kogut, Jaroslaw" , linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org, "Koss, Marcin" , Brice Goglin , "Nachimuthu, Murugasamy" , "Rafael J. Wysocki" , "Koziej, Artur" , "Lahtinen, Joonas" , Andrew Morton List-Id: linux-acpi@vger.kernel.org QWRkIHBlcmZvcm1hbmNlIGluZm9ybWF0aW9uIGZvdW5kIGluIHRoZSBITUFUIHRvIHRoZSBzeXNm cyByZXByZXNlbnRhdGlvbi4KVGhpcyBpbmZvcm1hdGlvbiBsaXZlcyBhcyBhbiBhdHRyaWJ1dGUg Z3JvdXAgbmFtZWQgImxvY2FsX2luaXQiIGluIHRoZQptZW1vcnkgdGFyZ2V0OgoKICAjIHRyZWUg bWVtX3RndDIKICBtZW1fdGd0MgogIOKUnOKUgOKUgCBmaXJtd2FyZV9pZAogIOKUnOKUgOKUgCBp c19jYWNoZWQKICDilJzilIDilIAgbG9jYWxfaW5pdAogIOKUgsKgwqAg4pSc4pSA4pSAIG1lbV9p bml0MCAtPiAuLi8uLi9tZW1faW5pdDAKICDilILCoMKgIOKUnOKUgOKUgCBtZW1faW5pdDEgLT4g Li4vLi4vbWVtX2luaXQxCiAg4pSCwqDCoCDilJzilIDilIAgcmVhZF9id19NQnBzCiAg4pSCwqDC oCDilJzilIDilIAgcmVhZF9sYXRfbnNlYwogIOKUgsKgwqAg4pSc4pSA4pSAIHdyaXRlX2J3X01C cHMKICDilILCoMKgIOKUlOKUgOKUgCB3cml0ZV9sYXRfbnNlYwogIOKUnOKUgOKUgCBub2RlMiAt PiAuLi8uLi9ub2RlL25vZGUyCiAg4pSc4pSA4pSAIHBvd2VyCiAg4pSCwqDCoCDilJzilIDilIAg YXN5bmMKICDilILCoMKgIC4uLgogIOKUnOKUgOKUgCBzdWJzeXN0ZW0gLT4gLi4vLi4vLi4vLi4v YnVzL2htYXQKICDilJTilIDilIAgdWV2ZW50CgpUaGlzIGF0dHJpYnV0ZSBncm91cCBzdXJmYWNl cyBsYXRlbmN5IGFuZCBiYW5kd2lkdGggcGVyZm9ybWFuY2UgZm9yIGEKbWVtb3J5IHRhcmdldCBh bmQgaXRzIGxvY2FsIGluaXRpYXRvcnMuICBGb3IgZXhhbXBsZToKCiAgIyBncmVwIC4gbWVtX3Rn dDIvbG9jYWxfaW5pdC8qIDI+L2Rldi9udWxsCiAgbWVtX3RndDIvbG9jYWxfaW5pdC9yZWFkX2J3 X01CcHM6MzA3MjAKICBtZW1fdGd0Mi9sb2NhbF9pbml0L3JlYWRfbGF0X25zZWM6MTAwCiAgbWVt X3RndDIvbG9jYWxfaW5pdC93cml0ZV9id19NQnBzOjMwNzIwCiAgbWVtX3RndDIvbG9jYWxfaW5p dC93cml0ZV9sYXRfbnNlYzoxMDAKClRoZSBpbml0aWF0b3JzIGFsc28gaGF2ZSBhIHN5bWxpbmsg dG8gdGhlaXIgbG9jYWwgdGFyZ2V0czoKCiAgIyBscyAtbCBtZW1faW5pdDAvbWVtX3RndDIKICBs cnd4cnd4cnd4LiAxIHJvb3Qgcm9vdCAwIERlYyAxMyAxNjo0NSBtZW1faW5pdDAvbWVtX3RndDIg LT4gLi4vbWVtX3RndDIKCldlIGNyZWF0ZSBwZXJmb3JtYW5jZSBhdHRyaWJ1dGUgZ3JvdXBzIG9u bHkgZm9yIGxvY2FsIChpbml0aWF0b3IsdGFyZ2V0KQpwYWlyaW5ncywgd2hlcmUgdGhlIGZpcnN0 IGxvY2FsIGluaXRpYXRvciBmb3IgYSBnaXZlbiB0YXJnZXQgaXMgZGVmaW5lZCBieQp0aGUgIlBy b2Nlc3NvciBQcm94aW1pdHkgRG9tYWluIiBmaWVsZCBpbiB0aGUgSE1BVCdzIE1lbW9yeSBTdWJz eXN0ZW0KQWRkcmVzcyBSYW5nZSBTdHJ1Y3R1cmUgdGFibGUuICBBZnRlciB3ZSBoYXZlIG9uZSBs b2NhbCBpbml0aWF0b3Igd2Ugc2Nhbgp0aGUgcGVyZm9ybWFuY2UgZGF0YSB0byBsaW5rIHRvIGFu eSBvdGhlciAibG9jYWwiIGluaXRpYXRvcnMgd2l0aCB0aGUgc2FtZQpsb2NhbCBwZXJmb3JtYW5j ZSB0byBhIGdpdmVuIG1lbW9yeSB0YXJnZXQuCgpBIGdpdmVuIHRhcmdldCBvbmx5IGhhcyBvbmUg c2V0IG9mIGxvY2FsIHBlcmZvcm1hbmNlIHZhbHVlcywgc28gZWFjaCB0YXJnZXQKd2lsbCBoYXZl IGF0IG1vc3Qgb25lICJsb2NhbF9pbml0IiBhdHRyaWJ1dGUgZ3JvdXAsIHRob3VnaCB0aGF0IGdy b3VwIGNhbgpjb250YWluIGxpbmtzIHRvIG11bHRpcGxlIGluaXRpYXRvcnMgdGhhdCBhbGwgaGF2 ZSBsb2NhbCBwZXJmb3JtYW5jZS4gIEEKZ2l2ZW4gbWVtb3J5IGluaXRpYXRvciBtYXkgaGF2ZSBt dWx0aXBsZSBsb2NhbCBtZW1vcnkgdGFyZ2V0cywgc28gbXVsdGlwbGUKIm1lbV90Z3RYIiBsaW5r cyBtYXkgZXhpc3QgZm9yIGEgZ2l2ZW4gaW5pdGlhdG9yLgoKSWYgYSBnaXZlbiBtZW1vcnkgdGFy Z2V0IGlzIGNhY2hlZCB3ZSBnaXZlIHBlcmZvcm1hbmNlIG51bWJlcnMgb25seSBmb3IgdGhlCm1l ZGlhIGl0c2VsZiwgYW5kIHJlbHkgb24gdGhlICJpc19jYWNoZWQiIGF0dHJpYnV0ZSB0byByZXBy ZXNlbnQgdGhlCmZhY3QgdGhhdCB0aGVyZSBpcyBhIGNhY2hpbmcgbGF5ZXIuCgpUaGUgZmFjdCB0 aGF0IHdlIG9ubHkgZXhwb3NlIGEgc3Vic2V0IG9mIHRoZSBwZXJmb3JtYW5jZSBpbmZvcm1hdGlv bgpwcmVzZW50ZWQgaW4gdGhlIEhNQVQgdmlhIHN5c2ZzIGFzIGEgY29tcHJvbWlzZSwgZHJpdmVu IGJ5IGZhY3QgdGhhdCB0aG9zZQp1c2FnZXMgd2lsbCBiZSB0aGUgaGlnaGVzdCBwZXJmb3JtaW5n IGFuZCBiZWNhdXNlIHRvIHJlcHJlc2VudCBhbGwgcG9zc2libGUKcGF0aHMgY291bGQgY2F1c2Ug YW4gdW5tYW5hZ2VhYmxlIGV4cGxvc2lvbiBvZiBzeXNmcyBlbnRyaWVzLgoKSWYgd2UgZHVtcCBl dmVyeXRoaW5nIGZyb20gdGhlIEhNQVQgaW50byBzeXNmcyB3ZSBlbmQgdXAgd2l0aApPKG51bV90 YXJnZXRzICogbnVtX2luaXRpYXRvcnMgKiBudW1fY2FjaGluZ19sZXZlbHMpIGF0dHJpYnV0ZXMu ICBFYWNoIG9mCnRoZXNlIGF0dHJpYnV0ZXMgb25seSB0YWtlcyB1cCAyIGJ5dGVzIGluIGEgU3lz dGVtIExvY2FsaXR5IExhdGVuY3kgYW5kCkJhbmR3aWR0aCBJbmZvcm1hdGlvbiBTdHJ1Y3R1cmUs IGJ1dCBpZiB3ZSBoYXZlIHRvIGNyZWF0ZSBhIGRpcmVjdG9yeSBlbnRyeQpmb3IgZWFjaCBpdCBi ZWNvbWVzIG11Y2ggbW9yZSBleHBlbnNpdmUuCgpGb3IgZXhhbXBsZSwgdmVyeSBsYXJnZSBzeXN0 ZW1zIHRvZGF5IGNhbiBoYXZlIG9uIHRoZSBvcmRlciBvZiB0aG91c2FuZHMgb2YKTlVNQSBub2Rl cy4gIFNheSB3ZSBoYXZlIGEgc3lzdGVtIHdoaWNoIHVzZWQgdG8gaGF2ZSAxLDAwMCBOVU1BIG5v ZGVzIHRoYXQKZWFjaCBoYWQgYm90aCBhIENQVSBhbmQgbG9jYWwgbWVtb3J5LiAgVGhlIEhNQVQg YWxsb3dzIHVzIHRvIHNlcGFyYXRlIHRoZQpDUFVzIGFuZCBtZW1vcnkgaW50byBzZXBhcmF0ZSBO VU1BIG5vZGVzLCBzbyB3ZSBjYW4gZW5kIHVwIHdpdGggMSwwMDAgQ1BVCmluaXRpYXRvciBOVU1B IG5vZGVzIGFuZCAxLDAwMCBtZW1vcnkgdGFyZ2V0IE5VTUEgbm9kZXMuICBJZiB3ZSByZXByZXNl bnRlZAp0aGUgcGVyZm9ybWFuY2UgaW5mb3JtYXRpb24gZm9yIGVhY2ggcG9zc2libGUgQ1BVL21l bW9yeSBwYWlyIGluIHN5c2ZzIHdlCndvdWxkIGVuZCB1cCB3aXRoIDEsMDAwLDAwMCBhdHRyaWJ1 dGUgZ3JvdXBzLgoKVGhpcyBpcyBhIGxvdCB0byBwYXNzIGluIGEgc2V0IG9mIHBhY2tlZCBkYXRh IHRhYmxlcywgYnV0IEkgdGhpbmsgd2UnbGwKYnJlYWsgc3lzZnMgaWYgd2UgdHJ5IHRvIGNyZWF0 ZSBtaWxsaW9ucyBvZiBhdHRyaWJ1dGVzLCByZWdhcmRsZXNzIG9mIGhvdwp3ZSBuZXN0IHRoZW0g aW4gYSBkaXJlY3RvcnkgaGllcmFyY2h5LgoKQnkgb25seSByZXByZXNlbnRpbmcgcGVyZm9ybWFu Y2UgaW5mb3JtYXRpb24gZm9yIGxvY2FsIChpbml0aWF0b3IsdGFyZ2V0KQpwYWlyaW5ncywgd2Ug cmVkdWNlIHRoZSBudW1iZXIgb2Ygc3lzZnMgZW50cmllcyB0byBPKG51bV90YXJnZXRzKS4KClNp Z25lZC1vZmYtYnk6IFJvc3MgWndpc2xlciA8cm9zcy56d2lzbGVyQGxpbnV4LmludGVsLmNvbT4K LS0tCiBkcml2ZXJzL2FjcGkvaG1hdC9NYWtlZmlsZSAgICAgICAgICB8ICAgMiArLQogZHJpdmVy cy9hY3BpL2htYXQvY29yZS5jICAgICAgICAgICAgfCAyNjMgKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKystCiBkcml2ZXJzL2FjcGkvaG1hdC9obWF0LmggICAgICAgICAgICB8ICAx NyArKysKIGRyaXZlcnMvYWNwaS9obWF0L3BlcmZfYXR0cmlidXRlcy5jIHwgIDU2ICsrKysrKysr CiA0IGZpbGVzIGNoYW5nZWQsIDMzNiBpbnNlcnRpb25zKCspLCAyIGRlbGV0aW9ucygtKQogY3Jl YXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvYWNwaS9obWF0L3BlcmZfYXR0cmlidXRlcy5jCgpkaWZm IC0tZ2l0IGEvZHJpdmVycy9hY3BpL2htYXQvTWFrZWZpbGUgYi9kcml2ZXJzL2FjcGkvaG1hdC9N YWtlZmlsZQppbmRleCBlZGY0YmNiMWM5N2QuLmI1ZDFkODM2ODRkYSAxMDA2NDQKLS0tIGEvZHJp dmVycy9hY3BpL2htYXQvTWFrZWZpbGUKKysrIGIvZHJpdmVycy9hY3BpL2htYXQvTWFrZWZpbGUK QEAgLTEsMiArMSwyIEBACiBvYmotJChDT05GSUdfQUNQSV9ITUFUKSA6PSBobWF0Lm8KLWhtYXQt eSA6PSBjb3JlLm8gaW5pdGlhdG9yLm8gdGFyZ2V0Lm8KK2htYXQteSA6PSBjb3JlLm8gaW5pdGlh dG9yLm8gdGFyZ2V0Lm8gcGVyZl9hdHRyaWJ1dGVzLm8KZGlmZiAtLWdpdCBhL2RyaXZlcnMvYWNw aS9obWF0L2NvcmUuYyBiL2RyaXZlcnMvYWNwaS9obWF0L2NvcmUuYwppbmRleCA2MWI5MGRhZGY4 NGIuLjg5ZTg0NjU4ZmM3MyAxMDA2NDQKLS0tIGEvZHJpdmVycy9hY3BpL2htYXQvY29yZS5jCisr KyBiL2RyaXZlcnMvYWNwaS9obWF0L2NvcmUuYwpAQCAtMjMsMTEgKzIzLDIyNSBAQAogI2luY2x1 ZGUgPGxpbnV4L3NsYWIuaD4KICNpbmNsdWRlICJobWF0LmgiCiAKKyNkZWZpbmUgTk9fVkFMVUUJ LTEKKyNkZWZpbmUgTE9DQUxfSU5JVAkibG9jYWxfaW5pdCIKKwogc3RhdGljIExJU1RfSEVBRCh0 YXJnZXRfbGlzdCk7CiBzdGF0aWMgTElTVF9IRUFEKGluaXRpYXRvcl9saXN0KTsKK0xJU1RfSEVB RChsb2NhbGl0eV9saXN0KTsKIAogc3RhdGljIGJvb2wgYmFkX2htYXQ7CiAKKy8qIFBlcmZvcm1h bmNlIGF0dHJpYnV0ZXMgZm9yIGFuIGluaXRpYXRvci90YXJnZXQgcGFpci4gKi8KK3N0YXRpYyBp bnQgZ2V0X3BlcmZvcm1hbmNlX2RhdGEodTMyIGluaXRfcHhtLCB1MzIgdGd0X3B4bSwKKwkJc3Ry dWN0IGFjcGlfaG1hdF9sb2NhbGl0eSAqaG1hdF9sb2MpCit7CisJaW50IG51bV9pbml0ID0gaG1h dF9sb2MtPm51bWJlcl9vZl9pbml0aWF0b3JfUGRzOworCWludCBudW1fdGd0ID0gaG1hdF9sb2Mt Pm51bWJlcl9vZl90YXJnZXRfUGRzOworCWludCBpbml0X2lkeCA9IE5PX1ZBTFVFOworCWludCB0 Z3RfaWR4ID0gTk9fVkFMVUU7CisJdTMyICppbml0aWF0b3JzLCAqdGFyZ2V0czsKKwl1MTYgKmVu dHJpZXMsIHZhbDsKKwlpbnQgaTsKKworCS8qIHRoZSBpbml0aWF0b3IgYXJyYXkgaXMgYWZ0ZXIg dGhlIHN0cnVjdCBhY3BpX2htYXRfbG9jYWxpdHkgZmllbGRzICovCisJaW5pdGlhdG9ycyA9ICh1 MzIgKikoaG1hdF9sb2MgKyAxKTsKKwl0YXJnZXRzID0gJmluaXRpYXRvcnNbbnVtX2luaXRdOwor CWVudHJpZXMgPSAodTE2ICopJnRhcmdldHNbbnVtX3RndF07CisKKwlmb3IgKGkgPSAwOyBpIDwg bnVtX2luaXQ7IGkrKykgeworCQlpZiAoaW5pdGlhdG9yc1tpXSA9PSBpbml0X3B4bSkgeworCQkJ aW5pdF9pZHggPSBpOworCQkJYnJlYWs7CisJCX0KKwl9CisKKwlpZiAoaW5pdF9pZHggPT0gTk9f VkFMVUUpCisJCXJldHVybiBOT19WQUxVRTsKKworCWZvciAoaSA9IDA7IGkgPCBudW1fdGd0OyBp KyspIHsKKwkJaWYgKHRhcmdldHNbaV0gPT0gdGd0X3B4bSkgeworCQkJdGd0X2lkeCA9IGk7CisJ CQlicmVhazsKKwkJfQorCX0KKworCWlmICh0Z3RfaWR4ID09IE5PX1ZBTFVFKQorCQlyZXR1cm4g Tk9fVkFMVUU7CisKKwl2YWwgPSBlbnRyaWVzW2luaXRfaWR4Km51bV90Z3QgKyB0Z3RfaWR4XTsK KwlpZiAodmFsIDwgMTAgfHwgdmFsID09IDB4RkZGRikKKwkJcmV0dXJuIE5PX1ZBTFVFOworCisJ cmV0dXJuIChpbnQpKHZhbCAqIGhtYXRfbG9jLT5lbnRyeV9iYXNlX3VuaXQpIC8gMTA7Cit9CisK Ky8qCisgKiAnZGlyZWN0aW9uJyBpcyBlaXRoZXIgUkVBRCBvciBXUklURQorICogTGF0ZW5jeSBp cyByZXBvcnRlZCBpbiBuYW5vc2Vjb25kcyBhbmQgYmFuZHdpZHRoIGlzIHJlcG9ydGVkIGluIE1C L3MuCisgKi8KK3N0YXRpYyBpbnQgaG1hdF9nZXRfYXR0cmlidXRlKGludCBpbml0X3B4bSwgaW50 IHRndF9weG0sIGludCBkaXJlY3Rpb24sCisJCWVudW0gaG1hdF9hdHRyX3R5cGUgdHlwZSkKK3sK KwlzdHJ1Y3QgbWVtb3J5X2xvY2FsaXR5ICpsb2M7CisJaW50IHZhbHVlOworCisJbGlzdF9mb3Jf ZWFjaF9lbnRyeShsb2MsICZsb2NhbGl0eV9saXN0LCBsaXN0KSB7CisJCXN0cnVjdCBhY3BpX2ht YXRfbG9jYWxpdHkgKmhtYXRfbG9jID0gbG9jLT5obWF0X2xvYzsKKworCQlpZiAoZGlyZWN0aW9u ID09IFJFQUQgJiYgdHlwZSA9PSBMQVRFTkNZICYmCisJCSAgICAoaG1hdF9sb2MtPmRhdGFfdHlw ZSA9PSBBQ1BJX0hNQVRfQUNDRVNTX0xBVEVOQ1kgfHwKKwkJICAgICBobWF0X2xvYy0+ZGF0YV90 eXBlID09IEFDUElfSE1BVF9SRUFEX0xBVEVOQ1kpKSB7CisJCQl2YWx1ZSA9IGdldF9wZXJmb3Jt YW5jZV9kYXRhKGluaXRfcHhtLCB0Z3RfcHhtLAorCQkJCQlobWF0X2xvYyk7CisJCQlpZiAodmFs dWUgIT0gTk9fVkFMVUUpCisJCQkJcmV0dXJuIHZhbHVlOworCQl9CisKKwkJaWYgKGRpcmVjdGlv biA9PSBXUklURSAmJiB0eXBlID09IExBVEVOQ1kgJiYKKwkJICAgIChobWF0X2xvYy0+ZGF0YV90 eXBlID09IEFDUElfSE1BVF9BQ0NFU1NfTEFURU5DWSB8fAorCQkgICAgIGhtYXRfbG9jLT5kYXRh X3R5cGUgPT0gQUNQSV9ITUFUX1dSSVRFX0xBVEVOQ1kpKSB7CisJCQl2YWx1ZSA9IGdldF9wZXJm b3JtYW5jZV9kYXRhKGluaXRfcHhtLCB0Z3RfcHhtLAorCQkJCQlobWF0X2xvYyk7CisJCQlpZiAo dmFsdWUgIT0gTk9fVkFMVUUpCisJCQkJcmV0dXJuIHZhbHVlOworCQl9CisKKwkJaWYgKGRpcmVj dGlvbiA9PSBSRUFEICYmIHR5cGUgPT0gQkFORFdJRFRIICYmCisJCSAgICAoaG1hdF9sb2MtPmRh dGFfdHlwZSA9PSBBQ1BJX0hNQVRfQUNDRVNTX0JBTkRXSURUSCB8fAorCQkgICAgIGhtYXRfbG9j LT5kYXRhX3R5cGUgPT0gQUNQSV9ITUFUX1JFQURfQkFORFdJRFRIKSkgeworCQkJdmFsdWUgPSBn ZXRfcGVyZm9ybWFuY2VfZGF0YShpbml0X3B4bSwgdGd0X3B4bSwKKwkJCQkJaG1hdF9sb2MpOwor CQkJaWYgKHZhbHVlICE9IE5PX1ZBTFVFKQorCQkJCXJldHVybiB2YWx1ZTsKKwkJfQorCisJCWlm IChkaXJlY3Rpb24gPT0gV1JJVEUgJiYgdHlwZSA9PSBCQU5EV0lEVEggJiYKKwkJICAgIChobWF0 X2xvYy0+ZGF0YV90eXBlID09IEFDUElfSE1BVF9BQ0NFU1NfQkFORFdJRFRIIHx8CisJCSAgICAg aG1hdF9sb2MtPmRhdGFfdHlwZSA9PSBBQ1BJX0hNQVRfV1JJVEVfQkFORFdJRFRIKSkgeworCQkJ dmFsdWUgPSBnZXRfcGVyZm9ybWFuY2VfZGF0YShpbml0X3B4bSwgdGd0X3B4bSwKKwkJCQkJaG1h dF9sb2MpOworCQkJaWYgKHZhbHVlICE9IE5PX1ZBTFVFKQorCQkJCXJldHVybiB2YWx1ZTsKKwkJ fQorCX0KKworCXJldHVybiBOT19WQUxVRTsKK30KKworLyoKKyAqICdkaXJlY3Rpb24nIGlzIGVp dGhlciBSRUFEIG9yIFdSSVRFCisgKiBMYXRlbmN5IGlzIHJlcG9ydGVkIGluIG5hbm9zZWNvbmRz IGFuZCBiYW5kd2lkdGggaXMgcmVwb3J0ZWQgaW4gTUIvcy4KKyAqLworaW50IGhtYXRfbG9jYWxf YXR0cmlidXRlKHN0cnVjdCBkZXZpY2UgKnRndF9kZXYsIGludCBkaXJlY3Rpb24sCisJCWVudW0g aG1hdF9hdHRyX3R5cGUgdHlwZSkKK3sKKwlzdHJ1Y3QgbWVtb3J5X3RhcmdldCAqdGd0ID0gdG9f bWVtb3J5X3RhcmdldCh0Z3RfZGV2KTsKKwlpbnQgdGd0X3B4bSA9IHRndC0+bWEtPnByb3hpbWl0 eV9kb21haW47CisJaW50IGluaXRfcHhtOworCisJaWYgKCF0Z3QtPmxvY2FsX2luaXQpCisJCXJl dHVybiBOT19WQUxVRTsKKworCWluaXRfcHhtID0gdGd0LT5sb2NhbF9pbml0LT5weG07CisJcmV0 dXJuIGhtYXRfZ2V0X2F0dHJpYnV0ZShpbml0X3B4bSwgdGd0X3B4bSwgZGlyZWN0aW9uLCB0eXBl KTsKK30KKworc3RhdGljIGJvb2wgaXNfbG9jYWxfaW5pdChpbnQgaW5pdF9weG0sIGludCB0Z3Rf cHhtLCBpbnQgcmVhZF9sYXQsCisJCWludCB3cml0ZV9sYXQsIGludCByZWFkX2J3LCBpbnQgd3Jp dGVfYncpCit7CisJaWYgKHJlYWRfbGF0ICE9IGhtYXRfZ2V0X2F0dHJpYnV0ZShpbml0X3B4bSwg dGd0X3B4bSwgUkVBRCwgTEFURU5DWSkpCisJCXJldHVybiBmYWxzZTsKKworCWlmICh3cml0ZV9s YXQgIT0gaG1hdF9nZXRfYXR0cmlidXRlKGluaXRfcHhtLCB0Z3RfcHhtLCBXUklURSwgTEFURU5D WSkpCisJCXJldHVybiBmYWxzZTsKKworCWlmIChyZWFkX2J3ICE9IGhtYXRfZ2V0X2F0dHJpYnV0 ZShpbml0X3B4bSwgdGd0X3B4bSwgUkVBRCwgQkFORFdJRFRIKSkKKwkJcmV0dXJuIGZhbHNlOwor CisJaWYgKHdyaXRlX2J3ICE9IGhtYXRfZ2V0X2F0dHJpYnV0ZShpbml0X3B4bSwgdGd0X3B4bSwg V1JJVEUsIEJBTkRXSURUSCkpCisJCXJldHVybiBmYWxzZTsKKworCXJldHVybiB0cnVlOworfQor CitzdGF0aWMgY29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCBwZXJmb3JtYW5jZV9hdHRyaWJ1 dGVfZ3JvdXAgPSB7CisJLmF0dHJzID0gcGVyZm9ybWFuY2VfYXR0cmlidXRlcywKKwkubmFtZSA9 IExPQ0FMX0lOSVQsCit9OworCitzdGF0aWMgdm9pZCByZW1vdmVfcGVyZm9ybWFuY2VfYXR0cmli dXRlcyhzdHJ1Y3QgbWVtb3J5X3RhcmdldCAqdGd0KQoreworCWlmICghdGd0LT5sb2NhbF9pbml0 KQorCQlyZXR1cm47CisKKwkvKgorCSAqIEZJWE1FOiBOZWVkIHRvIGVuaGFuY2UgdGhlIGNvcmUg c3lzZnMgY29kZSB0byByZW1vdmUgYWxsIHRoZSBsaW5rcworCSAqIGluIGJvdGggdGhlIGF0dHJp YnV0ZSBncm91cCBhbmQgaW4gdGhlIGRldmljZSBpdHNlbGYgd2hlbiB0aG9zZSBhcmUKKwkgKiBy ZW1vdmVkLgorCSAqLworCXN5c2ZzX3JlbW92ZV9ncm91cCgmdGd0LT5kZXYua29iaiwgJnBlcmZv cm1hbmNlX2F0dHJpYnV0ZV9ncm91cCk7Cit9CisKK3N0YXRpYyBpbnQgYWRkX3BlcmZvcm1hbmNl X2F0dHJpYnV0ZXMoc3RydWN0IG1lbW9yeV90YXJnZXQgKnRndCkKK3sKKwlpbnQgcmVhZF9sYXQs IHdyaXRlX2xhdCwgcmVhZF9idywgd3JpdGVfYnc7CisJaW50IHRndF9weG0gPSB0Z3QtPm1hLT5w cm94aW1pdHlfZG9tYWluOworCXN0cnVjdCBrb2JqZWN0ICppbml0X2tvYmosICp0Z3Rfa29iajsK KwlzdHJ1Y3QgZGV2aWNlICppbml0X2RldiwgKnRndF9kZXY7CisJc3RydWN0IG1lbW9yeV9pbml0 aWF0b3IgKmluaXQ7CisJaW50IHJldDsKKworCWlmICghdGd0LT5sb2NhbF9pbml0KQorCQlyZXR1 cm4gMDsKKworCXRndF9kZXYgPSAmdGd0LT5kZXY7CisJdGd0X2tvYmogPSAmdGd0X2Rldi0+a29i ajsKKworCS8qIENyZWF0ZSBlbnRyaWVzIGZvciBpbml0aWF0b3IvdGFyZ2V0IHBhaXIgaW4gdGhl IHRhcmdldC4gICovCisJcmV0ID0gc3lzZnNfY3JlYXRlX2dyb3VwKHRndF9rb2JqLCAmcGVyZm9y bWFuY2VfYXR0cmlidXRlX2dyb3VwKTsKKwlpZiAocmV0IDwgMCkKKwkJcmV0dXJuIHJldDsKKwor CS8qCisJICogSXRlcmF0ZSB0aHJvdWdoIGluaXRpYXRvcnMgYW5kIGZpbmQgYWxsIHRoZSBvbmVz IHRoYXQgaGF2ZSB0aGUgc2FtZQorCSAqIHBlcmZvcm1hbmNlIGFzIHRoZSBsb2NhbCBpbml0aWF0 b3IuCisJICovCisJcmVhZF9sYXQgPSBobWF0X2xvY2FsX2F0dHJpYnV0ZSh0Z3RfZGV2LCBSRUFE LCBMQVRFTkNZKTsKKwl3cml0ZV9sYXQgPSBobWF0X2xvY2FsX2F0dHJpYnV0ZSh0Z3RfZGV2LCBX UklURSwgTEFURU5DWSk7CisJcmVhZF9idyA9IGhtYXRfbG9jYWxfYXR0cmlidXRlKHRndF9kZXYs IFJFQUQsIEJBTkRXSURUSCk7CisJd3JpdGVfYncgPSBobWF0X2xvY2FsX2F0dHJpYnV0ZSh0Z3Rf ZGV2LCBXUklURSwgQkFORFdJRFRIKTsKKworCWxpc3RfZm9yX2VhY2hfZW50cnkoaW5pdCwgJmlu aXRpYXRvcl9saXN0LCBsaXN0KSB7CisJCWluaXRfZGV2ID0gJmluaXQtPmRldjsKKwkJaW5pdF9r b2JqID0gJmluaXRfZGV2LT5rb2JqOworCisJCWlmIChpbml0ID09IHRndC0+bG9jYWxfaW5pdCB8 fAorCQkJaXNfbG9jYWxfaW5pdChpbml0LT5weG0sIHRndF9weG0sIHJlYWRfbGF0LAorCQkJCXdy aXRlX2xhdCwgcmVhZF9idywgd3JpdGVfYncpKSB7CisJCQlyZXQgPSBzeXNmc19hZGRfbGlua190 b19ncm91cCh0Z3Rfa29iaiwgTE9DQUxfSU5JVCwKKwkJCQkJaW5pdF9rb2JqLCBkZXZfbmFtZShp bml0X2RldikpOworCQkJaWYgKHJldCA8IDApCisJCQkJZ290byBlcnI7CisKKwkJCS8qCisJCQkg KiBDcmVhdGUgYSBsaW5rIGluIHRoZSBsb2NhbCBpbml0aWF0b3IgdG8gdGhpcworCQkJICogdGFy Z2V0LgorCQkJICovCisJCQlyZXQgPSBzeXNmc19jcmVhdGVfbGluayhpbml0X2tvYmosIHRndF9r b2JqLAorCQkJCQlrb2JqZWN0X25hbWUodGd0X2tvYmopKTsKKwkJCWlmIChyZXQgPCAwKQorCQkJ CWdvdG8gZXJyOworCQl9CisKKwl9CisJdGd0LT5oYXNfcGVyZl9hdHRyaWJ1dGVzID0gdHJ1ZTsK KwlyZXR1cm4gMDsKK2VycjoKKwlyZW1vdmVfcGVyZm9ybWFuY2VfYXR0cmlidXRlcyh0Z3QpOwor CXJldHVybiByZXQ7Cit9CisKIHN0YXRpYyBpbnQgbGlua19ub2RlX2Zvcl9rb2JqKHVuc2lnbmVk IGludCBub2RlLCBzdHJ1Y3Qga29iamVjdCAqa29iaikKIHsKIAlpZiAobm9kZV9kZXZpY2VzW25v ZGVdKQpAQCAtMTMyLDYgKzM0Niw5IEBAIHN0YXRpYyB2b2lkIHJlbGVhc2VfbWVtb3J5X3Rhcmdl dChzdHJ1Y3QgZGV2aWNlICpkZXYpCiAKIHN0YXRpYyB2b2lkIF9faW5pdCByZW1vdmVfbWVtb3J5 X3RhcmdldChzdHJ1Y3QgbWVtb3J5X3RhcmdldCAqdGd0KQogeworCWlmICh0Z3QtPmhhc19wZXJm X2F0dHJpYnV0ZXMpCisJCXJlbW92ZV9wZXJmb3JtYW5jZV9hdHRyaWJ1dGVzKHRndCk7CisKIAlp ZiAodGd0LT5pc19yZWdpc3RlcmVkKSB7CiAJCXJlbW92ZV9ub2RlX2Zvcl9rb2JqKHB4bV90b19u b2RlKHRndC0+bWEtPnByb3hpbWl0eV9kb21haW4pLAogCQkJCSZ0Z3QtPmRldi5rb2JqKTsKQEAg LTI3Niw2ICs0OTMsMzggQEAgaG1hdF9wYXJzZV9hZGRyZXNzX3JhbmdlKHN0cnVjdCBhY3BpX3N1 YnRhYmxlX2hlYWRlciAqaGVhZGVyLAogCXJldHVybiAtRUlOVkFMOwogfQogCitzdGF0aWMgaW50 IF9faW5pdCBobWF0X3BhcnNlX2xvY2FsaXR5KHN0cnVjdCBhY3BpX3N1YnRhYmxlX2hlYWRlciAq aGVhZGVyLAorCQljb25zdCB1bnNpZ25lZCBsb25nIGVuZCkKK3sKKwlzdHJ1Y3QgYWNwaV9obWF0 X2xvY2FsaXR5ICpobWF0X2xvYzsKKwlzdHJ1Y3QgbWVtb3J5X2xvY2FsaXR5ICpsb2M7CisKKwlp ZiAoYmFkX2htYXQpCisJCXJldHVybiAwOworCisJaG1hdF9sb2MgPSAoc3RydWN0IGFjcGlfaG1h dF9sb2NhbGl0eSAqKWhlYWRlcjsKKwlpZiAoIWhtYXRfbG9jKSB7CisJCXByX2VycigiSE1BVDog TlVMTCB0YWJsZSBlbnRyeVxuIik7CisJCWJhZF9obWF0ID0gdHJ1ZTsKKwkJcmV0dXJuIC1FSU5W QUw7CisJfQorCisJLyogV2UgZG9uJ3QgcmVwb3J0IGNhY2hlZCBwZXJmb3JtYW5jZSBpbmZvcm1h dGlvbiBpbiBzeXNmcy4gKi8KKwlpZiAoaG1hdF9sb2MtPmZsYWdzID09IEFDUElfSE1BVF9NRU1P UlkgfHwKKwkJCWhtYXRfbG9jLT5mbGFncyA9PSBBQ1BJX0hNQVRfTEFTVF9MRVZFTF9DQUNIRSkg eworCQlsb2MgPSBremFsbG9jKHNpemVvZigqbG9jKSwgR0ZQX0tFUk5FTCk7CisJCWlmICghbG9j KSB7CisJCQliYWRfaG1hdCA9IHRydWU7CisJCQlyZXR1cm4gLUVOT01FTTsKKwkJfQorCisJCWxv Yy0+aG1hdF9sb2MgPSBobWF0X2xvYzsKKwkJbGlzdF9hZGRfdGFpbCgmbG9jLT5saXN0LCAmbG9j YWxpdHlfbGlzdCk7CisJfQorCisJcmV0dXJuIDA7Cit9CisKIHN0YXRpYyBpbnQgX19pbml0IGht YXRfcGFyc2VfY2FjaGUoc3RydWN0IGFjcGlfc3VidGFibGVfaGVhZGVyICpoZWFkZXIsCiAJCWNv bnN0IHVuc2lnbmVkIGxvbmcgZW5kKQogewpAQCAtNDMxLDYgKzY4MCw3IEBAIHNyYXRfcGFyc2Vf bWVtb3J5X2FmZmluaXR5KHN0cnVjdCBhY3BpX3N1YnRhYmxlX2hlYWRlciAqaGVhZGVyLAogc3Rh dGljIHZvaWQgaG1hdF9jbGVhbnVwKHZvaWQpCiB7CiAJc3RydWN0IG1lbW9yeV9pbml0aWF0b3Ig KmluaXQsICppbml0X2l0ZXI7CisJc3RydWN0IG1lbW9yeV9sb2NhbGl0eSAqbG9jLCAqbG9jX2l0 ZXI7CiAJc3RydWN0IG1lbW9yeV90YXJnZXQgKnRndCwgKnRndF9pdGVyOwogCiAJbGlzdF9mb3Jf ZWFjaF9lbnRyeV9zYWZlKHRndCwgdGd0X2l0ZXIsICZ0YXJnZXRfbGlzdCwgbGlzdCkKQEAgLTQz OCw2ICs2ODgsMTEgQEAgc3RhdGljIHZvaWQgaG1hdF9jbGVhbnVwKHZvaWQpCiAKIAlsaXN0X2Zv cl9lYWNoX2VudHJ5X3NhZmUoaW5pdCwgaW5pdF9pdGVyLCAmaW5pdGlhdG9yX2xpc3QsIGxpc3Qp CiAJCXJlbW92ZV9tZW1vcnlfaW5pdGlhdG9yKGluaXQpOworCisJbGlzdF9mb3JfZWFjaF9lbnRy eV9zYWZlKGxvYywgbG9jX2l0ZXIsICZsb2NhbGl0eV9saXN0LCBsaXN0KSB7CisJCWxpc3RfZGVs KCZsb2MtPmxpc3QpOworCQlrZnJlZShsb2MpOworCX0KIH0KIAogc3RhdGljIGludCBfX2luaXQg aG1hdF9pbml0KHZvaWQpCkBAIC00ODgsMTMgKzc0MywxNSBAQCBzdGF0aWMgaW50IF9faW5pdCBo bWF0X2luaXQodm9pZCkKIAl9CiAKIAlpZiAoIWFjcGlfdGFibGVfcGFyc2UoQUNQSV9TSUdfSE1B VCwgaG1hdF9ub29wX3BhcnNlKSkgewotCQlzdHJ1Y3QgYWNwaV9zdWJ0YWJsZV9wcm9jIGhtYXRf cHJvY1syXTsKKwkJc3RydWN0IGFjcGlfc3VidGFibGVfcHJvYyBobWF0X3Byb2NbM107CiAKIAkJ bWVtc2V0KGhtYXRfcHJvYywgMCwgc2l6ZW9mKGhtYXRfcHJvYykpOwogCQlobWF0X3Byb2NbMF0u aWQgPSBBQ1BJX0hNQVRfVFlQRV9BRERSRVNTX1JBTkdFOwogCQlobWF0X3Byb2NbMF0uaGFuZGxl ciA9IGhtYXRfcGFyc2VfYWRkcmVzc19yYW5nZTsKIAkJaG1hdF9wcm9jWzFdLmlkID0gQUNQSV9I TUFUX1RZUEVfQ0FDSEU7CiAJCWhtYXRfcHJvY1sxXS5oYW5kbGVyID0gaG1hdF9wYXJzZV9jYWNo ZTsKKwkJaG1hdF9wcm9jWzJdLmlkID0gQUNQSV9ITUFUX1RZUEVfTE9DQUxJVFk7CisJCWhtYXRf cHJvY1syXS5oYW5kbGVyID0gaG1hdF9wYXJzZV9sb2NhbGl0eTsKIAogCQlhY3BpX3RhYmxlX3Bh cnNlX2VudHJpZXNfYXJyYXkoQUNQSV9TSUdfSE1BVCwKIAkJCQkJc2l6ZW9mKHN0cnVjdCBhY3Bp X3RhYmxlX2htYXQpLApAQCAtNTE2LDYgKzc3MywxMCBAQCBzdGF0aWMgaW50IF9faW5pdCBobWF0 X2luaXQodm9pZCkKIAkJcmV0ID0gcmVnaXN0ZXJfbWVtb3J5X3RhcmdldCh0Z3QpOwogCQlpZiAo cmV0KQogCQkJZ290byBlcnI7CisKKwkJcmV0ID0gYWRkX3BlcmZvcm1hbmNlX2F0dHJpYnV0ZXMo dGd0KTsKKwkJaWYgKHJldCkKKwkJCWdvdG8gZXJyOwogCX0KIAogCXJldHVybiAwOwpkaWZmIC0t Z2l0IGEvZHJpdmVycy9hY3BpL2htYXQvaG1hdC5oIGIvZHJpdmVycy9hY3BpL2htYXQvaG1hdC5o CmluZGV4IDEwOGFhZDFmOGFkNy4uODkyMDBmNWM0YjM4IDEwMDY0NAotLS0gYS9kcml2ZXJzL2Fj cGkvaG1hdC9obWF0LmgKKysrIGIvZHJpdmVycy9hY3BpL2htYXQvaG1hdC5oCkBAIC0xNiw2ICsx NiwxMSBAQAogI2lmbmRlZiBfQUNQSV9ITUFUX0hfCiAjZGVmaW5lIF9BQ1BJX0hNQVRfSF8KIAor ZW51bSBobWF0X2F0dHJfdHlwZSB7CisJTEFURU5DWSwKKwlCQU5EV0lEVEgsCit9OworCiBzdHJ1 Y3QgbWVtb3J5X2luaXRpYXRvciB7CiAJc3RydWN0IGxpc3RfaGVhZCBsaXN0OwogCXN0cnVjdCBk ZXZpY2UgZGV2OwpAQCAtMzksOSArNDQsMjEgQEAgc3RydWN0IG1lbW9yeV90YXJnZXQgewogCiAJ Ym9vbCBpc19jYWNoZWQ7CiAJYm9vbCBpc19yZWdpc3RlcmVkOworCWJvb2wgaGFzX3BlcmZfYXR0 cmlidXRlczsKIH07CiAjZGVmaW5lIHRvX21lbW9yeV90YXJnZXQoZCkgY29udGFpbmVyX29mKChk KSwgc3RydWN0IG1lbW9yeV90YXJnZXQsIGRldikKIAorc3RydWN0IG1lbW9yeV9sb2NhbGl0eSB7 CisJc3RydWN0IGxpc3RfaGVhZCBsaXN0OworCXN0cnVjdCBhY3BpX2htYXRfbG9jYWxpdHkgKmht YXRfbG9jOworfTsKKwogZXh0ZXJuIGNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKm1lbW9y eV9pbml0aWF0b3JfYXR0cmlidXRlX2dyb3Vwc1tdOwogZXh0ZXJuIGNvbnN0IHN0cnVjdCBhdHRy aWJ1dGVfZ3JvdXAgKm1lbW9yeV90YXJnZXRfYXR0cmlidXRlX2dyb3Vwc1tdOworZXh0ZXJuIHN0 cnVjdCBhdHRyaWJ1dGUgKnBlcmZvcm1hbmNlX2F0dHJpYnV0ZXNbXTsKKworZXh0ZXJuIHN0cnVj dCBsaXN0X2hlYWQgbG9jYWxpdHlfbGlzdDsKKworaW50IGhtYXRfbG9jYWxfYXR0cmlidXRlKHN0 cnVjdCBkZXZpY2UgKnRndF9kZXYsIGludCBkaXJlY3Rpb24sCisJCWVudW0gaG1hdF9hdHRyX3R5 cGUgdHlwZSk7CiAjZW5kaWYgLyogX0FDUElfSE1BVF9IXyAqLwpkaWZmIC0tZ2l0IGEvZHJpdmVy cy9hY3BpL2htYXQvcGVyZl9hdHRyaWJ1dGVzLmMgYi9kcml2ZXJzL2FjcGkvaG1hdC9wZXJmX2F0 dHJpYnV0ZXMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLjYwZjEw N2I1ODgyMgotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvYWNwaS9obWF0L3BlcmZfYXR0cmli dXRlcy5jCkBAIC0wLDAgKzEsNTYgQEAKKy8qCisgKiBIZXRlcm9nZW5lb3VzIE1lbW9yeSBBdHRy aWJ1dGVzIFRhYmxlIChITUFUKSBzeXNmcyBwZXJmb3JtYW5jZSBhdHRyaWJ1dGVzCisgKgorICog Q29weXJpZ2h0IChjKSAyMDE3LCBJbnRlbCBDb3Jwb3JhdGlvbi4KKyAqCisgKiBUaGlzIHByb2dy YW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlm eSBpdAorICogdW5kZXIgdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHRoZSBHTlUgR2VuZXJh bCBQdWJsaWMgTGljZW5zZSwKKyAqIHZlcnNpb24gMiwgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVl IFNvZnR3YXJlIEZvdW5kYXRpb24uCisgKgorICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVk IGluIHRoZSBob3BlIGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAorICogQU5ZIFdBUlJB TlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZ IG9yCisgKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VIEdl bmVyYWwgUHVibGljIExpY2Vuc2UgZm9yCisgKiBtb3JlIGRldGFpbHMuCisgKi8KKworI2luY2x1 ZGUgPGxpbnV4L2FjcGkuaD4KKyNpbmNsdWRlIDxsaW51eC9kZXZpY2UuaD4KKyNpbmNsdWRlIDxs aW51eC9zeXNmcy5oPgorI2luY2x1ZGUgImhtYXQuaCIKKworc3RhdGljIHNzaXplX3QgcmVhZF9s YXRfbnNlY19zaG93KHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJCXN0cnVjdCBkZXZpY2VfYXR0cmli dXRlICphdHRyLCBjaGFyICpidWYpCit7CisJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIGht YXRfbG9jYWxfYXR0cmlidXRlKGRldiwgUkVBRCwgTEFURU5DWSkpOworfQorc3RhdGljIERFVklD RV9BVFRSX1JPKHJlYWRfbGF0X25zZWMpOworCitzdGF0aWMgc3NpemVfdCB3cml0ZV9sYXRfbnNl Y19zaG93KHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICph dHRyLCBjaGFyICpidWYpCit7CisJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIGhtYXRfbG9j YWxfYXR0cmlidXRlKGRldiwgV1JJVEUsIExBVEVOQ1kpKTsKK30KK3N0YXRpYyBERVZJQ0VfQVRU Ul9STyh3cml0ZV9sYXRfbnNlYyk7CisKK3N0YXRpYyBzc2l6ZV90IHJlYWRfYndfTUJwc19zaG93 KHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBj aGFyICpidWYpCit7CisJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIGhtYXRfbG9jYWxfYXR0 cmlidXRlKGRldiwgUkVBRCwgQkFORFdJRFRIKSk7Cit9CitzdGF0aWMgREVWSUNFX0FUVFJfUk8o cmVhZF9id19NQnBzKTsKKworc3RhdGljIHNzaXplX3Qgd3JpdGVfYndfTUJwc19zaG93KHN0cnVj dCBkZXZpY2UgKmRldiwKKwkJCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpi dWYpCit7CisJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsCisJCQlobWF0X2xvY2FsX2F0dHJp YnV0ZShkZXYsIFdSSVRFLCBCQU5EV0lEVEgpKTsKK30KK3N0YXRpYyBERVZJQ0VfQVRUUl9STyh3 cml0ZV9id19NQnBzKTsKKworc3RydWN0IGF0dHJpYnV0ZSAqcGVyZm9ybWFuY2VfYXR0cmlidXRl c1tdID0geworCSZkZXZfYXR0cl9yZWFkX2xhdF9uc2VjLmF0dHIsCisJJmRldl9hdHRyX3dyaXRl X2xhdF9uc2VjLmF0dHIsCisJJmRldl9hdHRyX3JlYWRfYndfTUJwcy5hdHRyLAorCSZkZXZfYXR0 cl93cml0ZV9id19NQnBzLmF0dHIsCisJTlVMTAorfTsKLS0gCjIuMTQuMwoKX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KTGludXgtbnZkaW1tIG1haWxpbmcg bGlzdApMaW51eC1udmRpbW1AbGlzdHMuMDEub3JnCmh0dHBzOi8vbGlzdHMuMDEub3JnL21haWxt YW4vbGlzdGluZm8vbGludXgtbnZkaW1tCg== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752152AbdLNCKx (ORCPT ); Wed, 13 Dec 2017 21:10:53 -0500 Received: from mga01.intel.com ([192.55.52.88]:64712 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751984AbdLNCKe (ORCPT ); Wed, 13 Dec 2017 21:10:34 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,399,1508828400"; d="scan'208";a="2623246" From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "Anaczkowski, Lukasz" , "Box, David E" , "Kogut, Jaroslaw" , "Koss, Marcin" , "Koziej, Artur" , "Lahtinen, Joonas" , "Moore, Robert" , "Nachimuthu, Murugasamy" , "Odzioba, Lukasz" , "Rafael J. Wysocki" , "Rafael J. Wysocki" , "Schmauss, Erik" , "Verma, Vishal L" , "Zheng, Lv" , Andrew Morton , Balbir Singh , Brice Goglin , Dan Williams , Dave Hansen , Jerome Glisse , John Hubbard , Len Brown , Tim Chen , devel@acpica.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org Subject: [PATCH v3 3/3] hmat: add performance attributes Date: Wed, 13 Dec 2017 19:10:19 -0700 Message-Id: <20171214021019.13579-4-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20171214021019.13579-1-ross.zwisler@linux.intel.com> References: <20171214021019.13579-1-ross.zwisler@linux.intel.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 Add performance information found in the HMAT to the sysfs representation. This information lives as an attribute group named "local_init" in the memory target: # tree mem_tgt2 mem_tgt2 ├── firmware_id ├── is_cached ├── local_init │   ├── mem_init0 -> ../../mem_init0 │   ├── mem_init1 -> ../../mem_init1 │   ├── read_bw_MBps │   ├── read_lat_nsec │   ├── write_bw_MBps │   └── write_lat_nsec ├── node2 -> ../../node/node2 ├── power │   ├── async │   ... ├── subsystem -> ../../../../bus/hmat └── uevent This attribute group surfaces latency and bandwidth performance for a memory target and its local initiators. For example: # grep . mem_tgt2/local_init/* 2>/dev/null mem_tgt2/local_init/read_bw_MBps:30720 mem_tgt2/local_init/read_lat_nsec:100 mem_tgt2/local_init/write_bw_MBps:30720 mem_tgt2/local_init/write_lat_nsec:100 The initiators also have a symlink to their local targets: # ls -l mem_init0/mem_tgt2 lrwxrwxrwx. 1 root root 0 Dec 13 16:45 mem_init0/mem_tgt2 -> ../mem_tgt2 We create performance attribute groups only for local (initiator,target) pairings, where the first local initiator for a given target is defined by the "Processor Proximity Domain" field in the HMAT's Memory Subsystem Address Range Structure table. After we have one local initiator we scan the performance data to link to any other "local" initiators with the same local performance to a given memory target. A given target only has one set of local performance values, so each target will have at most one "local_init" attribute group, though that group can contain links to multiple initiators that all have local performance. A given memory initiator may have multiple local memory targets, so multiple "mem_tgtX" links may exist for a given initiator. If a given memory target is cached we give performance numbers only for the media itself, and rely on the "is_cached" attribute to represent the fact that there is a caching layer. The fact that we only expose a subset of the performance information presented in the HMAT via sysfs as a compromise, driven by fact that those usages will be the highest performing and because to represent all possible paths could cause an unmanageable explosion of sysfs entries. If we dump everything from the HMAT into sysfs we end up with O(num_targets * num_initiators * num_caching_levels) attributes. Each of these attributes only takes up 2 bytes in a System Locality Latency and Bandwidth Information Structure, but if we have to create a directory entry for each it becomes much more expensive. For example, very large systems today can have on the order of thousands of NUMA nodes. Say we have a system which used to have 1,000 NUMA nodes that each had both a CPU and local memory. The HMAT allows us to separate the CPUs and memory into separate NUMA nodes, so we can end up with 1,000 CPU initiator NUMA nodes and 1,000 memory target NUMA nodes. If we represented the performance information for each possible CPU/memory pair in sysfs we would end up with 1,000,000 attribute groups. This is a lot to pass in a set of packed data tables, but I think we'll break sysfs if we try to create millions of attributes, regardless of how we nest them in a directory hierarchy. By only representing performance information for local (initiator,target) pairings, we reduce the number of sysfs entries to O(num_targets). Signed-off-by: Ross Zwisler --- drivers/acpi/hmat/Makefile | 2 +- drivers/acpi/hmat/core.c | 263 +++++++++++++++++++++++++++++++++++- drivers/acpi/hmat/hmat.h | 17 +++ drivers/acpi/hmat/perf_attributes.c | 56 ++++++++ 4 files changed, 336 insertions(+), 2 deletions(-) create mode 100644 drivers/acpi/hmat/perf_attributes.c diff --git a/drivers/acpi/hmat/Makefile b/drivers/acpi/hmat/Makefile index edf4bcb1c97d..b5d1d83684da 100644 --- a/drivers/acpi/hmat/Makefile +++ b/drivers/acpi/hmat/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_ACPI_HMAT) := hmat.o -hmat-y := core.o initiator.o target.o +hmat-y := core.o initiator.o target.o perf_attributes.o diff --git a/drivers/acpi/hmat/core.c b/drivers/acpi/hmat/core.c index 61b90dadf84b..89e84658fc73 100644 --- a/drivers/acpi/hmat/core.c +++ b/drivers/acpi/hmat/core.c @@ -23,11 +23,225 @@ #include #include "hmat.h" +#define NO_VALUE -1 +#define LOCAL_INIT "local_init" + static LIST_HEAD(target_list); static LIST_HEAD(initiator_list); +LIST_HEAD(locality_list); static bool bad_hmat; +/* Performance attributes for an initiator/target pair. */ +static int get_performance_data(u32 init_pxm, u32 tgt_pxm, + struct acpi_hmat_locality *hmat_loc) +{ + int num_init = hmat_loc->number_of_initiator_Pds; + int num_tgt = hmat_loc->number_of_target_Pds; + int init_idx = NO_VALUE; + int tgt_idx = NO_VALUE; + u32 *initiators, *targets; + u16 *entries, val; + int i; + + /* the initiator array is after the struct acpi_hmat_locality fields */ + initiators = (u32 *)(hmat_loc + 1); + targets = &initiators[num_init]; + entries = (u16 *)&targets[num_tgt]; + + for (i = 0; i < num_init; i++) { + if (initiators[i] == init_pxm) { + init_idx = i; + break; + } + } + + if (init_idx == NO_VALUE) + return NO_VALUE; + + for (i = 0; i < num_tgt; i++) { + if (targets[i] == tgt_pxm) { + tgt_idx = i; + break; + } + } + + if (tgt_idx == NO_VALUE) + return NO_VALUE; + + val = entries[init_idx*num_tgt + tgt_idx]; + if (val < 10 || val == 0xFFFF) + return NO_VALUE; + + return (int)(val * hmat_loc->entry_base_unit) / 10; +} + +/* + * 'direction' is either READ or WRITE + * Latency is reported in nanoseconds and bandwidth is reported in MB/s. + */ +static int hmat_get_attribute(int init_pxm, int tgt_pxm, int direction, + enum hmat_attr_type type) +{ + struct memory_locality *loc; + int value; + + list_for_each_entry(loc, &locality_list, list) { + struct acpi_hmat_locality *hmat_loc = loc->hmat_loc; + + if (direction == READ && type == LATENCY && + (hmat_loc->data_type == ACPI_HMAT_ACCESS_LATENCY || + hmat_loc->data_type == ACPI_HMAT_READ_LATENCY)) { + value = get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value != NO_VALUE) + return value; + } + + if (direction == WRITE && type == LATENCY && + (hmat_loc->data_type == ACPI_HMAT_ACCESS_LATENCY || + hmat_loc->data_type == ACPI_HMAT_WRITE_LATENCY)) { + value = get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value != NO_VALUE) + return value; + } + + if (direction == READ && type == BANDWIDTH && + (hmat_loc->data_type == ACPI_HMAT_ACCESS_BANDWIDTH || + hmat_loc->data_type == ACPI_HMAT_READ_BANDWIDTH)) { + value = get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value != NO_VALUE) + return value; + } + + if (direction == WRITE && type == BANDWIDTH && + (hmat_loc->data_type == ACPI_HMAT_ACCESS_BANDWIDTH || + hmat_loc->data_type == ACPI_HMAT_WRITE_BANDWIDTH)) { + value = get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value != NO_VALUE) + return value; + } + } + + return NO_VALUE; +} + +/* + * 'direction' is either READ or WRITE + * Latency is reported in nanoseconds and bandwidth is reported in MB/s. + */ +int hmat_local_attribute(struct device *tgt_dev, int direction, + enum hmat_attr_type type) +{ + struct memory_target *tgt = to_memory_target(tgt_dev); + int tgt_pxm = tgt->ma->proximity_domain; + int init_pxm; + + if (!tgt->local_init) + return NO_VALUE; + + init_pxm = tgt->local_init->pxm; + return hmat_get_attribute(init_pxm, tgt_pxm, direction, type); +} + +static bool is_local_init(int init_pxm, int tgt_pxm, int read_lat, + int write_lat, int read_bw, int write_bw) +{ + if (read_lat != hmat_get_attribute(init_pxm, tgt_pxm, READ, LATENCY)) + return false; + + if (write_lat != hmat_get_attribute(init_pxm, tgt_pxm, WRITE, LATENCY)) + return false; + + if (read_bw != hmat_get_attribute(init_pxm, tgt_pxm, READ, BANDWIDTH)) + return false; + + if (write_bw != hmat_get_attribute(init_pxm, tgt_pxm, WRITE, BANDWIDTH)) + return false; + + return true; +} + +static const struct attribute_group performance_attribute_group = { + .attrs = performance_attributes, + .name = LOCAL_INIT, +}; + +static void remove_performance_attributes(struct memory_target *tgt) +{ + if (!tgt->local_init) + return; + + /* + * FIXME: Need to enhance the core sysfs code to remove all the links + * in both the attribute group and in the device itself when those are + * removed. + */ + sysfs_remove_group(&tgt->dev.kobj, &performance_attribute_group); +} + +static int add_performance_attributes(struct memory_target *tgt) +{ + int read_lat, write_lat, read_bw, write_bw; + int tgt_pxm = tgt->ma->proximity_domain; + struct kobject *init_kobj, *tgt_kobj; + struct device *init_dev, *tgt_dev; + struct memory_initiator *init; + int ret; + + if (!tgt->local_init) + return 0; + + tgt_dev = &tgt->dev; + tgt_kobj = &tgt_dev->kobj; + + /* Create entries for initiator/target pair in the target. */ + ret = sysfs_create_group(tgt_kobj, &performance_attribute_group); + if (ret < 0) + return ret; + + /* + * Iterate through initiators and find all the ones that have the same + * performance as the local initiator. + */ + read_lat = hmat_local_attribute(tgt_dev, READ, LATENCY); + write_lat = hmat_local_attribute(tgt_dev, WRITE, LATENCY); + read_bw = hmat_local_attribute(tgt_dev, READ, BANDWIDTH); + write_bw = hmat_local_attribute(tgt_dev, WRITE, BANDWIDTH); + + list_for_each_entry(init, &initiator_list, list) { + init_dev = &init->dev; + init_kobj = &init_dev->kobj; + + if (init == tgt->local_init || + is_local_init(init->pxm, tgt_pxm, read_lat, + write_lat, read_bw, write_bw)) { + ret = sysfs_add_link_to_group(tgt_kobj, LOCAL_INIT, + init_kobj, dev_name(init_dev)); + if (ret < 0) + goto err; + + /* + * Create a link in the local initiator to this + * target. + */ + ret = sysfs_create_link(init_kobj, tgt_kobj, + kobject_name(tgt_kobj)); + if (ret < 0) + goto err; + } + + } + tgt->has_perf_attributes = true; + return 0; +err: + remove_performance_attributes(tgt); + return ret; +} + static int link_node_for_kobj(unsigned int node, struct kobject *kobj) { if (node_devices[node]) @@ -132,6 +346,9 @@ static void release_memory_target(struct device *dev) static void __init remove_memory_target(struct memory_target *tgt) { + if (tgt->has_perf_attributes) + remove_performance_attributes(tgt); + if (tgt->is_registered) { remove_node_for_kobj(pxm_to_node(tgt->ma->proximity_domain), &tgt->dev.kobj); @@ -276,6 +493,38 @@ hmat_parse_address_range(struct acpi_subtable_header *header, return -EINVAL; } +static int __init hmat_parse_locality(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct acpi_hmat_locality *hmat_loc; + struct memory_locality *loc; + + if (bad_hmat) + return 0; + + hmat_loc = (struct acpi_hmat_locality *)header; + if (!hmat_loc) { + pr_err("HMAT: NULL table entry\n"); + bad_hmat = true; + return -EINVAL; + } + + /* We don't report cached performance information in sysfs. */ + if (hmat_loc->flags == ACPI_HMAT_MEMORY || + hmat_loc->flags == ACPI_HMAT_LAST_LEVEL_CACHE) { + loc = kzalloc(sizeof(*loc), GFP_KERNEL); + if (!loc) { + bad_hmat = true; + return -ENOMEM; + } + + loc->hmat_loc = hmat_loc; + list_add_tail(&loc->list, &locality_list); + } + + return 0; +} + static int __init hmat_parse_cache(struct acpi_subtable_header *header, const unsigned long end) { @@ -431,6 +680,7 @@ srat_parse_memory_affinity(struct acpi_subtable_header *header, static void hmat_cleanup(void) { struct memory_initiator *init, *init_iter; + struct memory_locality *loc, *loc_iter; struct memory_target *tgt, *tgt_iter; list_for_each_entry_safe(tgt, tgt_iter, &target_list, list) @@ -438,6 +688,11 @@ static void hmat_cleanup(void) list_for_each_entry_safe(init, init_iter, &initiator_list, list) remove_memory_initiator(init); + + list_for_each_entry_safe(loc, loc_iter, &locality_list, list) { + list_del(&loc->list); + kfree(loc); + } } static int __init hmat_init(void) @@ -488,13 +743,15 @@ static int __init hmat_init(void) } if (!acpi_table_parse(ACPI_SIG_HMAT, hmat_noop_parse)) { - struct acpi_subtable_proc hmat_proc[2]; + struct acpi_subtable_proc hmat_proc[3]; memset(hmat_proc, 0, sizeof(hmat_proc)); hmat_proc[0].id = ACPI_HMAT_TYPE_ADDRESS_RANGE; hmat_proc[0].handler = hmat_parse_address_range; hmat_proc[1].id = ACPI_HMAT_TYPE_CACHE; hmat_proc[1].handler = hmat_parse_cache; + hmat_proc[2].id = ACPI_HMAT_TYPE_LOCALITY; + hmat_proc[2].handler = hmat_parse_locality; acpi_table_parse_entries_array(ACPI_SIG_HMAT, sizeof(struct acpi_table_hmat), @@ -516,6 +773,10 @@ static int __init hmat_init(void) ret = register_memory_target(tgt); if (ret) goto err; + + ret = add_performance_attributes(tgt); + if (ret) + goto err; } return 0; diff --git a/drivers/acpi/hmat/hmat.h b/drivers/acpi/hmat/hmat.h index 108aad1f8ad7..89200f5c4b38 100644 --- a/drivers/acpi/hmat/hmat.h +++ b/drivers/acpi/hmat/hmat.h @@ -16,6 +16,11 @@ #ifndef _ACPI_HMAT_H_ #define _ACPI_HMAT_H_ +enum hmat_attr_type { + LATENCY, + BANDWIDTH, +}; + struct memory_initiator { struct list_head list; struct device dev; @@ -39,9 +44,21 @@ struct memory_target { bool is_cached; bool is_registered; + bool has_perf_attributes; }; #define to_memory_target(d) container_of((d), struct memory_target, dev) +struct memory_locality { + struct list_head list; + struct acpi_hmat_locality *hmat_loc; +}; + extern const struct attribute_group *memory_initiator_attribute_groups[]; extern const struct attribute_group *memory_target_attribute_groups[]; +extern struct attribute *performance_attributes[]; + +extern struct list_head locality_list; + +int hmat_local_attribute(struct device *tgt_dev, int direction, + enum hmat_attr_type type); #endif /* _ACPI_HMAT_H_ */ diff --git a/drivers/acpi/hmat/perf_attributes.c b/drivers/acpi/hmat/perf_attributes.c new file mode 100644 index 000000000000..60f107b58822 --- /dev/null +++ b/drivers/acpi/hmat/perf_attributes.c @@ -0,0 +1,56 @@ +/* + * Heterogeneous Memory Attributes Table (HMAT) sysfs performance attributes + * + * Copyright (c) 2017, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include "hmat.h" + +static ssize_t read_lat_nsec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", hmat_local_attribute(dev, READ, LATENCY)); +} +static DEVICE_ATTR_RO(read_lat_nsec); + +static ssize_t write_lat_nsec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", hmat_local_attribute(dev, WRITE, LATENCY)); +} +static DEVICE_ATTR_RO(write_lat_nsec); + +static ssize_t read_bw_MBps_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", hmat_local_attribute(dev, READ, BANDWIDTH)); +} +static DEVICE_ATTR_RO(read_bw_MBps); + +static ssize_t write_bw_MBps_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", + hmat_local_attribute(dev, WRITE, BANDWIDTH)); +} +static DEVICE_ATTR_RO(write_bw_MBps); + +struct attribute *performance_attributes[] = { + &dev_attr_read_lat_nsec.attr, + &dev_attr_write_lat_nsec.attr, + &dev_attr_read_bw_MBps.attr, + &dev_attr_write_bw_MBps.attr, + NULL +}; -- 2.14.3 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-f71.google.com (mail-pg0-f71.google.com [74.125.83.71]) by kanga.kvack.org (Postfix) with ESMTP id E64516B0260 for ; Wed, 13 Dec 2017 21:10:36 -0500 (EST) Received: by mail-pg0-f71.google.com with SMTP id g8so2828052pgs.14 for ; Wed, 13 Dec 2017 18:10:36 -0800 (PST) Received: from mga11.intel.com (mga11.intel.com. [192.55.52.93]) by mx.google.com with ESMTPS id e69si2358748pfc.337.2017.12.13.18.10.34 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 13 Dec 2017 18:10:34 -0800 (PST) From: Ross Zwisler Subject: [PATCH v3 3/3] hmat: add performance attributes Date: Wed, 13 Dec 2017 19:10:19 -0700 Message-Id: <20171214021019.13579-4-ross.zwisler@linux.intel.com> In-Reply-To: <20171214021019.13579-1-ross.zwisler@linux.intel.com> References: <20171214021019.13579-1-ross.zwisler@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: owner-linux-mm@kvack.org List-ID: To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "Anaczkowski, Lukasz" , "Box, David E" , "Kogut, Jaroslaw" , "Koss, Marcin" , "Koziej, Artur" , "Lahtinen, Joonas" , "Moore, Robert" , "Nachimuthu, Murugasamy" , "Odzioba, Lukasz" , "Rafael J. Wysocki" , "Rafael J. Wysocki" , "Schmauss, Erik" , "Verma, Vishal L" , "Zheng, Lv" , Andrew Morton , Balbir Singh , Brice Goglin , Dan Williams , Dave Hansen , Jerome Glisse , John Hubbard , Len Brown , Tim Chen , devel@acpica.org, linux-acpi@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org Add performance information found in the HMAT to the sysfs representation. This information lives as an attribute group named "local_init" in the memory target: # tree mem_tgt2 mem_tgt2 a??a??a?? firmware_id a??a??a?? is_cached a??a??a?? local_init a??A A a??a??a?? mem_init0 -> ../../mem_init0 a??A A a??a??a?? mem_init1 -> ../../mem_init1 a??A A a??a??a?? read_bw_MBps a??A A a??a??a?? read_lat_nsec a??A A a??a??a?? write_bw_MBps a??A A a??a??a?? write_lat_nsec a??a??a?? node2 -> ../../node/node2 a??a??a?? power a??A A a??a??a?? async a??A A ... a??a??a?? subsystem -> ../../../../bus/hmat a??a??a?? uevent This attribute group surfaces latency and bandwidth performance for a memory target and its local initiators. For example: # grep . mem_tgt2/local_init/* 2>/dev/null mem_tgt2/local_init/read_bw_MBps:30720 mem_tgt2/local_init/read_lat_nsec:100 mem_tgt2/local_init/write_bw_MBps:30720 mem_tgt2/local_init/write_lat_nsec:100 The initiators also have a symlink to their local targets: # ls -l mem_init0/mem_tgt2 lrwxrwxrwx. 1 root root 0 Dec 13 16:45 mem_init0/mem_tgt2 -> ../mem_tgt2 We create performance attribute groups only for local (initiator,target) pairings, where the first local initiator for a given target is defined by the "Processor Proximity Domain" field in the HMAT's Memory Subsystem Address Range Structure table. After we have one local initiator we scan the performance data to link to any other "local" initiators with the same local performance to a given memory target. A given target only has one set of local performance values, so each target will have at most one "local_init" attribute group, though that group can contain links to multiple initiators that all have local performance. A given memory initiator may have multiple local memory targets, so multiple "mem_tgtX" links may exist for a given initiator. If a given memory target is cached we give performance numbers only for the media itself, and rely on the "is_cached" attribute to represent the fact that there is a caching layer. The fact that we only expose a subset of the performance information presented in the HMAT via sysfs as a compromise, driven by fact that those usages will be the highest performing and because to represent all possible paths could cause an unmanageable explosion of sysfs entries. If we dump everything from the HMAT into sysfs we end up with O(num_targets * num_initiators * num_caching_levels) attributes. Each of these attributes only takes up 2 bytes in a System Locality Latency and Bandwidth Information Structure, but if we have to create a directory entry for each it becomes much more expensive. For example, very large systems today can have on the order of thousands of NUMA nodes. Say we have a system which used to have 1,000 NUMA nodes that each had both a CPU and local memory. The HMAT allows us to separate the CPUs and memory into separate NUMA nodes, so we can end up with 1,000 CPU initiator NUMA nodes and 1,000 memory target NUMA nodes. If we represented the performance information for each possible CPU/memory pair in sysfs we would end up with 1,000,000 attribute groups. This is a lot to pass in a set of packed data tables, but I think we'll break sysfs if we try to create millions of attributes, regardless of how we nest them in a directory hierarchy. By only representing performance information for local (initiator,target) pairings, we reduce the number of sysfs entries to O(num_targets). Signed-off-by: Ross Zwisler --- drivers/acpi/hmat/Makefile | 2 +- drivers/acpi/hmat/core.c | 263 +++++++++++++++++++++++++++++++++++- drivers/acpi/hmat/hmat.h | 17 +++ drivers/acpi/hmat/perf_attributes.c | 56 ++++++++ 4 files changed, 336 insertions(+), 2 deletions(-) create mode 100644 drivers/acpi/hmat/perf_attributes.c diff --git a/drivers/acpi/hmat/Makefile b/drivers/acpi/hmat/Makefile index edf4bcb1c97d..b5d1d83684da 100644 --- a/drivers/acpi/hmat/Makefile +++ b/drivers/acpi/hmat/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_ACPI_HMAT) := hmat.o -hmat-y := core.o initiator.o target.o +hmat-y := core.o initiator.o target.o perf_attributes.o diff --git a/drivers/acpi/hmat/core.c b/drivers/acpi/hmat/core.c index 61b90dadf84b..89e84658fc73 100644 --- a/drivers/acpi/hmat/core.c +++ b/drivers/acpi/hmat/core.c @@ -23,11 +23,225 @@ #include #include "hmat.h" +#define NO_VALUE -1 +#define LOCAL_INIT "local_init" + static LIST_HEAD(target_list); static LIST_HEAD(initiator_list); +LIST_HEAD(locality_list); static bool bad_hmat; +/* Performance attributes for an initiator/target pair. */ +static int get_performance_data(u32 init_pxm, u32 tgt_pxm, + struct acpi_hmat_locality *hmat_loc) +{ + int num_init = hmat_loc->number_of_initiator_Pds; + int num_tgt = hmat_loc->number_of_target_Pds; + int init_idx = NO_VALUE; + int tgt_idx = NO_VALUE; + u32 *initiators, *targets; + u16 *entries, val; + int i; + + /* the initiator array is after the struct acpi_hmat_locality fields */ + initiators = (u32 *)(hmat_loc + 1); + targets = &initiators[num_init]; + entries = (u16 *)&targets[num_tgt]; + + for (i = 0; i < num_init; i++) { + if (initiators[i] == init_pxm) { + init_idx = i; + break; + } + } + + if (init_idx == NO_VALUE) + return NO_VALUE; + + for (i = 0; i < num_tgt; i++) { + if (targets[i] == tgt_pxm) { + tgt_idx = i; + break; + } + } + + if (tgt_idx == NO_VALUE) + return NO_VALUE; + + val = entries[init_idx*num_tgt + tgt_idx]; + if (val < 10 || val == 0xFFFF) + return NO_VALUE; + + return (int)(val * hmat_loc->entry_base_unit) / 10; +} + +/* + * 'direction' is either READ or WRITE + * Latency is reported in nanoseconds and bandwidth is reported in MB/s. + */ +static int hmat_get_attribute(int init_pxm, int tgt_pxm, int direction, + enum hmat_attr_type type) +{ + struct memory_locality *loc; + int value; + + list_for_each_entry(loc, &locality_list, list) { + struct acpi_hmat_locality *hmat_loc = loc->hmat_loc; + + if (direction == READ && type == LATENCY && + (hmat_loc->data_type == ACPI_HMAT_ACCESS_LATENCY || + hmat_loc->data_type == ACPI_HMAT_READ_LATENCY)) { + value = get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value != NO_VALUE) + return value; + } + + if (direction == WRITE && type == LATENCY && + (hmat_loc->data_type == ACPI_HMAT_ACCESS_LATENCY || + hmat_loc->data_type == ACPI_HMAT_WRITE_LATENCY)) { + value = get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value != NO_VALUE) + return value; + } + + if (direction == READ && type == BANDWIDTH && + (hmat_loc->data_type == ACPI_HMAT_ACCESS_BANDWIDTH || + hmat_loc->data_type == ACPI_HMAT_READ_BANDWIDTH)) { + value = get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value != NO_VALUE) + return value; + } + + if (direction == WRITE && type == BANDWIDTH && + (hmat_loc->data_type == ACPI_HMAT_ACCESS_BANDWIDTH || + hmat_loc->data_type == ACPI_HMAT_WRITE_BANDWIDTH)) { + value = get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value != NO_VALUE) + return value; + } + } + + return NO_VALUE; +} + +/* + * 'direction' is either READ or WRITE + * Latency is reported in nanoseconds and bandwidth is reported in MB/s. + */ +int hmat_local_attribute(struct device *tgt_dev, int direction, + enum hmat_attr_type type) +{ + struct memory_target *tgt = to_memory_target(tgt_dev); + int tgt_pxm = tgt->ma->proximity_domain; + int init_pxm; + + if (!tgt->local_init) + return NO_VALUE; + + init_pxm = tgt->local_init->pxm; + return hmat_get_attribute(init_pxm, tgt_pxm, direction, type); +} + +static bool is_local_init(int init_pxm, int tgt_pxm, int read_lat, + int write_lat, int read_bw, int write_bw) +{ + if (read_lat != hmat_get_attribute(init_pxm, tgt_pxm, READ, LATENCY)) + return false; + + if (write_lat != hmat_get_attribute(init_pxm, tgt_pxm, WRITE, LATENCY)) + return false; + + if (read_bw != hmat_get_attribute(init_pxm, tgt_pxm, READ, BANDWIDTH)) + return false; + + if (write_bw != hmat_get_attribute(init_pxm, tgt_pxm, WRITE, BANDWIDTH)) + return false; + + return true; +} + +static const struct attribute_group performance_attribute_group = { + .attrs = performance_attributes, + .name = LOCAL_INIT, +}; + +static void remove_performance_attributes(struct memory_target *tgt) +{ + if (!tgt->local_init) + return; + + /* + * FIXME: Need to enhance the core sysfs code to remove all the links + * in both the attribute group and in the device itself when those are + * removed. + */ + sysfs_remove_group(&tgt->dev.kobj, &performance_attribute_group); +} + +static int add_performance_attributes(struct memory_target *tgt) +{ + int read_lat, write_lat, read_bw, write_bw; + int tgt_pxm = tgt->ma->proximity_domain; + struct kobject *init_kobj, *tgt_kobj; + struct device *init_dev, *tgt_dev; + struct memory_initiator *init; + int ret; + + if (!tgt->local_init) + return 0; + + tgt_dev = &tgt->dev; + tgt_kobj = &tgt_dev->kobj; + + /* Create entries for initiator/target pair in the target. */ + ret = sysfs_create_group(tgt_kobj, &performance_attribute_group); + if (ret < 0) + return ret; + + /* + * Iterate through initiators and find all the ones that have the same + * performance as the local initiator. + */ + read_lat = hmat_local_attribute(tgt_dev, READ, LATENCY); + write_lat = hmat_local_attribute(tgt_dev, WRITE, LATENCY); + read_bw = hmat_local_attribute(tgt_dev, READ, BANDWIDTH); + write_bw = hmat_local_attribute(tgt_dev, WRITE, BANDWIDTH); + + list_for_each_entry(init, &initiator_list, list) { + init_dev = &init->dev; + init_kobj = &init_dev->kobj; + + if (init == tgt->local_init || + is_local_init(init->pxm, tgt_pxm, read_lat, + write_lat, read_bw, write_bw)) { + ret = sysfs_add_link_to_group(tgt_kobj, LOCAL_INIT, + init_kobj, dev_name(init_dev)); + if (ret < 0) + goto err; + + /* + * Create a link in the local initiator to this + * target. + */ + ret = sysfs_create_link(init_kobj, tgt_kobj, + kobject_name(tgt_kobj)); + if (ret < 0) + goto err; + } + + } + tgt->has_perf_attributes = true; + return 0; +err: + remove_performance_attributes(tgt); + return ret; +} + static int link_node_for_kobj(unsigned int node, struct kobject *kobj) { if (node_devices[node]) @@ -132,6 +346,9 @@ static void release_memory_target(struct device *dev) static void __init remove_memory_target(struct memory_target *tgt) { + if (tgt->has_perf_attributes) + remove_performance_attributes(tgt); + if (tgt->is_registered) { remove_node_for_kobj(pxm_to_node(tgt->ma->proximity_domain), &tgt->dev.kobj); @@ -276,6 +493,38 @@ hmat_parse_address_range(struct acpi_subtable_header *header, return -EINVAL; } +static int __init hmat_parse_locality(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct acpi_hmat_locality *hmat_loc; + struct memory_locality *loc; + + if (bad_hmat) + return 0; + + hmat_loc = (struct acpi_hmat_locality *)header; + if (!hmat_loc) { + pr_err("HMAT: NULL table entry\n"); + bad_hmat = true; + return -EINVAL; + } + + /* We don't report cached performance information in sysfs. */ + if (hmat_loc->flags == ACPI_HMAT_MEMORY || + hmat_loc->flags == ACPI_HMAT_LAST_LEVEL_CACHE) { + loc = kzalloc(sizeof(*loc), GFP_KERNEL); + if (!loc) { + bad_hmat = true; + return -ENOMEM; + } + + loc->hmat_loc = hmat_loc; + list_add_tail(&loc->list, &locality_list); + } + + return 0; +} + static int __init hmat_parse_cache(struct acpi_subtable_header *header, const unsigned long end) { @@ -431,6 +680,7 @@ srat_parse_memory_affinity(struct acpi_subtable_header *header, static void hmat_cleanup(void) { struct memory_initiator *init, *init_iter; + struct memory_locality *loc, *loc_iter; struct memory_target *tgt, *tgt_iter; list_for_each_entry_safe(tgt, tgt_iter, &target_list, list) @@ -438,6 +688,11 @@ static void hmat_cleanup(void) list_for_each_entry_safe(init, init_iter, &initiator_list, list) remove_memory_initiator(init); + + list_for_each_entry_safe(loc, loc_iter, &locality_list, list) { + list_del(&loc->list); + kfree(loc); + } } static int __init hmat_init(void) @@ -488,13 +743,15 @@ static int __init hmat_init(void) } if (!acpi_table_parse(ACPI_SIG_HMAT, hmat_noop_parse)) { - struct acpi_subtable_proc hmat_proc[2]; + struct acpi_subtable_proc hmat_proc[3]; memset(hmat_proc, 0, sizeof(hmat_proc)); hmat_proc[0].id = ACPI_HMAT_TYPE_ADDRESS_RANGE; hmat_proc[0].handler = hmat_parse_address_range; hmat_proc[1].id = ACPI_HMAT_TYPE_CACHE; hmat_proc[1].handler = hmat_parse_cache; + hmat_proc[2].id = ACPI_HMAT_TYPE_LOCALITY; + hmat_proc[2].handler = hmat_parse_locality; acpi_table_parse_entries_array(ACPI_SIG_HMAT, sizeof(struct acpi_table_hmat), @@ -516,6 +773,10 @@ static int __init hmat_init(void) ret = register_memory_target(tgt); if (ret) goto err; + + ret = add_performance_attributes(tgt); + if (ret) + goto err; } return 0; diff --git a/drivers/acpi/hmat/hmat.h b/drivers/acpi/hmat/hmat.h index 108aad1f8ad7..89200f5c4b38 100644 --- a/drivers/acpi/hmat/hmat.h +++ b/drivers/acpi/hmat/hmat.h @@ -16,6 +16,11 @@ #ifndef _ACPI_HMAT_H_ #define _ACPI_HMAT_H_ +enum hmat_attr_type { + LATENCY, + BANDWIDTH, +}; + struct memory_initiator { struct list_head list; struct device dev; @@ -39,9 +44,21 @@ struct memory_target { bool is_cached; bool is_registered; + bool has_perf_attributes; }; #define to_memory_target(d) container_of((d), struct memory_target, dev) +struct memory_locality { + struct list_head list; + struct acpi_hmat_locality *hmat_loc; +}; + extern const struct attribute_group *memory_initiator_attribute_groups[]; extern const struct attribute_group *memory_target_attribute_groups[]; +extern struct attribute *performance_attributes[]; + +extern struct list_head locality_list; + +int hmat_local_attribute(struct device *tgt_dev, int direction, + enum hmat_attr_type type); #endif /* _ACPI_HMAT_H_ */ diff --git a/drivers/acpi/hmat/perf_attributes.c b/drivers/acpi/hmat/perf_attributes.c new file mode 100644 index 000000000000..60f107b58822 --- /dev/null +++ b/drivers/acpi/hmat/perf_attributes.c @@ -0,0 +1,56 @@ +/* + * Heterogeneous Memory Attributes Table (HMAT) sysfs performance attributes + * + * Copyright (c) 2017, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include "hmat.h" + +static ssize_t read_lat_nsec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", hmat_local_attribute(dev, READ, LATENCY)); +} +static DEVICE_ATTR_RO(read_lat_nsec); + +static ssize_t write_lat_nsec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", hmat_local_attribute(dev, WRITE, LATENCY)); +} +static DEVICE_ATTR_RO(write_lat_nsec); + +static ssize_t read_bw_MBps_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", hmat_local_attribute(dev, READ, BANDWIDTH)); +} +static DEVICE_ATTR_RO(read_bw_MBps); + +static ssize_t write_bw_MBps_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", + hmat_local_attribute(dev, WRITE, BANDWIDTH)); +} +static DEVICE_ATTR_RO(write_bw_MBps); + +struct attribute *performance_attributes[] = { + &dev_attr_read_lat_nsec.attr, + &dev_attr_write_lat_nsec.attr, + &dev_attr_read_bw_MBps.attr, + &dev_attr_write_bw_MBps.attr, + NULL +}; -- 2.14.3 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: multipart/mixed; boundary="===============5641856057549040242==" MIME-Version: 1.0 From: Ross Zwisler Subject: [Devel] [PATCH v3 3/3] hmat: add performance attributes Date: Wed, 13 Dec 2017 19:10:19 -0700 Message-ID: <20171214021019.13579-4-ross.zwisler@linux.intel.com> In-Reply-To: 20171214021019.13579-1-ross.zwisler@linux.intel.com List-ID: To: devel@acpica.org --===============5641856057549040242== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Add performance information found in the HMAT to the sysfs representation. This information lives as an attribute group named "local_init" in the memory target: # tree mem_tgt2 mem_tgt2 =E2=94=9C=E2=94=80=E2=94=80 firmware_id =E2=94=9C=E2=94=80=E2=94=80 is_cached =E2=94=9C=E2=94=80=E2=94=80 local_init =E2=94=82=C2=A0=C2=A0 =E2=94=9C=E2=94=80=E2=94=80 mem_init0 -> ../../mem_= init0 =E2=94=82=C2=A0=C2=A0 =E2=94=9C=E2=94=80=E2=94=80 mem_init1 -> ../../mem_= init1 =E2=94=82=C2=A0=C2=A0 =E2=94=9C=E2=94=80=E2=94=80 read_bw_MBps =E2=94=82=C2=A0=C2=A0 =E2=94=9C=E2=94=80=E2=94=80 read_lat_nsec =E2=94=82=C2=A0=C2=A0 =E2=94=9C=E2=94=80=E2=94=80 write_bw_MBps =E2=94=82=C2=A0=C2=A0 =E2=94=94=E2=94=80=E2=94=80 write_lat_nsec =E2=94=9C=E2=94=80=E2=94=80 node2 -> ../../node/node2 =E2=94=9C=E2=94=80=E2=94=80 power =E2=94=82=C2=A0=C2=A0 =E2=94=9C=E2=94=80=E2=94=80 async =E2=94=82=C2=A0=C2=A0 ... =E2=94=9C=E2=94=80=E2=94=80 subsystem -> ../../../../bus/hmat =E2=94=94=E2=94=80=E2=94=80 uevent This attribute group surfaces latency and bandwidth performance for a memory target and its local initiators. For example: # grep . mem_tgt2/local_init/* 2>/dev/null mem_tgt2/local_init/read_bw_MBps:30720 mem_tgt2/local_init/read_lat_nsec:100 mem_tgt2/local_init/write_bw_MBps:30720 mem_tgt2/local_init/write_lat_nsec:100 The initiators also have a symlink to their local targets: # ls -l mem_init0/mem_tgt2 lrwxrwxrwx. 1 root root 0 Dec 13 16:45 mem_init0/mem_tgt2 -> ../mem_tgt2 We create performance attribute groups only for local (initiator,target) pairings, where the first local initiator for a given target is defined by the "Processor Proximity Domain" field in the HMAT's Memory Subsystem Address Range Structure table. After we have one local initiator we scan the performance data to link to any other "local" initiators with the same local performance to a given memory target. A given target only has one set of local performance values, so each target will have at most one "local_init" attribute group, though that group can contain links to multiple initiators that all have local performance. A given memory initiator may have multiple local memory targets, so multiple "mem_tgtX" links may exist for a given initiator. If a given memory target is cached we give performance numbers only for the media itself, and rely on the "is_cached" attribute to represent the fact that there is a caching layer. The fact that we only expose a subset of the performance information presented in the HMAT via sysfs as a compromise, driven by fact that those usages will be the highest performing and because to represent all possible paths could cause an unmanageable explosion of sysfs entries. If we dump everything from the HMAT into sysfs we end up with O(num_targets * num_initiators * num_caching_levels) attributes. Each of these attributes only takes up 2 bytes in a System Locality Latency and Bandwidth Information Structure, but if we have to create a directory entry for each it becomes much more expensive. For example, very large systems today can have on the order of thousands of NUMA nodes. Say we have a system which used to have 1,000 NUMA nodes that each had both a CPU and local memory. The HMAT allows us to separate the CPUs and memory into separate NUMA nodes, so we can end up with 1,000 CPU initiator NUMA nodes and 1,000 memory target NUMA nodes. If we represented the performance information for each possible CPU/memory pair in sysfs we would end up with 1,000,000 attribute groups. This is a lot to pass in a set of packed data tables, but I think we'll break sysfs if we try to create millions of attributes, regardless of how we nest them in a directory hierarchy. By only representing performance information for local (initiator,target) pairings, we reduce the number of sysfs entries to O(num_targets). Signed-off-by: Ross Zwisler --- drivers/acpi/hmat/Makefile | 2 +- drivers/acpi/hmat/core.c | 263 ++++++++++++++++++++++++++++++++= +++- drivers/acpi/hmat/hmat.h | 17 +++ drivers/acpi/hmat/perf_attributes.c | 56 ++++++++ 4 files changed, 336 insertions(+), 2 deletions(-) create mode 100644 drivers/acpi/hmat/perf_attributes.c diff --git a/drivers/acpi/hmat/Makefile b/drivers/acpi/hmat/Makefile index edf4bcb1c97d..b5d1d83684da 100644 --- a/drivers/acpi/hmat/Makefile +++ b/drivers/acpi/hmat/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_ACPI_HMAT) :=3D hmat.o -hmat-y :=3D core.o initiator.o target.o +hmat-y :=3D core.o initiator.o target.o perf_attributes.o diff --git a/drivers/acpi/hmat/core.c b/drivers/acpi/hmat/core.c index 61b90dadf84b..89e84658fc73 100644 --- a/drivers/acpi/hmat/core.c +++ b/drivers/acpi/hmat/core.c @@ -23,11 +23,225 @@ #include #include "hmat.h" = +#define NO_VALUE -1 +#define LOCAL_INIT "local_init" + static LIST_HEAD(target_list); static LIST_HEAD(initiator_list); +LIST_HEAD(locality_list); = static bool bad_hmat; = +/* Performance attributes for an initiator/target pair. */ +static int get_performance_data(u32 init_pxm, u32 tgt_pxm, + struct acpi_hmat_locality *hmat_loc) +{ + int num_init =3D hmat_loc->number_of_initiator_Pds; + int num_tgt =3D hmat_loc->number_of_target_Pds; + int init_idx =3D NO_VALUE; + int tgt_idx =3D NO_VALUE; + u32 *initiators, *targets; + u16 *entries, val; + int i; + + /* the initiator array is after the struct acpi_hmat_locality fields */ + initiators =3D (u32 *)(hmat_loc + 1); + targets =3D &initiators[num_init]; + entries =3D (u16 *)&targets[num_tgt]; + + for (i =3D 0; i < num_init; i++) { + if (initiators[i] =3D=3D init_pxm) { + init_idx =3D i; + break; + } + } + + if (init_idx =3D=3D NO_VALUE) + return NO_VALUE; + + for (i =3D 0; i < num_tgt; i++) { + if (targets[i] =3D=3D tgt_pxm) { + tgt_idx =3D i; + break; + } + } + + if (tgt_idx =3D=3D NO_VALUE) + return NO_VALUE; + + val =3D entries[init_idx*num_tgt + tgt_idx]; + if (val < 10 || val =3D=3D 0xFFFF) + return NO_VALUE; + + return (int)(val * hmat_loc->entry_base_unit) / 10; +} + +/* + * 'direction' is either READ or WRITE + * Latency is reported in nanoseconds and bandwidth is reported in MB/s. + */ +static int hmat_get_attribute(int init_pxm, int tgt_pxm, int direction, + enum hmat_attr_type type) +{ + struct memory_locality *loc; + int value; + + list_for_each_entry(loc, &locality_list, list) { + struct acpi_hmat_locality *hmat_loc =3D loc->hmat_loc; + + if (direction =3D=3D READ && type =3D=3D LATENCY && + (hmat_loc->data_type =3D=3D ACPI_HMAT_ACCESS_LATENCY || + hmat_loc->data_type =3D=3D ACPI_HMAT_READ_LATENCY)) { + value =3D get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value !=3D NO_VALUE) + return value; + } + + if (direction =3D=3D WRITE && type =3D=3D LATENCY && + (hmat_loc->data_type =3D=3D ACPI_HMAT_ACCESS_LATENCY || + hmat_loc->data_type =3D=3D ACPI_HMAT_WRITE_LATENCY)) { + value =3D get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value !=3D NO_VALUE) + return value; + } + + if (direction =3D=3D READ && type =3D=3D BANDWIDTH && + (hmat_loc->data_type =3D=3D ACPI_HMAT_ACCESS_BANDWIDTH || + hmat_loc->data_type =3D=3D ACPI_HMAT_READ_BANDWIDTH)) { + value =3D get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value !=3D NO_VALUE) + return value; + } + + if (direction =3D=3D WRITE && type =3D=3D BANDWIDTH && + (hmat_loc->data_type =3D=3D ACPI_HMAT_ACCESS_BANDWIDTH || + hmat_loc->data_type =3D=3D ACPI_HMAT_WRITE_BANDWIDTH)) { + value =3D get_performance_data(init_pxm, tgt_pxm, + hmat_loc); + if (value !=3D NO_VALUE) + return value; + } + } + + return NO_VALUE; +} + +/* + * 'direction' is either READ or WRITE + * Latency is reported in nanoseconds and bandwidth is reported in MB/s. + */ +int hmat_local_attribute(struct device *tgt_dev, int direction, + enum hmat_attr_type type) +{ + struct memory_target *tgt =3D to_memory_target(tgt_dev); + int tgt_pxm =3D tgt->ma->proximity_domain; + int init_pxm; + + if (!tgt->local_init) + return NO_VALUE; + + init_pxm =3D tgt->local_init->pxm; + return hmat_get_attribute(init_pxm, tgt_pxm, direction, type); +} + +static bool is_local_init(int init_pxm, int tgt_pxm, int read_lat, + int write_lat, int read_bw, int write_bw) +{ + if (read_lat !=3D hmat_get_attribute(init_pxm, tgt_pxm, READ, LATENCY)) + return false; + + if (write_lat !=3D hmat_get_attribute(init_pxm, tgt_pxm, WRITE, LATENCY)) + return false; + + if (read_bw !=3D hmat_get_attribute(init_pxm, tgt_pxm, READ, BANDWIDTH)) + return false; + + if (write_bw !=3D hmat_get_attribute(init_pxm, tgt_pxm, WRITE, BANDWIDTH)) + return false; + + return true; +} + +static const struct attribute_group performance_attribute_group =3D { + .attrs =3D performance_attributes, + .name =3D LOCAL_INIT, +}; + +static void remove_performance_attributes(struct memory_target *tgt) +{ + if (!tgt->local_init) + return; + + /* + * FIXME: Need to enhance the core sysfs code to remove all the links + * in both the attribute group and in the device itself when those are + * removed. + */ + sysfs_remove_group(&tgt->dev.kobj, &performance_attribute_group); +} + +static int add_performance_attributes(struct memory_target *tgt) +{ + int read_lat, write_lat, read_bw, write_bw; + int tgt_pxm =3D tgt->ma->proximity_domain; + struct kobject *init_kobj, *tgt_kobj; + struct device *init_dev, *tgt_dev; + struct memory_initiator *init; + int ret; + + if (!tgt->local_init) + return 0; + + tgt_dev =3D &tgt->dev; + tgt_kobj =3D &tgt_dev->kobj; + + /* Create entries for initiator/target pair in the target. */ + ret =3D sysfs_create_group(tgt_kobj, &performance_attribute_group); + if (ret < 0) + return ret; + + /* + * Iterate through initiators and find all the ones that have the same + * performance as the local initiator. + */ + read_lat =3D hmat_local_attribute(tgt_dev, READ, LATENCY); + write_lat =3D hmat_local_attribute(tgt_dev, WRITE, LATENCY); + read_bw =3D hmat_local_attribute(tgt_dev, READ, BANDWIDTH); + write_bw =3D hmat_local_attribute(tgt_dev, WRITE, BANDWIDTH); + + list_for_each_entry(init, &initiator_list, list) { + init_dev =3D &init->dev; + init_kobj =3D &init_dev->kobj; + + if (init =3D=3D tgt->local_init || + is_local_init(init->pxm, tgt_pxm, read_lat, + write_lat, read_bw, write_bw)) { + ret =3D sysfs_add_link_to_group(tgt_kobj, LOCAL_INIT, + init_kobj, dev_name(init_dev)); + if (ret < 0) + goto err; + + /* + * Create a link in the local initiator to this + * target. + */ + ret =3D sysfs_create_link(init_kobj, tgt_kobj, + kobject_name(tgt_kobj)); + if (ret < 0) + goto err; + } + + } + tgt->has_perf_attributes =3D true; + return 0; +err: + remove_performance_attributes(tgt); + return ret; +} + static int link_node_for_kobj(unsigned int node, struct kobject *kobj) { if (node_devices[node]) @@ -132,6 +346,9 @@ static void release_memory_target(struct device *dev) = static void __init remove_memory_target(struct memory_target *tgt) { + if (tgt->has_perf_attributes) + remove_performance_attributes(tgt); + if (tgt->is_registered) { remove_node_for_kobj(pxm_to_node(tgt->ma->proximity_domain), &tgt->dev.kobj); @@ -276,6 +493,38 @@ hmat_parse_address_range(struct acpi_subtable_header *= header, return -EINVAL; } = +static int __init hmat_parse_locality(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct acpi_hmat_locality *hmat_loc; + struct memory_locality *loc; + + if (bad_hmat) + return 0; + + hmat_loc =3D (struct acpi_hmat_locality *)header; + if (!hmat_loc) { + pr_err("HMAT: NULL table entry\n"); + bad_hmat =3D true; + return -EINVAL; + } + + /* We don't report cached performance information in sysfs. */ + if (hmat_loc->flags =3D=3D ACPI_HMAT_MEMORY || + hmat_loc->flags =3D=3D ACPI_HMAT_LAST_LEVEL_CACHE) { + loc =3D kzalloc(sizeof(*loc), GFP_KERNEL); + if (!loc) { + bad_hmat =3D true; + return -ENOMEM; + } + + loc->hmat_loc =3D hmat_loc; + list_add_tail(&loc->list, &locality_list); + } + + return 0; +} + static int __init hmat_parse_cache(struct acpi_subtable_header *header, const unsigned long end) { @@ -431,6 +680,7 @@ srat_parse_memory_affinity(struct acpi_subtable_header = *header, static void hmat_cleanup(void) { struct memory_initiator *init, *init_iter; + struct memory_locality *loc, *loc_iter; struct memory_target *tgt, *tgt_iter; = list_for_each_entry_safe(tgt, tgt_iter, &target_list, list) @@ -438,6 +688,11 @@ static void hmat_cleanup(void) = list_for_each_entry_safe(init, init_iter, &initiator_list, list) remove_memory_initiator(init); + + list_for_each_entry_safe(loc, loc_iter, &locality_list, list) { + list_del(&loc->list); + kfree(loc); + } } = static int __init hmat_init(void) @@ -488,13 +743,15 @@ static int __init hmat_init(void) } = if (!acpi_table_parse(ACPI_SIG_HMAT, hmat_noop_parse)) { - struct acpi_subtable_proc hmat_proc[2]; + struct acpi_subtable_proc hmat_proc[3]; = memset(hmat_proc, 0, sizeof(hmat_proc)); hmat_proc[0].id =3D ACPI_HMAT_TYPE_ADDRESS_RANGE; hmat_proc[0].handler =3D hmat_parse_address_range; hmat_proc[1].id =3D ACPI_HMAT_TYPE_CACHE; hmat_proc[1].handler =3D hmat_parse_cache; + hmat_proc[2].id =3D ACPI_HMAT_TYPE_LOCALITY; + hmat_proc[2].handler =3D hmat_parse_locality; = acpi_table_parse_entries_array(ACPI_SIG_HMAT, sizeof(struct acpi_table_hmat), @@ -516,6 +773,10 @@ static int __init hmat_init(void) ret =3D register_memory_target(tgt); if (ret) goto err; + + ret =3D add_performance_attributes(tgt); + if (ret) + goto err; } = return 0; diff --git a/drivers/acpi/hmat/hmat.h b/drivers/acpi/hmat/hmat.h index 108aad1f8ad7..89200f5c4b38 100644 --- a/drivers/acpi/hmat/hmat.h +++ b/drivers/acpi/hmat/hmat.h @@ -16,6 +16,11 @@ #ifndef _ACPI_HMAT_H_ #define _ACPI_HMAT_H_ = +enum hmat_attr_type { + LATENCY, + BANDWIDTH, +}; + struct memory_initiator { struct list_head list; struct device dev; @@ -39,9 +44,21 @@ struct memory_target { = bool is_cached; bool is_registered; + bool has_perf_attributes; }; #define to_memory_target(d) container_of((d), struct memory_target, dev) = +struct memory_locality { + struct list_head list; + struct acpi_hmat_locality *hmat_loc; +}; + extern const struct attribute_group *memory_initiator_attribute_groups[]; extern const struct attribute_group *memory_target_attribute_groups[]; +extern struct attribute *performance_attributes[]; + +extern struct list_head locality_list; + +int hmat_local_attribute(struct device *tgt_dev, int direction, + enum hmat_attr_type type); #endif /* _ACPI_HMAT_H_ */ diff --git a/drivers/acpi/hmat/perf_attributes.c b/drivers/acpi/hmat/perf_a= ttributes.c new file mode 100644 index 000000000000..60f107b58822 --- /dev/null +++ b/drivers/acpi/hmat/perf_attributes.c @@ -0,0 +1,56 @@ +/* + * Heterogeneous Memory Attributes Table (HMAT) sysfs performance attribut= es + * + * Copyright (c) 2017, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License f= or + * more details. + */ + +#include +#include +#include +#include "hmat.h" + +static ssize_t read_lat_nsec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", hmat_local_attribute(dev, READ, LATENCY)); +} +static DEVICE_ATTR_RO(read_lat_nsec); + +static ssize_t write_lat_nsec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", hmat_local_attribute(dev, WRITE, LATENCY)); +} +static DEVICE_ATTR_RO(write_lat_nsec); + +static ssize_t read_bw_MBps_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", hmat_local_attribute(dev, READ, BANDWIDTH)); +} +static DEVICE_ATTR_RO(read_bw_MBps); + +static ssize_t write_bw_MBps_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", + hmat_local_attribute(dev, WRITE, BANDWIDTH)); +} +static DEVICE_ATTR_RO(write_bw_MBps); + +struct attribute *performance_attributes[] =3D { + &dev_attr_read_lat_nsec.attr, + &dev_attr_write_lat_nsec.attr, + &dev_attr_read_bw_MBps.attr, + &dev_attr_write_bw_MBps.attr, + NULL +}; -- = 2.14.3 --===============5641856057549040242==--