Skip to contentSkip to conversation

mm/highmem: Preemptible variant of kmap_atomic & friends

PATCH Applied Thomas Gleixner 8 participants 71 messages Nov 3, 2020 – Nov 12, 2020

Subsystems (35)

v3 of 4 Applied Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover mm/highmem: Preemptible variant of kmap_atomic & friends

Rm9sbG93aW5nIHVwIHRvIHRoZSBkaXNjdXNzaW9uIGluOgoKICBodHRwczovL2xvcmUua2VybmVs Lm9yZy9yLzIwMjAwOTE0MjA0MjA5LjI1NjI2NjA5M0BsaW51dHJvbml4LmRlCgphbmQgdGhlIHNl Y29uZCB2ZXJzaW9uIG9mIHRoaXM6CgogIGh0dHBzOi8vbG9yZS5rZXJuZWwub3JnL3IvMjAyMDEw MjkyMjE4MDYuMTg5NTIzMzc1QGxpbnV0cm9uaXguZGUKCnRoaXMgc2VyaWVzIHByb3ZpZGVzIGEg cHJlZW1wdGlibGUgdmFyaWFudCBvZiBrbWFwX2F0b21pYyAmIHJlbGF0ZWQKaW50ZXJmYWNlcy4K ClRoaXMgaXMgYWNoaWV2ZWQgYnk6CgogLSBSZW1vdmluZyB0aGUgUlQgZGVwZW5kZW5jeSBmcm9t IG1pZ3JhdGVfZGlzYWJsZS9lbmFibGUoKQoKIC0gQ29uc29saWRhdGluZyBhbGwga21hcCBhdG9t aWMgaW1wbGVtZW50YXRpb25zIGluIGdlbmVyaWMgY29kZSBpbmNsdWRpbmcKICAgYSB1c2VmdWwg dmVyc2lvbiBvZiB0aGUgQ09ORklHX0RFQlVHX0hJR0hNRU0gd2hpY2ggcHJvdmlkZXMgZ3VhcmQg cGFnZXMKICAgYmV0d2VlbiB0aGUgaW5kaXZpZHVhbCBtYXBzIGluc3RlYWQgb2YganVzdCBpbmNy ZWFzaW5nIHRoZSBtYXAgc2l6ZS4KCiAtIFN3aXRjaGluZyBmcm9tIHBlciBDUFUgc3RvcmFnZSBv ZiB0aGUga21hcCBpbmRleCB0byBhIHBlciB0YXNrIHN0b3JhZ2UKCiAtIEFkZGluZyBhIHB0ZXZh bCBhcnJheSB0byB0aGUgcGVyIHRhc2sgc3RvcmFnZSB3aGljaCBjb250YWlucyB0aGUgcHRldmFs cwogICBvZiB0aGUgY3VycmVudGx5IGFjdGl2ZSB0ZW1wb3Jhcnkga21hcHMKCiAtIEFkZGluZyBj b250ZXh0IHN3aXRjaCBjb2RlIHdoaWNoIGNoZWNrcyB3aGV0aGVyIHRoZSBvdXRnb2luZyBvciB0 aGUKICAgaW5jb21pbmcgdGFzayBoYXMgYWN0aXZlIHRlbXBvcmFyeSBrbWFwcy4gSWYgc28sIHRo ZSBvdXRnb2luZyB0YXNrJ3MKICAga21hcHMgYXJlIHJlbW92ZWQgYW5kIHRoZSBpbmNvbWluZyB0 YXNrJ3Mga21hcHMgYXJlIHJlc3RvcmVkLgoKIC0gQWRkaW5nIG5ldyBpbnRlcmZhY2VzIGtbdW5d bWFwX2xvY2FsKigpIHdoaWNoIGFyZSBub3QgZGlzYWJsaW5nCiAgIHByZWVtcHRpb24gYW5kIGNh biBiZSBjYWxsZWQgZnJvbSBhbnkgY29udGV4dCAoZXhjZXB0IE5NSSkuCgogICBDb250cmFyeSB0 byBrbWFwKCkgd2hpY2ggcHJvdmlkZXMgcHJlZW1wdGlibGUgYW5kICJwZXJzaXN0YW50IiBtYXBw aW5ncywKICAgdGhlc2UgaW50ZXJmYWNlcyBhcmUgbWVhbnQgdG8gcmVwbGFjZSB0aGUgdGVtcG9y YXJ5IG1hcHBpbmdzIHByb3ZpZGVkIGJ5CiAgIGttYXBfYXRvbWljKigpIHRvZGF5LgoKVGhpcyBh bGxvd3MgdG8gZ2V0IHJpZCBvZiBjb25kaXRpb25hbCBtYXBwaW5nIGNob2ljZXMgYW5kIGFsbG93 cyB0byBoYXZlCnByZWVtcHRpYmxlIHNob3J0IHRlcm0gbWFwcGluZ3Mgb24gNjRiaXQgd2hpY2gg YXJlIHRvZGF5IGVuZm9yY2VkIHRvIGJlCm5vbi1wcmVlbXB0aWJsZSBkdWUgdG8gdGhlIGhpZ2ht ZW0gY29uc3RyYWludHMuIEl0IGNsZWFybHkgcHV0cyBvdmVyaGVhZCBvbgp0aGUgaGlnaG1lbSB1 c2VycywgYnV0IGhpZ2htZW0gaXMgc2xvdyBhbnl3YXkuCgpUaGlzIGlzIG5vdCBhIHdob2xlc2Fs ZSBjb252ZXJzaW9uIHdoaWNoIG1ha2VzIGttYXBfYXRvbWljIG1hZ2ljYWxseQpwcmVlbXB0aWJs ZSBiZWNhdXNlIHRoZXJlIG1pZ2h0IGJlIHVzYWdlIHNpdGVzIHdoaWNoIHJlbHkgb24gdGhlIGlt cGxpY2l0CnByZWVtcHQgZGlzYWJsZS4gU28gdGhpcyBuZWVkcyB0byBiZSBkb25lIG9uIGEgY2Fz ZSBieSBjYXNlIGJhc2lzIGFuZCB0aGUKY2FsbCBzaXRlcyBjb252ZXJ0ZWQgdG8ga21hcF9sb2Nh bCgpLgoKTm90ZSwgdGhhdCB0aGlzIGlzIG9ubHkgdGVzdGVkIG9uIFg4NiBhbmQgY29tcGxldGVs eSB1bnRlc3RlZCBvbiBhbGwgb3RoZXIKYXJjaGl0ZWN0dXJlcyAoYXQgbGVhc3QgaXQgY29tcGls ZXMgZXhjZXB0IG9uIGNza3kgd2hpY2ggZG9lcyBub3QgY29tcGlsZQp3aXRoIHRoZSBuZXdlc3Qg Y3Jvc3MgdG9vbHMgZnJvbSBrZXJuZWwub3JnIGluZGVwZW5kZW50IG9mIHRoaXMgY2hhbmdlKS4K ClRoZSBsb3QgaXMgYXZhaWxhYmxlIGZyb20KCiAgIGdpdDovL2dpdC5rZXJuZWwub3JnL3B1Yi9z Y20vbGludXgva2VybmVsL2dpdC90Z2x4L2RldmVsLmdpdCBoaWdobWVtCgpJdCBpcyBiYXNlZCBv biBQZXRlciBaaWpsc3RyYXMgbWlncmF0ZSBkaXNhYmxlIGJyYW5jaCB3aGljaCBpcyBjbG9zZSB0 byBiZQptZXJnZWQgaW50byB0aGUgdGlwIHRyZWUsIGJ1dCBzdGlsbCBub3QgZmluYWxpemVkOgoK ICAgZ2l0Oi8vZ2l0Lmtlcm5lbC5vcmcvcHViL3NjbS9saW51eC9rZXJuZWwvZ2l0L3BldGVyei9x dWV1ZS5naXQgc2NoZWQvbWlncmF0ZS1kaXNhYmxlCgpUaGUgc2VyaWVzIGhhcyB0aGUgZm9sbG93 aW5nIHBhcnRzOgoKICAgIFBhdGNoZXMgIDEgLSAyMjogQ29uc29saWRhdGlvbiB3b3JrIHdoaWNo IGlzIGluZGVwZW5kZW50IG9mIHRoZSBzY2hlZHVsZXIKICAgIAkgICAgICAgCSAgICAgY2hhbmdl cwoKCQkgICAgIDc5IGZpbGVzIGNoYW5nZWQsIDU5NSBpbnNlcnRpb25zKCspLCAxMjk2IGRlbGV0 aW9ucygtKQoKICAgIFBhdGNoICAgMjM6ICAgICAgTmVlZHMgdG8gYmUgZm9sZGVkIGJhY2sgaW50 byB0aGUgc2NoZWQvbWlncmF0ZS1kaXNhYmxlCgogICAgUGF0Y2hlcyAyNCAtIDI2OiBUaGUgcHJl ZW1wdGlibGUga21hcF9sb2NhbCgpIGltcGxlbWVudGF0aW9uCgogICAgCSAgICAgICAJICAgICA5 IGZpbGVzIGNoYW5nZWQsIDI4MyBpbnNlcnRpb25zKCspLCA1NyBkZWxldGlvbnMoLSkKCiAgICBQ YXRjaGVzIDI3IC0gMzc6IENsZWFudXAgb2YgdGhlIGxlc3MgY29tbW9uIGttYXAvaW9fbWFwX2F0 b21pYyB1c2VycwoKICAgIAkgICAgICAgCSAgICAgMTkgZmlsZXMgY2hhbmdlZCwgMTE0IGluc2Vy dGlvbnMoKyksIDI1NiBkZWxldGlvbnMoLSkKClZzLiBtZXJnaW5nIHRoaXMgcGlsZToKCklmIGV2 ZXJ5b25lIGFncmVlcywgSSdkIGxpa2UgdG8gdGFrZSB0aGUgZmlyc3QgcGFydCAoMS0yMikgdGhy b3VnaCB0aXAgc28KdGhhdCB0aGUgcHJlZW1wdGlibGUgaW1wbGVtZW50YXRpb24gY2FuIGJlIHNv cnRlZCBpbiB0aXAgb25jZSB0aGUgc2NoZWR1bGVyCnByZXJlcXVpc2l0ZXMgYXJlIHRoZXJlLiBU aGUgaW5pdGlhbCBjbGVhbnVwcyAoMjctMzcpIG1pZ2h0IGhhdmUgdG8gd2FpdCBpZgp0aGVyZSBh cmUgY29uZmxpY3RzIHZzLiB0aGUgZHJtL2dwdSB0cmVlLiBXZSdsbCBzZWUuCgo+RnJvbSB3aGF0 IEkgY2FuIHRlbGwga21hcF9hdG9taWMoKSBjYW4gYmUgcmVtb3ZlZCBhbGwgdG9nZXRoZXIgYW5k CmNvbXBsZXRseSByZXBsYWNlZCBieSBrbWFwX2xvY2FsKCkuIE1vc3Qgb2YgdGhlIHVzYWdlIHNp dGVzIGFyZSB0cml2aWFsIGFuZApqdXN0IGRvaW5nIG1lbWNweSgpLCBtZW1zZXQoKSBvciB0cml2 aWFsIG9wZXJhdGlvbnMgb24gdGhlIHRlbXBvcmFyaWx5Cm1hcHBlZCBwYWdlLiBUaGUgaW50ZXJl c3Rpbmcgb25lcyBhcmUgdGhvc2Ugd2hpY2ggZG8gZWl0aGVyIGNvbmRpdGlvbmFsCnN0dWZmIG9y IGhhdmUgY29weV8uKl91c2VyX2luYXRvbWljKCkgaW5zaWRlLiBBcyBzaG93biB3aXRoIHRoZSBj cmFzaCBhbmQKZHJtL2dwdSBjbGVhbnVwcyB0aGlzIGFsbG93cyB0byBzaW1wbGlmeSB0aGUgY29k ZSBxdWl0ZSBhIGJpdC4KCkNoYW5nZXMgdnMuIFYyOgoKICAtIFJlbW92ZSB0aGUgbWlncmF0ZSBk aXNhYmxlIGZyb20ga21hcF9sb2NhbCBhbmQgb25seSBpc3N1ZSB0aGF0IHdoZW4gdGhlCiAgICB0 aGVyZSBpcyBhbiBhY3R1YWwgaGlnaG1lbSBtYXBwaW5nLiAoTGludXMpCiAgLSBSZW9yZGVyZWQg dGhlIHNlcmllcyBzbyB0aGUgY29uc29saWRhdGlvbiBpcyB1cGZyb250CiAgLSBHZXQgcmlkIG9m IGttYXBfdHlwZXMuaCBhbmQgdGhlIGFzc29jaWF0ZWQgY3J1ZnQKICAtIEZpeHVwIGRvY3VtZW50 YXRpb24gYW5kIGFkZCBmdW5jdGlvbiBkb2N1bWVudGF0aW9uIGZvciBrbWFwXyoKICAtIFNwbGl0 b3V0IHRoZSBpbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBpbnRvIGEgc2VwZXJhdGUgaGVhZGVyCiAg LSBNb3JlIGNsZWFudXBzIC0gcmVtb3ZhbCBvZiB1bnVzZWQgZnVuY3Rpb25zCiAgLSBSZXBsYWNl IGEgZmV3IG9mIHRoZSBsZXNzIGZyZXF1ZW50bHkgdXNlZCBrbWFwX2F0b21pYyBhbmQKICAgIGlv X21hcHBpbmdfbWFwX2F0b21pYyB2YXJpYW50cyBhbmQgcmVtb3ZlIHRob3NlIGludGVyZmFjZXMu CgpUaGFua3MsCgoJdGdseAotLS0KIGFyY2gvYWxwaGEvaW5jbHVkZS9hc20va21hcF90eXBlcy5o ICAgICAgICAgICAgICAgICAgIHwgICAxNSAKIGFyY2gvYXJjL2luY2x1ZGUvYXNtL2ttYXBfdHlw ZXMuaCAgICAgICAgICAgICAgICAgICAgIHwgICAxNCAKIGFyY2gvYXJtL2luY2x1ZGUvYXNtL2tt YXBfdHlwZXMuaCAgICAgICAgICAgICAgICAgICAgIHwgICAxMCAKIGFyY2gvYXJtL21tL2hpZ2ht ZW0uYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIDEyMSAtLS0tLS0tCiBhcmNo L2lhNjQvaW5jbHVkZS9hc20va21hcF90eXBlcy5oICAgICAgICAgICAgICAgICAgICB8ICAgMTMg CiBhcmNoL21pY3JvYmxhemUvbW0vaGlnaG1lbS5jICAgICAgICAgICAgICAgICAgICAgICAgICB8 ICAgNzggLS0tLQogYXJjaC9taXBzL2luY2x1ZGUvYXNtL2ttYXBfdHlwZXMuaCAgICAgICAgICAg ICAgICAgICAgfCAgIDEzIAogYXJjaC9uZHMzMi9tbS9oaWdobWVtLmMgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgfCAgIDQ4IC0tCiBhcmNoL3BhcmlzYy9pbmNsdWRlL2FzbS9rbWFwX3R5 cGVzLmggICAgICAgICAgICAgICAgICB8ICAgMTMgCiBhcmNoL3Bvd2VycGMvaW5jbHVkZS9hc20v a21hcF90eXBlcy5oICAgICAgICAgICAgICAgICB8ICAgMTMgCiBhcmNoL3Bvd2VycGMvbW0vaGln aG1lbS5jICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgNjcgLS0tLQogYXJjaC9zaC9p bmNsdWRlL2FzbS9rbWFwX3R5cGVzLmggICAgICAgICAgICAgICAgICAgICAgfCAgIDE1IAogYXJj aC9zcGFyYy9pbmNsdWRlL2FzbS9rbWFwX3R5cGVzLmggICAgICAgICAgICAgICAgICAgfCAgIDEx IAogYXJjaC9zcGFyYy9tbS9oaWdobWVtLmMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg fCAgMTE1IC0tLS0tLS0KIGFyY2gvdW0vaW5jbHVkZS9hc20va21hcF90eXBlcy5oICAgICAgICAg ICAgICAgICAgICAgIHwgICAxMyAKIGFyY2gveDg2L2luY2x1ZGUvYXNtL2ttYXBfdHlwZXMuaCAg ICAgICAgICAgICAgICAgICAgIHwgICAxMyAKIGIvRG9jdW1lbnRhdGlvbi9kcml2ZXItYXBpL2lv LW1hcHBpbmcucnN0ICAgICAgICAgICAgIHwgICA5MiArKy0tLQogYi9hcmNoL2FyYy9LY29uZmln ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAxIAogYi9hcmNoL2FyYy9p bmNsdWRlL2FzbS9oaWdobWVtLmggICAgICAgICAgICAgICAgICAgICAgfCAgIDI2ICsKIGIvYXJj aC9hcmMvbW0vaGlnaG1lbS5jICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICA1NCAt LS0KIGIvYXJjaC9hcm0vS2NvbmZpZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IHwgICAgMSAKIGIvYXJjaC9hcm0vaW5jbHVkZS9hc20vZml4bWFwLmggICAgICAgICAgICAgICAg ICAgICAgIHwgICAgNCAKIGIvYXJjaC9hcm0vaW5jbHVkZS9hc20vaGlnaG1lbS5oICAgICAgICAg ICAgICAgICAgICAgIHwgICAzMyArLQogYi9hcmNoL2FybS9tbS9NYWtlZmlsZSAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgfCAgICAxIAogYi9hcmNoL2FybS9tbS9jYWNoZS1mZXJvY2Vv bi1sMi5jICAgICAgICAgICAgICAgICAgICAgfCAgICA2IAogYi9hcmNoL2FybS9tbS9jYWNoZS14 c2MzbDIuYyAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICA0IAogYi9hcmNoL2Nza3kvS2Nv bmZpZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAxIAogYi9hcmNoL2Nz a3kvaW5jbHVkZS9hc20vZml4bWFwLmggICAgICAgICAgICAgICAgICAgICAgfCAgICA0IAogYi9h cmNoL2Nza3kvaW5jbHVkZS9hc20vaGlnaG1lbS5oICAgICAgICAgICAgICAgICAgICAgfCAgICA2 IAogYi9hcmNoL2Nza3kvbW0vaGlnaG1lbS5jICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg fCAgIDc1IC0tLS0KIGIvYXJjaC9taWNyb2JsYXplL0tjb25maWcgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIHwgICAgMSAKIGIvYXJjaC9taWNyb2JsYXplL2luY2x1ZGUvYXNtL2ZpeG1hcC5o ICAgICAgICAgICAgICAgIHwgICAgNCAKIGIvYXJjaC9taWNyb2JsYXplL2luY2x1ZGUvYXNtL2hp Z2htZW0uaCAgICAgICAgICAgICAgIHwgICAgNiAKIGIvYXJjaC9taWNyb2JsYXplL21tL01ha2Vm aWxlICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgMSAKIGIvYXJjaC9taWNyb2JsYXplL21t L2luaXQuYyAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgNiAKIGIvYXJjaC9taXBzL0tj b25maWcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgMSAKIGIvYXJjaC9t aXBzL2luY2x1ZGUvYXNtL2ZpeG1hcC5oICAgICAgICAgICAgICAgICAgICAgIHwgICAgNCAKIGIv YXJjaC9taXBzL2luY2x1ZGUvYXNtL2hpZ2htZW0uaCAgICAgICAgICAgICAgICAgICAgIHwgICAg NiAKIGIvYXJjaC9taXBzL2tlcm5lbC9jcmFzaF9kdW1wLmMgICAgICAgICAgICAgICAgICAgICAg IHwgICA0MiAtLQogYi9hcmNoL21pcHMvbW0vaGlnaG1lbS5jICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgfCAgIDc3IC0tLS0KIGIvYXJjaC9taXBzL21tL2luaXQuYyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgIHwgICAgNCAKIGIvYXJjaC9uZHMzMi9LY29uZmlnLmNwdSAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgMSAKIGIvYXJjaC9uZHMzMi9pbmNsdWRlL2Fz bS9maXhtYXAuaCAgICAgICAgICAgICAgICAgICAgIHwgICAgNCAKIGIvYXJjaC9uZHMzMi9pbmNs dWRlL2FzbS9oaWdobWVtLmggICAgICAgICAgICAgICAgICAgIHwgICAyMiAtCiBiL2FyY2gvbmRz MzIvbW0vTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDEgCiBiL2Fy Y2gvb3BlbnJpc2MvbW0vaW5pdC5jICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDEg CiBiL2FyY2gvb3BlbnJpc2MvbW0vaW9yZW1hcC5jICAgICAgICAgICAgICAgICAgICAgICAgICB8 ICAgIDEgCiBiL2FyY2gvcG93ZXJwYy9LY29uZmlnICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICB8ICAgIDEgCiBiL2FyY2gvcG93ZXJwYy9pbmNsdWRlL2FzbS9maXhtYXAuaCAgICAgICAg ICAgICAgICAgICB8ICAgIDQgCiBiL2FyY2gvcG93ZXJwYy9pbmNsdWRlL2FzbS9oaWdobWVtLmgg ICAgICAgICAgICAgICAgICB8ICAgIDcgCiBiL2FyY2gvcG93ZXJwYy9tbS9NYWtlZmlsZSAgICAg ICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDEgCiBiL2FyY2gvcG93ZXJwYy9tbS9tZW0uYyAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDcgCiBiL2FyY2gvc2gvaW5jbHVkZS9h c20vZml4bWFwLmggICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDggCiBiL2FyY2gvc2gvbW0v aW5pdC5jICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDggCiBiL2FyY2gv c3BhcmMvS2NvbmZpZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDEgCiBi L2FyY2gvc3BhcmMvaW5jbHVkZS9hc20vaGlnaG1lbS5oICAgICAgICAgICAgICAgICAgICB8ICAg IDggCiBiL2FyY2gvc3BhcmMvaW5jbHVkZS9hc20vdmFkZHJzLmggICAgICAgICAgICAgICAgICAg ICB8ICAgIDQgCiBiL2FyY2gvc3BhcmMvbW0vTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICB8ICAgIDMgCiBiL2FyY2gvc3BhcmMvbW0vc3JtbXUuYyAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICB8ICAgIDIgCiBiL2FyY2gvdW0vaW5jbHVkZS9hc20vZml4bWFwLmggICAg ICAgICAgICAgICAgICAgICAgICB8ICAgIDEgCiBiL2FyY2gveDg2L0tjb25maWcgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDMgCiBiL2FyY2gveDg2L2luY2x1ZGUvYXNt L2ZpeG1hcC5oICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDUgCiBiL2FyY2gveDg2L2luY2x1 ZGUvYXNtL2hpZ2htZW0uaCAgICAgICAgICAgICAgICAgICAgICB8ICAgMTMgCiBiL2FyY2gveDg2 L2luY2x1ZGUvYXNtL2lvbWFwLmggICAgICAgICAgICAgICAgICAgICAgICB8ICAgMTMgCiBiL2Fy Y2gveDg2L2luY2x1ZGUvYXNtL3BhcmF2aXJ0X3R5cGVzLmggICAgICAgICAgICAgICB8ICAgIDEg CiBiL2FyY2gveDg2L2tlcm5lbC9jcmFzaF9kdW1wXzMyLmMgICAgICAgICAgICAgICAgICAgICB8 ICAgNDggLS0KIGIvYXJjaC94ODYvbW0vaGlnaG1lbV8zMi5jICAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICA1OSAtLS0KIGIvYXJjaC94ODYvbW0vaW5pdF8zMi5jICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIHwgICAxNSAKIGIvYXJjaC94ODYvbW0vaW9tYXBfMzIuYyAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIHwgICA1NyAtLS0KIGIvYXJjaC94dGVuc2EvS2NvbmZpZyAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgMSAKIGIvYXJjaC94dGVuc2EvaW5j bHVkZS9hc20vZml4bWFwLmggICAgICAgICAgICAgICAgICAgIHwgICAgNCAKIGIvYXJjaC94dGVu c2EvaW5jbHVkZS9hc20vaGlnaG1lbS5oICAgICAgICAgICAgICAgICAgIHwgICAxMiAKIGIvYXJj aC94dGVuc2EvbW0vaGlnaG1lbS5jICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICA0NiAt LQogYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vaTkxNV9nZW1fZXhlY2J1ZmZlci5jICAgICAg fCAgICA3IAogYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X2dlbS5jICAgICAgICAgICAgICAg ICAgICAgfCAgIDQwIC0tCiBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0cy9pOTE1X2dl bS5jICAgICAgICAgICB8ICAgIDQgCiBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0cy9p OTE1X2dlbV9ndHQuYyAgICAgICB8ICAgIDggCiBiL2RyaXZlcnMvZ3B1L2RybS9ub3V2ZWF1L252 a20vc3ViZGV2L2RldmluaXQvZmJtZW0uaCB8ICAgIDggCiBiL2RyaXZlcnMvZ3B1L2RybS9xeGwv cXhsX2ltYWdlLmMgICAgICAgICAgICAgICAgICAgICB8ICAgMTggLQogYi9kcml2ZXJzL2dwdS9k cm0vcXhsL3F4bF9pb2N0bC5jICAgICAgICAgICAgICAgICAgICAgfCAgIDI3IC0KIGIvZHJpdmVy cy9ncHUvZHJtL3F4bC9xeGxfb2JqZWN0LmMgICAgICAgICAgICAgICAgICAgIHwgICAxMiAKIGIv ZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfb2JqZWN0LmggICAgICAgICAgICAgICAgICAgIHwgICAg NCAKIGIvZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfcmVsZWFzZS5jICAgICAgICAgICAgICAgICAg IHwgICAgNCAKIGIvZHJpdmVycy9ncHUvZHJtL3R0bS90dG1fYm9fdXRpbC5jICAgICAgICAgICAg ICAgICAgIHwgICAyMCAtCiBiL2RyaXZlcnMvZ3B1L2RybS92bXdnZngvdm13Z2Z4X2JsaXQuYyAg ICAgICAgICAgICAgICB8ICAgMzAgLQogYi9mcy9haW8uYyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgfCAgICAxIAogYi9mcy9idHJmcy9jdHJlZS5oICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAxIAogYi9pbmNsdWRlL2FzbS1nZW5lcmlj L0tidWlsZCAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAyIAogYi9pbmNsdWRlL2FzbS1n ZW5lcmljL2ttYXBfc2l6ZS5oICAgICAgICAgICAgICAgICAgICAgfCAgIDEyIAogYi9pbmNsdWRl L2xpbnV4L2hpZ2htZW0taW50ZXJuYWwuaCAgICAgICAgICAgICAgICAgICAgfCAgMjEwICsrKysr KysrKysrKwogYi9pbmNsdWRlL2xpbnV4L2hpZ2htZW0uaCAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgfCAgMjk0ICsrKysrKy0tLS0tLS0tLS0tLQogYi9pbmNsdWRlL2xpbnV4L2lvLW1hcHBp bmcuaCAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDI4IC0KIGIvaW5jbHVkZS9saW51eC9r ZXJuZWwuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAyMSAtCiBiL2luY2x1ZGUv bGludXgvcHJlZW1wdC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgMzggLS0KIGIv aW5jbHVkZS9saW51eC9zY2hlZC5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAx MSAKIGIva2VybmVsL2VudHJ5L2NvbW1vbi5jICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IHwgICAgMiAKIGIva2VybmVsL2ZvcmsuYyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICAgMSAKIGIva2VybmVsL3NjaGVkL2NvcmUuYyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIHwgICA2MyArKysKIGIva2VybmVsL3NjaGVkL3NjaGVkLmggICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIHwgICAgNCAKIGIvbGliL3NtcF9wcm9jZXNzb3JfaWQuYyAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgMiAKIGIvbW0vS2NvbmZpZyAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgMyAKIGIvbW0vaGlnaG1lbS5j ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIDI1NSArKysrKysrKysr KysrKy0KIGluY2x1ZGUvYXNtLWdlbmVyaWMva21hcF90eXBlcy5oICAgICAgICAgICAgICAgICAg ICAgIHwgICAxMSAKIDEwMyBmaWxlcyBjaGFuZ2VkLCA5NTkgaW5zZXJ0aW9ucygrKSwgMTU3NiBk ZWxldGlvbnMoLSkK

--
To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"[email protected]">[email protected]</a>

#1 lore raw

PATCH v3 1/37 mm/highmem: Un-EXPORT __kmap_atomic_idx()

Nothing in modules can use that.

---
 mm/highmem.c |    2 --
 1 file changed, 2 deletions(-)
mm/highmem.c +0 -2
@@ -108,8 +108,6 @@ static inline wait_queue_head_t *get_pkm
 atomic_long_t _totalhigh_pages __read_mostly;
 EXPORT_SYMBOL(_totalhigh_pages);
 
-EXPORT_PER_CPU_SYMBOL(__kmap_atomic_idx);
-
 unsigned int nr_free_highpages (void)
 {
 	struct zone *zone;

--
To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"[email protected]">[email protected]</a>

#2 lore raw

[tip: core/mm] mm/highmem: Un-EXPORT __kmap_atomic_idx()

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     16675dda9355505245b89dd50723a2754819594b
Gitweb:        https://git.kernel.org/tip/16675dda9355505245b89dd50723a2754819594b
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:13 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:53 +01:00

mm/highmem: Un-EXPORT __kmap_atomic_idx()

Nothing in modules can use that.

---
 mm/highmem.c | 2 --
 1 file changed, 2 deletions(-)
mm/highmem.c +0 -2
index 1352a27..6abfd76 100644
@@ -108,8 +108,6 @@ static inline wait_queue_head_t *get_pkmap_wait_queue_head(unsigned int color)
 atomic_long_t _totalhigh_pages __read_mostly;
 EXPORT_SYMBOL(_totalhigh_pages);
 
-EXPORT_PER_CPU_SYMBOL(__kmap_atomic_idx);
-
 unsigned int nr_free_highpages (void)
 {
 	struct zone *zone;
#3 lore raw

PATCH v3 2/37 highmem: Remove unused functions

In reply to Thomas Gleixner

Nothing uses totalhigh_pages_dec() and totalhigh_pages_set().

---
V3: New patch

---
 include/linux/highmem.h |   10 ----------
 1 file changed, 10 deletions(-)
include/linux/highmem.h +0 -10
@@ -104,21 +104,11 @@ static inline void totalhigh_pages_inc(v
 	atomic_long_inc(&_totalhigh_pages);
 }
 
-static inline void totalhigh_pages_dec(void)
-{
-	atomic_long_dec(&_totalhigh_pages);
-}
-
 static inline void totalhigh_pages_add(long count)
 {
 	atomic_long_add(count, &_totalhigh_pages);
 }
 
-static inline void totalhigh_pages_set(long val)
-{
-	atomic_long_set(&_totalhigh_pages, val);
-}
-
 void kmap_flush_unused(void);
 
 struct page *kmap_to_page(void *addr);
#4 lore raw

[tip: core/mm] highmem: Remove unused functions

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     b819fd9da38508e0504624b87d9983fcc4237f3c
Gitweb:        https://git.kernel.org/tip/b819fd9da38508e0504624b87d9983fcc4237f3c
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:14 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:53 +01:00

highmem: Remove unused functions

Nothing uses totalhigh_pages_dec() and totalhigh_pages_set().

---
 include/linux/highmem.h | 10 ----------
 1 file changed, 10 deletions(-)
include/linux/highmem.h +0 -10
index 14e6202..f5c3133 100644
@@ -104,21 +104,11 @@ static inline void totalhigh_pages_inc(void)
 	atomic_long_inc(&_totalhigh_pages);
 }
 
-static inline void totalhigh_pages_dec(void)
-{
-	atomic_long_dec(&_totalhigh_pages);
-}
-
 static inline void totalhigh_pages_add(long count)
 {
 	atomic_long_add(count, &_totalhigh_pages);
 }
 
-static inline void totalhigh_pages_set(long val)
-{
-	atomic_long_set(&_totalhigh_pages, val);
-}
-
 void kmap_flush_unused(void);
 
 struct page *kmap_to_page(void *addr);
#5 lore raw

PATCH v3 3/37 fs: Remove asm/kmap_types.h includes

In reply to Thomas Gleixner

Historical leftovers from the time where kmap() had fixed slots.

---
 fs/aio.c         |    1 -
 fs/btrfs/ctree.h |    1 -
 2 files changed, 2 deletions(-)
fs/aio.c +0 -1
@@ -43,7 +43,6 @@
 #include <linux/mount.h>
 #include <linux/pseudo_fs.h>
 
-#include <asm/kmap_types.h>
 #include <linux/uaccess.h>
 #include <linux/nospec.h>
 
fs/btrfs/ctree.h +0 -1
@@ -17,7 +17,6 @@
 #include <linux/wait.h>
 #include <linux/slab.h>
 #include <trace/events/btrfs.h>
-#include <asm/kmap_types.h>
 #include <asm/unaligned.h>
 #include <linux/pagemap.h>
 #include <linux/btrfs.h>

--
To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"[email protected]">[email protected]</a>

Acked-by on v3 3/37
#6 lore raw

Re: [patch V3 03/37] fs: Remove asm/kmap_types.h includes

Quoted 10 lines · Thomas Gleixner

Historical leftovers from the time where kmap() had fixed slots.

Cc Alexander Viro <[email protected]>
Cc Benjamin LaHaise <[email protected]>
Cc Chris Mason <[email protected]>
Cc Josef Bacik <[email protected]>
Cc David Sterba <[email protected]>

For the btrfs bits

Quoted 12 lines
 fs/btrfs/ctree.h |    1 -
fs/btrfs/ctree.h +0 -1
@@ -17,7 +17,6 @@
 #include <linux/wait.h>
 #include <linux/slab.h>
 #include <trace/events/btrfs.h>
-#include <asm/kmap_types.h>
 #include <asm/unaligned.h>
 #include <linux/pagemap.h>
 #include <linux/btrfs.h>
#7 lore raw

[tip: core/mm] fs: Remove asm/kmap_types.h includes

In reply to Thomas Gleixner
The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     e8f147dc3f1f6b4c27b2eeaf82df4f469d80d469
Gitweb:        https://git.kernel.org/tip/e8f147dc3f1f6b4c27b2eeaf82df4f469d80d469
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:15 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:53 +01:00

fs: Remove asm/kmap_types.h includes

Historical leftovers from the time where kmap() had fixed slots.

---
 fs/aio.c         | 1 -
 fs/btrfs/ctree.h | 1 -
 2 files changed, 2 deletions(-)
fs/aio.c +0 -1
index c45c20d..0247daf 100644
@@ -43,7 +43,6 @@
 #include <linux/mount.h>
 #include <linux/pseudo_fs.h>
 
-#include <asm/kmap_types.h>
 #include <linux/uaccess.h>
 #include <linux/nospec.h>
 
fs/btrfs/ctree.h +0 -1
index 0378933..01947f6 100644
@@ -17,7 +17,6 @@
 #include <linux/wait.h>
 #include <linux/slab.h>
 #include <trace/events/btrfs.h>
-#include <asm/kmap_types.h>
 #include <asm/unaligned.h>
 #include <linux/pagemap.h>
 #include <linux/btrfs.h>
#8 lore raw

PATCH v3 4/37 sh/highmem: Remove all traces of unused cruft

In reply to Thomas Gleixner

For whatever reasons SH has highmem bits all over the place but does not enable it via Kconfig. Remove the bitrot.

---
 arch/sh/include/asm/fixmap.h     |    8 --------
 arch/sh/include/asm/kmap_types.h |   15 ---------------
 arch/sh/mm/init.c                |    8 --------
 3 files changed, 31 deletions(-)
arch/sh/include/asm/fixmap.h +0 -8
@@ -13,9 +13,6 @@
 #include <linux/kernel.h>
 #include <linux/threads.h>
 #include <asm/page.h>
-#ifdef CONFIG_HIGHMEM
-#include <asm/kmap_types.h>
-#endif
 
 /*
  * Here we define all the compile-time 'special' virtual
@@ -53,11 +50,6 @@ enum fixed_addresses {
 	FIX_CMAP_BEGIN,
 	FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS) - 1,
 
-#ifdef CONFIG_HIGHMEM
-	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
-	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
-#endif
-
 #ifdef CONFIG_IOREMAP_FIXED
 	/*
 	 * FIX_IOREMAP entries are useful for mapping physical address
arch/sh/include/asm/kmap_types.h deleted +0 -15
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __SH_KMAP_TYPES_H
-#define __SH_KMAP_TYPES_H
-
-/* Dummy header just to define km_type. */
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define  __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif
arch/sh/mm/init.c +0 -8
@@ -362,9 +362,6 @@ void __init mem_init(void)
 	mem_init_print_info(NULL);
 	pr_info("virtual kernel memory layout:\n"
 		"    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
-#ifdef CONFIG_HIGHMEM
-		"    pkmap   : 0x%08lx - 0x%08lx   (%4ld kB)\n"
-#endif
 		"    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
 		"    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB) (cached)\n"
 #ifdef CONFIG_UNCACHED_MAPPING
@@ -376,11 +373,6 @@ void __init mem_init(void)
 		FIXADDR_START, FIXADDR_TOP,
 		(FIXADDR_TOP - FIXADDR_START) >> 10,
 
-#ifdef CONFIG_HIGHMEM
-		PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
-		(LAST_PKMAP*PAGE_SIZE) >> 10,
-#endif
-
 		(unsigned long)VMALLOC_START, VMALLOC_END,
 		(VMALLOC_END - VMALLOC_START) >> 20,
 
#9 lore raw

[tip: core/mm] sh/highmem: Remove all traces of unused cruft

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     673afbace459ae6fd8d03bda410e0a9f10438c99
Gitweb:        https://git.kernel.org/tip/673afbace459ae6fd8d03bda410e0a9f10438c99
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:16 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:54 +01:00

sh/highmem: Remove all traces of unused cruft

For whatever reasons SH has highmem bits all over the place but does not enable it via Kconfig. Remove the bitrot.

---
 arch/sh/include/asm/fixmap.h     |  8 --------
 arch/sh/include/asm/kmap_types.h | 15 ---------------
 arch/sh/mm/init.c                |  8 --------
 3 files changed, 31 deletions(-)
 delete mode 100644 arch/sh/include/asm/kmap_types.h
arch/sh/include/asm/fixmap.h +0 -8
index f38adc1..b07fbc7 100644
@@ -13,9 +13,6 @@
 #include <linux/kernel.h>
 #include <linux/threads.h>
 #include <asm/page.h>
-#ifdef CONFIG_HIGHMEM
-#include <asm/kmap_types.h>
-#endif
 
 /*
  * Here we define all the compile-time 'special' virtual
@@ -53,11 +50,6 @@ enum fixed_addresses {
 	FIX_CMAP_BEGIN,
 	FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS) - 1,
 
-#ifdef CONFIG_HIGHMEM
-	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
-	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
-#endif
-
 #ifdef CONFIG_IOREMAP_FIXED
 	/*
 	 * FIX_IOREMAP entries are useful for mapping physical address
arch/sh/include/asm/kmap_types.h deleted +0 -15
deleted file mode 100644
index b78107f..0000000
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __SH_KMAP_TYPES_H
-#define __SH_KMAP_TYPES_H
-
-/* Dummy header just to define km_type. */
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define  __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif
arch/sh/mm/init.c +0 -8
index 3348e0c..0db6919 100644
@@ -362,9 +362,6 @@ void __init mem_init(void)
 	mem_init_print_info(NULL);
 	pr_info("virtual kernel memory layout:\n"
 		"    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
-#ifdef CONFIG_HIGHMEM
-		"    pkmap   : 0x%08lx - 0x%08lx   (%4ld kB)\n"
-#endif
 		"    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
 		"    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB) (cached)\n"
 #ifdef CONFIG_UNCACHED_MAPPING
@@ -376,11 +373,6 @@ void __init mem_init(void)
 		FIXADDR_START, FIXADDR_TOP,
 		(FIXADDR_TOP - FIXADDR_START) >> 10,
 
-#ifdef CONFIG_HIGHMEM
-		PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
-		(LAST_PKMAP*PAGE_SIZE) >> 10,
-#endif
-
 		(unsigned long)VMALLOC_START, VMALLOC_END,
 		(VMALLOC_END - VMALLOC_START) >> 20,
 
#10 lore raw

PATCH v3 5/37 asm-generic: Provide kmap_size.h

In reply to Thomas Gleixner

kmap_types.h is a misnomer because the old atomic MAP based array does not exist anymore and the whole indirection of architectures including kmap_types.h is inconinstent and does not allow to provide guard page debugging for this misfeature.

Add a common header file which defines the mapping stack size for all architectures. Will be used when converting architectures over to a generic kmap_local/atomic implementation.

The array size is chosen with the following constraints in mind:

- The deepest nest level in one context is 3 according to code inspection.

- The worst case nesting for the upcoming reemptible version would be:

2 maps in task context and a fault inside
2 maps in the fault handler
3 maps in softirq
2 maps in interrupt

So a total of 16 is sufficient and probably overestimated.

---
V3: New patch

---
 include/asm-generic/Kbuild      |    1 +
 include/asm-generic/kmap_size.h |   12 ++++++++++++
 2 files changed, 13 insertions(+)
include/asm-generic/Kbuild +1 -0
@@ -31,6 +31,7 @@ mandatory-y += irq_regs.h
 mandatory-y += irq_work.h
 mandatory-y += kdebug.h
 mandatory-y += kmap_types.h
+mandatory-y += kmap_size.h
 mandatory-y += kprobes.h
 mandatory-y += linkage.h
 mandatory-y += local.h
include/asm-generic/kmap_size.h new file +12 -0
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_KMAP_SIZE_H
+#define _ASM_GENERIC_KMAP_SIZE_H
+
+/* For debug this provides guard pages between the maps */
+#ifdef CONFIG_DEBUG_HIGHMEM
+# define KM_MAX_IDX	33
+#else
+# define KM_MAX_IDX	16
+#endif
+
+#endif
Acked-by on v3 5/37
#11 lore raw

Re: [patch V3 05/37] asm-generic: Provide kmap_size.h

Quoted 17 lines · Thomas Gleixner

kmap_types.h is a misnomer because the old atomic MAP based array does not exist anymore and the whole indirection of architectures including kmap_types.h is inconinstent and does not allow to provide guard page debugging for this misfeature.

Add a common header file which defines the mapping stack size for all architectures. Will be used when converting architectures over to a generic kmap_local/atomic implementation.

The array size is chosen with the following constraints in mind:

- The deepest nest level in one context is 3 according to code inspection.

- The worst case nesting for the upcoming reemptible version would be:

Quoted 8 lines

2 maps in task context and a fault inside
2 maps in the fault handler
3 maps in softirq
2 maps in interrupt

So a total of 16 is sufficient and probably overestimated.

#12 lore raw

[tip: core/mm] asm-generic: Provide kmap_size.h

In reply to Thomas Gleixner
The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     4f8b96cd47b06f1e3ec71c1a3216113efe8dbfb5
Gitweb:        https://git.kernel.org/tip/4f8b96cd47b06f1e3ec71c1a3216113efe8dbfb5
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:17 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:54 +01:00

asm-generic: Provide kmap_size.h

kmap_types.h is a misnomer because the old atomic MAP based array does not exist anymore and the whole indirection of architectures including kmap_types.h is inconinstent and does not allow to provide guard page debugging for this misfeature.

Add a common header file which defines the mapping stack size for all architectures. Will be used when converting architectures over to a generic kmap_local/atomic implementation.

The array size is chosen with the following constraints in mind:

- The deepest nest level in one context is 3 according to code inspection.

- The worst case nesting for the upcoming reemptible version would be:

2 maps in task context and a fault inside
2 maps in the fault handler
3 maps in softirq
2 maps in interrupt

So a total of 16 is sufficient and probably overestimated.

---
 include/asm-generic/Kbuild      |  1 +
 include/asm-generic/kmap_size.h | 12 ++++++++++++
 2 files changed, 13 insertions(+)
 create mode 100644 include/asm-generic/kmap_size.h
include/asm-generic/Kbuild +1 -0
index e78bbb9..ed62d38 100644
@@ -31,6 +31,7 @@ mandatory-y += irq_regs.h
 mandatory-y += irq_work.h
 mandatory-y += kdebug.h
 mandatory-y += kmap_types.h
+mandatory-y += kmap_size.h
 mandatory-y += kprobes.h
 mandatory-y += linkage.h
 mandatory-y += local.h
include/asm-generic/kmap_size.h new file +12 -0
new file mode 100644
index 0000000..9d6c778
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_GENERIC_KMAP_SIZE_H
+#define _ASM_GENERIC_KMAP_SIZE_H
+
+/* For debug this provides guard pages between the maps */
+#ifdef CONFIG_DEBUG_HIGHMEM
+# define KM_MAX_IDX	33
+#else
+# define KM_MAX_IDX	16
+#endif
+
+#endif
#13 lore raw

PATCH v3 6/37 highmem: Provide generic variant of kmap_atomic*

In reply to Thomas Gleixner

The kmap_atomic* interfaces in all architectures are pretty much the same except for post map operations (flush) and pre- and post unmap operations.

Provide a generic variant for that.

---
V3: Do not reuse the kmap_atomic_idx pile and use kmap_size.h right away
V2: Address review comments from Christoph (style and EXPORT variant)

---
 include/linux/highmem.h |   82 ++++++++++++++++++++++-----
 mm/Kconfig              |    3 +
 mm/highmem.c            |  144 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 211 insertions(+), 18 deletions(-)
include/linux/highmem.h +66 -16
@@ -31,9 +31,16 @@ static inline void invalidate_kernel_vma
 
 #include <asm/kmap_types.h>
 
+/*
+ * Outside of CONFIG_HIGHMEM to support X86 32bit iomap_atomic() cruft.
+ */
+#ifdef CONFIG_KMAP_LOCAL
+void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot);
+void *__kmap_local_page_prot(struct page *page, pgprot_t prot);
+void kunmap_local_indexed(void *vaddr);
+#endif
+
 #ifdef CONFIG_HIGHMEM
-extern void *kmap_atomic_high_prot(struct page *page, pgprot_t prot);
-extern void kunmap_atomic_high(void *kvaddr);
 #include <asm/highmem.h>
 
 #ifndef ARCH_HAS_KMAP_FLUSH_TLB
@@ -81,6 +88,11 @@ static inline void kunmap(struct page *p
  * be used in IRQ contexts, so in some (very limited) cases we need
  * it.
  */
+
+#ifndef CONFIG_KMAP_LOCAL
+void *kmap_atomic_high_prot(struct page *page, pgprot_t prot);
+void kunmap_atomic_high(void *kvaddr);
+
 static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
 {
 	preempt_disable();
@@ -89,7 +101,38 @@ static inline void *kmap_atomic_prot(str
 		return page_address(page);
 	return kmap_atomic_high_prot(page, prot);
 }
-#define kmap_atomic(page)	kmap_atomic_prot(page, kmap_prot)
+
+static inline void __kunmap_atomic(void *vaddr)
+{
+	kunmap_atomic_high(vaddr);
+}
+#else /* !CONFIG_KMAP_LOCAL */
+
+static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+{
+	preempt_disable();
+	pagefault_disable();
+	return __kmap_local_page_prot(page, prot);
+}
+
+static inline void *kmap_atomic_pfn(unsigned long pfn)
+{
+	preempt_disable();
+	pagefault_disable();
+	return __kmap_local_pfn_prot(pfn, kmap_prot);
+}
+
+static inline void __kunmap_atomic(void *addr)
+{
+	kunmap_local_indexed(addr);
+}
+
+#endif /* CONFIG_KMAP_LOCAL */
+
+static inline void *kmap_atomic(struct page *page)
+{
+	return kmap_atomic_prot(page, kmap_prot);
+}
 
 /* declarations for linux/mm/highmem.c */
 unsigned int nr_free_highpages(void);
@@ -147,25 +190,33 @@ static inline void *kmap_atomic(struct p
 	pagefault_disable();
 	return page_address(page);
 }
-#define kmap_atomic_prot(page, prot)	kmap_atomic(page)
 
-static inline void kunmap_atomic_high(void *addr)
+static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+{
+	return kmap_atomic(page);
+}
+
+static inline void *kmap_atomic_pfn(unsigned long pfn)
+{
+	return kmap_atomic(pfn_to_page(pfn));
+}
+
+static inline void __kunmap_atomic(void *addr)
 {
 	/*
 	 * Mostly nothing to do in the CONFIG_HIGHMEM=n case as kunmap_atomic()
-	 * handles re-enabling faults + preemption
+	 * handles re-enabling faults and preemption
 	 */
 #ifdef ARCH_HAS_FLUSH_ON_KUNMAP
 	kunmap_flush_on_unmap(addr);
 #endif
 }
 
-#define kmap_atomic_pfn(pfn)	kmap_atomic(pfn_to_page(pfn))
-
 #define kmap_flush_unused()	do {} while(0)
 
 #endif /* CONFIG_HIGHMEM */
 
+#if !defined(CONFIG_KMAP_LOCAL)
 #if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32)
 
 DECLARE_PER_CPU(int, __kmap_atomic_idx);
@@ -196,22 +247,21 @@ static inline void kmap_atomic_idx_pop(v
 	__this_cpu_dec(__kmap_atomic_idx);
 #endif
 }
-
+#endif
 #endif
 
 /*
  * Prevent people trying to call kunmap_atomic() as if it were kunmap()
  * kunmap_atomic() should get the return value of kmap_atomic, not the page.
  */
-#define kunmap_atomic(addr)                                     \
-do {                                                            \
-	BUILD_BUG_ON(__same_type((addr), struct page *));       \
-	kunmap_atomic_high(addr);                                  \
-	pagefault_enable();                                     \
-	preempt_enable();                                       \
+#define kunmap_atomic(__addr)					\
+do {								\
+	BUILD_BUG_ON(__same_type((__addr), struct page *));	\
+	__kunmap_atomic(__addr);				\
+	pagefault_enable();					\
+	preempt_enable();					\
 } while (0)
 
-
 /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */
 #ifndef clear_user_highpage
 static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
mm/Kconfig +3 -0
@@ -872,4 +872,7 @@ config ARCH_HAS_HUGEPD
 config MAPPING_DIRTY_HELPERS
         bool
 
+config KMAP_LOCAL
+	bool
+
 endmenu
mm/highmem.c +142 -2

159 lines not on this page · raw message

#14 lore raw

[tip: core/mm] highmem: Provide generic variant of kmap_atomic*

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     298fa1ad5571f59cb3ca5497a9455f36867f065e
Gitweb:        https://git.kernel.org/tip/298fa1ad5571f59cb3ca5497a9455f36867f065e
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:18 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:54 +01:00

highmem: Provide generic variant of kmap_atomic*

The kmap_atomic* interfaces in all architectures are pretty much the same except for post map operations (flush) and pre- and post unmap operations.

Provide a generic variant for that.

---
 include/linux/highmem.h |  82 +++++++++++++++++-----
 mm/Kconfig              |   3 +-
 mm/highmem.c            | 144 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 211 insertions(+), 18 deletions(-)
include/linux/highmem.h +66 -16
index f5c3133..f5ecee9 100644
@@ -31,9 +31,16 @@ static inline void invalidate_kernel_vmap_range(void *vaddr, int size)
 
 #include <asm/kmap_types.h>
 
+/*
+ * Outside of CONFIG_HIGHMEM to support X86 32bit iomap_atomic() cruft.
+ */
+#ifdef CONFIG_KMAP_LOCAL
+void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot);
+void *__kmap_local_page_prot(struct page *page, pgprot_t prot);
+void kunmap_local_indexed(void *vaddr);
+#endif
+
 #ifdef CONFIG_HIGHMEM
-extern void *kmap_atomic_high_prot(struct page *page, pgprot_t prot);
-extern void kunmap_atomic_high(void *kvaddr);
 #include <asm/highmem.h>
 
 #ifndef ARCH_HAS_KMAP_FLUSH_TLB
@@ -81,6 +88,11 @@ static inline void kunmap(struct page *page)
  * be used in IRQ contexts, so in some (very limited) cases we need
  * it.
  */
+
+#ifndef CONFIG_KMAP_LOCAL
+void *kmap_atomic_high_prot(struct page *page, pgprot_t prot);
+void kunmap_atomic_high(void *kvaddr);
+
 static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
 {
 	preempt_disable();
@@ -89,7 +101,38 @@ static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
 		return page_address(page);
 	return kmap_atomic_high_prot(page, prot);
 }
-#define kmap_atomic(page)	kmap_atomic_prot(page, kmap_prot)
+
+static inline void __kunmap_atomic(void *vaddr)
+{
+	kunmap_atomic_high(vaddr);
+}
+#else /* !CONFIG_KMAP_LOCAL */
+
+static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+{
+	preempt_disable();
+	pagefault_disable();
+	return __kmap_local_page_prot(page, prot);
+}
+
+static inline void *kmap_atomic_pfn(unsigned long pfn)
+{
+	preempt_disable();
+	pagefault_disable();
+	return __kmap_local_pfn_prot(pfn, kmap_prot);
+}
+
+static inline void __kunmap_atomic(void *addr)
+{
+	kunmap_local_indexed(addr);
+}
+
+#endif /* CONFIG_KMAP_LOCAL */
+
+static inline void *kmap_atomic(struct page *page)
+{
+	return kmap_atomic_prot(page, kmap_prot);
+}
 
 /* declarations for linux/mm/highmem.c */
 unsigned int nr_free_highpages(void);
@@ -147,25 +190,33 @@ static inline void *kmap_atomic(struct page *page)
 	pagefault_disable();
 	return page_address(page);
 }
-#define kmap_atomic_prot(page, prot)	kmap_atomic(page)
 
-static inline void kunmap_atomic_high(void *addr)
+static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+{
+	return kmap_atomic(page);
+}
+
+static inline void *kmap_atomic_pfn(unsigned long pfn)
+{
+	return kmap_atomic(pfn_to_page(pfn));
+}
+
+static inline void __kunmap_atomic(void *addr)
 {
 	/*
 	 * Mostly nothing to do in the CONFIG_HIGHMEM=n case as kunmap_atomic()
-	 * handles re-enabling faults + preemption
+	 * handles re-enabling faults and preemption
 	 */
 #ifdef ARCH_HAS_FLUSH_ON_KUNMAP
 	kunmap_flush_on_unmap(addr);
 #endif
 }
 
-#define kmap_atomic_pfn(pfn)	kmap_atomic(pfn_to_page(pfn))
-
 #define kmap_flush_unused()	do {} while(0)
 
 #endif /* CONFIG_HIGHMEM */
 
+#if !defined(CONFIG_KMAP_LOCAL)
 #if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32)
 
 DECLARE_PER_CPU(int, __kmap_atomic_idx);
@@ -196,22 +247,21 @@ static inline void kmap_atomic_idx_pop(void)
 	__this_cpu_dec(__kmap_atomic_idx);
 #endif
 }
-
+#endif
 #endif
 
 /*
  * Prevent people trying to call kunmap_atomic() as if it were kunmap()
  * kunmap_atomic() should get the return value of kmap_atomic, not the page.
  */
-#define kunmap_atomic(addr)                                     \
-do {                                                            \
-	BUILD_BUG_ON(__same_type((addr), struct page *));       \
-	kunmap_atomic_high(addr);                                  \
-	pagefault_enable();                                     \
-	preempt_enable();                                       \
+#define kunmap_atomic(__addr)					\
+do {								\
+	BUILD_BUG_ON(__same_type((__addr), struct page *));	\
+	__kunmap_atomic(__addr);				\
+	pagefault_enable();					\
+	preempt_enable();					\
 } while (0)
 
-
 /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */
 #ifndef clear_user_highpage
 static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
mm/Kconfig +3 -0
index d42423f..a1ccf98 100644
@@ -872,4 +872,7 @@ config ARCH_HAS_HUGEPD
 config MAPPING_DIRTY_HELPERS
         bool
 
+config KMAP_LOCAL
+	bool
+
 endmenu
mm/highmem.c +142 -2

160 lines not on this page · raw message

#15 lore raw

PATCH v3 7/37 highmem: Make DEBUG_HIGHMEM functional

In reply to Thomas Gleixner

For some obscure reason when CONFIG_DEBUG_HIGHMEM is enabled the stack depth is increased from 20 to 41. But the only thing DEBUG_HIGHMEM does is to enable a few BUG_ON()'s in the mapping code.

That's a leftover from the historical mapping code which had fixed entries for various purposes. DEBUG_HIGHMEM inserted guard mappings between the map types. But that got all ditched when kmap_atomic() switched to a stack based map management. Though the WITH_KM_FENCE magic survived without being functional. All the thing does today is to increase the stack depth.

Add a working implementation to the generic kmap_local* implementation.

---
V3: New patch

---
 mm/highmem.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
mm/highmem.c +12 -2
@@ -374,9 +374,19 @@ EXPORT_SYMBOL(kunmap_high);
 
 static DEFINE_PER_CPU(int, __kmap_local_idx);
 
+/*
+ * With DEBUG_HIGHMEM the stack depth is doubled and every second
+ * slot is unused which acts as a guard page
+ */
+#ifdef CONFIG_DEBUG_HIGHMEM
+# define KM_INCR	2
+#else
+# define KM_INCR	1
+#endif
+
 static inline int kmap_local_idx_push(void)
 {
-	int idx = __this_cpu_inc_return(__kmap_local_idx) - 1;
+	int idx = __this_cpu_add_return(__kmap_local_idx, KM_INCR) - 1;
 
 	WARN_ON_ONCE(in_irq() && !irqs_disabled());
 	BUG_ON(idx >= KM_MAX_IDX);
@@ -390,7 +400,7 @@ static inline int kmap_local_idx(void)
 
 static inline void kmap_local_idx_pop(void)
 {
-	int idx = __this_cpu_dec_return(__kmap_local_idx);
+	int idx = __this_cpu_sub_return(__kmap_local_idx, KM_INCR);
 
 	BUG_ON(idx < 0);
 }
#16 lore raw

[tip: core/mm] highmem: Make DEBUG_HIGHMEM functional

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     389755c250814185938f5b04334a4f0184c30647
Gitweb:        https://git.kernel.org/tip/389755c250814185938f5b04334a4f0184c30647
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:19 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:55 +01:00

highmem: Make DEBUG_HIGHMEM functional

For some obscure reason when CONFIG_DEBUG_HIGHMEM is enabled the stack depth is increased from 20 to 41. But the only thing DEBUG_HIGHMEM does is to enable a few BUG_ON()'s in the mapping code.

That's a leftover from the historical mapping code which had fixed entries for various purposes. DEBUG_HIGHMEM inserted guard mappings between the map types. But that got all ditched when kmap_atomic() switched to a stack based map management. Though the WITH_KM_FENCE magic survived without being functional. All the thing does today is to increase the stack depth.

Add a working implementation to the generic kmap_local* implementation.

---
 mm/highmem.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
mm/highmem.c +12 -2
index bb4ce13..67d2d59 100644
@@ -376,9 +376,19 @@ EXPORT_SYMBOL(kunmap_high);
 
 static DEFINE_PER_CPU(int, __kmap_local_idx);
 
+/*
+ * With DEBUG_HIGHMEM the stack depth is doubled and every second
+ * slot is unused which acts as a guard page
+ */
+#ifdef CONFIG_DEBUG_HIGHMEM
+# define KM_INCR	2
+#else
+# define KM_INCR	1
+#endif
+
 static inline int kmap_local_idx_push(void)
 {
-	int idx = __this_cpu_inc_return(__kmap_local_idx) - 1;
+	int idx = __this_cpu_add_return(__kmap_local_idx, KM_INCR) - 1;
 
 	WARN_ON_ONCE(in_irq() && !irqs_disabled());
 	BUG_ON(idx >= KM_MAX_IDX);
@@ -392,7 +402,7 @@ static inline int kmap_local_idx(void)
 
 static inline void kmap_local_idx_pop(void)
 {
-	int idx = __this_cpu_dec_return(__kmap_local_idx);
+	int idx = __this_cpu_sub_return(__kmap_local_idx, KM_INCR);
 
 	BUG_ON(idx < 0);
 }
#17 lore raw

PATCH v3 8/37 x86/mm/highmem: Use generic kmap atomic implementation

In reply to Thomas Gleixner

Convert X86 to the generic kmap atomic implementation and make the iomap_atomic() naming convention consistent while at it.

---
V3: Remove the kmap_types cruft

---
 arch/x86/Kconfig                      |    3 +
 arch/x86/include/asm/fixmap.h         |    5 +-
 arch/x86/include/asm/highmem.h        |   13 +++++--
 arch/x86/include/asm/iomap.h          |   18 +++++-----
 arch/x86/include/asm/kmap_types.h     |   13 -------
 arch/x86/include/asm/paravirt_types.h |    1 
 arch/x86/mm/highmem_32.c              |   59 ----------------------------------
 arch/x86/mm/init_32.c                 |   15 --------
 arch/x86/mm/iomap_32.c                |   59 ++--------------------------------
 include/linux/highmem.h               |    2 -
 include/linux/io-mapping.h            |    2 -
 mm/highmem.c                          |    2 -
 12 files changed, 31 insertions(+), 161 deletions(-)
arch/x86/Kconfig +2 -1
@@ -14,10 +14,11 @@ config X86_32
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select CLKSRC_I8253
 	select CLONE_BACKWARDS
+	select GENERIC_VDSO_32
 	select HAVE_DEBUG_STACKOVERFLOW
+	select KMAP_LOCAL
 	select MODULES_USE_ELF_REL
 	select OLD_SIGACTION
-	select GENERIC_VDSO_32
 
 config X86_64
 	def_bool y
arch/x86/include/asm/fixmap.h +2 -3
@@ -31,7 +31,7 @@
 #include <asm/pgtable_types.h>
 #ifdef CONFIG_X86_32
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #else
 #include <uapi/asm/vsyscall.h>
 #endif
@@ -94,7 +94,7 @@ enum fixed_addresses {
 #endif
 #ifdef CONFIG_X86_32
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
-	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 #ifdef CONFIG_PCI_MMCONFIG
 	FIX_PCIE_MCFG,
 #endif
@@ -151,7 +151,6 @@ extern void reserve_top_address(unsigned
 
 extern int fixmaps_set;
 
-extern pte_t *kmap_pte;
 extern pte_t *pkmap_page_table;
 
 void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
arch/x86/include/asm/highmem.h +9 -4
@@ -23,7 +23,6 @@
 
 #include <linux/interrupt.h>
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
 #include <asm/tlbflush.h>
 #include <asm/paravirt.h>
 #include <asm/fixmap.h>
@@ -58,11 +57,17 @@ extern unsigned long highstart_pfn, high
 #define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
 #define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
 
-void *kmap_atomic_pfn(unsigned long pfn);
-void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
-
 #define flush_cache_kmaps()	do { } while (0)
 
+#define	arch_kmap_local_post_map(vaddr, pteval)		\
+	arch_flush_lazy_mmu_mode()
+
+#define	arch_kmap_local_post_unmap(vaddr)		\
+	do {						\
+		flush_tlb_one_kernel((vaddr));		\
+		arch_flush_lazy_mmu_mode();		\
+	} while (0)
+
 extern void add_highpages_with_active_regions(int nid, unsigned long start_pfn,
 					unsigned long end_pfn);
 
arch/x86/include/asm/iomap.h +10 -8
@@ -9,19 +9,21 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
+#include <linux/highmem.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
-void __iomem *
-iomap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
+void __iomem *iomap_atomic_pfn_prot(unsigned long pfn, pgprot_t prot);
 
-void
-iounmap_atomic(void __iomem *kvaddr);
+static inline void iounmap_atomic(void __iomem *vaddr)
+{
+	kunmap_local_indexed((void __force *)vaddr);
+	pagefault_enable();
+	preempt_enable();
+}
 
-int
-iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot);
+int iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot);
 
-void
-iomap_free(resource_size_t base, unsigned long size);
+void iomap_free(resource_size_t base, unsigned long size);
 
 #endif /* _ASM_X86_IOMAP_H */
arch/x86/include/asm/kmap_types.h deleted +0 -13
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_X86_KMAP_TYPES_H
-#define _ASM_X86_KMAP_TYPES_H
-
-#if defined(CONFIG_X86_32) && defined(CONFIG_DEBUG_HIGHMEM)
-#define  __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif /* _ASM_X86_KMAP_TYPES_H */
arch/x86/include/asm/paravirt_types.h +0 -1
@@ -41,7 +41,6 @@
 #ifndef __ASSEMBLY__
 
 #include <asm/desc_defs.h>
-#include <asm/kmap_types.h>
 #include <asm/pgtable_types.h>
 #include <asm/nospec-branch.h>
 
arch/x86/mm/highmem_32.c +0 -59

65 lines not on this page · raw message

arch/x86/mm/init_32.c +0 -15
@@ -394,19 +394,6 @@ kernel_physical_mapping_init(unsigned lo
 	return last_map_addr;
 }
 
-pte_t *kmap_pte;
-
-static void __init kmap_init(void)
-{
-	unsigned long kmap_vstart;
-
-	/*
-	 * Cache the first kmap pte:
-	 */
-	kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
-	kmap_pte = virt_to_kpte(kmap_vstart);
-}
-
 #ifdef CONFIG_HIGHMEM
 static void __init permanent_kmaps_init(pgd_t *pgd_base)
 {
@@ -712,8 +699,6 @@ void __init paging_init(void)
 
 	__flush_tlb_all();
 
-	kmap_init();
-
 	/*
 	 * NOTE: at this point the bootmem allocator is fully available.
 	 */
arch/x86/mm/iomap_32.c +5 -54

69 lines not on this page · raw message

include/linux/highmem.h +1 -1
@@ -217,7 +217,7 @@ static inline void __kunmap_atomic(void
 #endif /* CONFIG_HIGHMEM */
 
 #if !defined(CONFIG_KMAP_LOCAL)
-#if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32)
+#if defined(CONFIG_HIGHMEM)
 
 DECLARE_PER_CPU(int, __kmap_atomic_idx);
 
include/linux/io-mapping.h +1 -1
@@ -69,7 +69,7 @@ io_mapping_map_atomic_wc(struct io_mappi
 
 	BUG_ON(offset >= mapping->size);
 	phys_addr = mapping->base + offset;
-	return iomap_atomic_prot_pfn(PHYS_PFN(phys_addr), mapping->prot);
+	return iomap_atomic_pfn_prot(PHYS_PFN(phys_addr), mapping->prot);
 }
 
 static inline void
mm/highmem.c +1 -1
@@ -32,7 +32,7 @@
 #include <linux/vmalloc.h>
 
 #ifndef CONFIG_KMAP_LOCAL
-#if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32)
+#ifdef CONFIG_HIGHMEM
 DEFINE_PER_CPU(int, __kmap_atomic_idx);
 #endif
 #endif
#18 lore raw

[tip: core/mm] x86/mm/highmem: Use generic kmap atomic implementation

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     157e118b55113d1e6c7f8ddfcec0a1dbf3a69511
Gitweb:        https://git.kernel.org/tip/157e118b55113d1e6c7f8ddfcec0a1dbf3a69511
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:20 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:55 +01:00

x86/mm/highmem: Use generic kmap atomic implementation

Convert X86 to the generic kmap atomic implementation and make the iomap_atomic() naming convention consistent while at it.

---
 arch/x86/Kconfig                      |  3 +-
 arch/x86/include/asm/fixmap.h         |  5 +--
 arch/x86/include/asm/highmem.h        | 13 ++++--
 arch/x86/include/asm/iomap.h          | 18 ++++----
 arch/x86/include/asm/kmap_types.h     | 13 +------
 arch/x86/include/asm/paravirt_types.h |  1 +-
 arch/x86/mm/highmem_32.c              | 59 +--------------------------
 arch/x86/mm/init_32.c                 | 15 +-------
 arch/x86/mm/iomap_32.c                | 59 ++------------------------
 include/linux/highmem.h               |  2 +-
 include/linux/io-mapping.h            |  2 +-
 mm/highmem.c                          |  2 +-
 12 files changed, 31 insertions(+), 161 deletions(-)
 delete mode 100644 arch/x86/include/asm/kmap_types.h
arch/x86/Kconfig +2 -1
index f6946b8..33c273c 100644
@@ -14,10 +14,11 @@ config X86_32
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select CLKSRC_I8253
 	select CLONE_BACKWARDS
+	select GENERIC_VDSO_32
 	select HAVE_DEBUG_STACKOVERFLOW
+	select KMAP_LOCAL
 	select MODULES_USE_ELF_REL
 	select OLD_SIGACTION
-	select GENERIC_VDSO_32
 
 config X86_64
 	def_bool y
arch/x86/include/asm/fixmap.h +2 -3
index 77217bd..8eba66a 100644
@@ -31,7 +31,7 @@
 #include <asm/pgtable_types.h>
 #ifdef CONFIG_X86_32
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #else
 #include <uapi/asm/vsyscall.h>
 #endif
@@ -94,7 +94,7 @@ enum fixed_addresses {
 #endif
 #ifdef CONFIG_X86_32
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
-	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 #ifdef CONFIG_PCI_MMCONFIG
 	FIX_PCIE_MCFG,
 #endif
@@ -151,7 +151,6 @@ extern void reserve_top_address(unsigned long reserve);
 
 extern int fixmaps_set;
 
-extern pte_t *kmap_pte;
 extern pte_t *pkmap_page_table;
 
 void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
arch/x86/include/asm/highmem.h +9 -4
index 0f420b2..032e020 100644
@@ -23,7 +23,6 @@
 
 #include <linux/interrupt.h>
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
 #include <asm/tlbflush.h>
 #include <asm/paravirt.h>
 #include <asm/fixmap.h>
@@ -58,11 +57,17 @@ extern unsigned long highstart_pfn, highend_pfn;
 #define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
 #define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
 
-void *kmap_atomic_pfn(unsigned long pfn);
-void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
-
 #define flush_cache_kmaps()	do { } while (0)
 
+#define	arch_kmap_local_post_map(vaddr, pteval)		\
+	arch_flush_lazy_mmu_mode()
+
+#define	arch_kmap_local_post_unmap(vaddr)		\
+	do {						\
+		flush_tlb_one_kernel((vaddr));		\
+		arch_flush_lazy_mmu_mode();		\
+	} while (0)
+
 extern void add_highpages_with_active_regions(int nid, unsigned long start_pfn,
 					unsigned long end_pfn);
 
arch/x86/include/asm/iomap.h +10 -8
index bacf68c..0be7a30 100644
@@ -9,19 +9,21 @@
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
+#include <linux/highmem.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
-void __iomem *
-iomap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
+void __iomem *iomap_atomic_pfn_prot(unsigned long pfn, pgprot_t prot);
 
-void
-iounmap_atomic(void __iomem *kvaddr);
+static inline void iounmap_atomic(void __iomem *vaddr)
+{
+	kunmap_local_indexed((void __force *)vaddr);
+	pagefault_enable();
+	preempt_enable();
+}
 
-int
-iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot);
+int iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot);
 
-void
-iomap_free(resource_size_t base, unsigned long size);
+void iomap_free(resource_size_t base, unsigned long size);
 
 #endif /* _ASM_X86_IOMAP_H */
arch/x86/include/asm/kmap_types.h deleted +0 -13
deleted file mode 100644
index 04ab826..0000000
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_X86_KMAP_TYPES_H
-#define _ASM_X86_KMAP_TYPES_H
-
-#if defined(CONFIG_X86_32) && defined(CONFIG_DEBUG_HIGHMEM)
-#define  __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif /* _ASM_X86_KMAP_TYPES_H */
arch/x86/include/asm/paravirt_types.h +0 -1
index 0fad9f6..b6b02b7 100644
@@ -41,7 +41,6 @@
 #ifndef __ASSEMBLY__
 
 #include <asm/desc_defs.h>
-#include <asm/kmap_types.h>
 #include <asm/pgtable_types.h>
 #include <asm/nospec-branch.h>
 
arch/x86/mm/highmem_32.c +0 -59

65 lines not on this page · raw message

arch/x86/mm/init_32.c +0 -15
index 7c05525..da31c26 100644
@@ -394,19 +394,6 @@ repeat:
 	return last_map_addr;
 }
 
-pte_t *kmap_pte;
-
-static void __init kmap_init(void)
-{
-	unsigned long kmap_vstart;
-
-	/*
-	 * Cache the first kmap pte:
-	 */
-	kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
-	kmap_pte = virt_to_kpte(kmap_vstart);
-}
-
 #ifdef CONFIG_HIGHMEM
 static void __init permanent_kmaps_init(pgd_t *pgd_base)
 {
@@ -712,8 +699,6 @@ void __init paging_init(void)
 
 	__flush_tlb_all();
 
-	kmap_init();
-
 	/*
 	 * NOTE: at this point the bootmem allocator is fully available.
 	 */
arch/x86/mm/iomap_32.c +5 -54

69 lines not on this page · raw message

include/linux/highmem.h +1 -1
index f5ecee9..1222a31 100644
@@ -217,7 +217,7 @@ static inline void __kunmap_atomic(void *addr)
 #endif /* CONFIG_HIGHMEM */
 
 #if !defined(CONFIG_KMAP_LOCAL)
-#if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32)
+#if defined(CONFIG_HIGHMEM)
 
 DECLARE_PER_CPU(int, __kmap_atomic_idx);
 
include/linux/io-mapping.h +1 -1
index c75e4d3..3b0940b 100644
@@ -69,7 +69,7 @@ io_mapping_map_atomic_wc(struct io_mapping *mapping,
 
 	BUG_ON(offset >= mapping->size);
 	phys_addr = mapping->base + offset;
-	return iomap_atomic_prot_pfn(PHYS_PFN(phys_addr), mapping->prot);
+	return iomap_atomic_pfn_prot(PHYS_PFN(phys_addr), mapping->prot);
 }
 
 static inline void
mm/highmem.c +1 -1
index 67d2d59..77677c6 100644
@@ -32,7 +32,7 @@
 #include <linux/vmalloc.h>
 
 #ifndef CONFIG_KMAP_LOCAL
-#if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32)
+#ifdef CONFIG_HIGHMEM
 DEFINE_PER_CPU(int, __kmap_atomic_idx);
 #endif
 #endif
#19 lore raw

PATCH v3 9/37 arc/mm/highmem: Use generic kmap atomic implementation

In reply to Thomas Gleixner

Adopt the map ordering to match the other architectures and the generic code. Also make the maximum entries limited and not dependend on the number of CPUs. With the original implementation did the following calculation:

   nr_slots = mapsize >> PAGE_SHIFT;

The results in either 512 or 1024 total slots depending on configuration. The total slots have to be divided by the number of CPUs to get the number of slots per CPU (former KM_TYPE_NR). ARC supports up to 4k CPUs, so this just falls apart in random ways depending on the number of CPUs and the actual kmap (atomic) nesting. The comment in highmem.c:

* - fixmap anyhow needs a limited number of mappings. So 2M kvaddr == 256 PTE
* slots across NR_CPUS would be more than sufficient (generic code defines
* KM_TYPE_NR as 20).

is just wrong. KM_TYPE_NR (now KM_MAX_IDX) is the number of slots per CPU because kmap_local/atomic() needs to support nested mappings (thread, softirq, interrupt). While KM_MAX_IDX might be overestimated, the above reasoning is just wrong and clearly the highmem code was never tested with any system with more than a few CPUs.

Use the default number of slots and fail the build when it does not fit. Randomly failing at runtime is not a really good option.

---
V3: Make it actually more correct.

---
 arch/arc/Kconfig                  |    1 
 arch/arc/include/asm/highmem.h    |   26 ++++++++++++++----
 arch/arc/include/asm/kmap_types.h |   14 ---------
 arch/arc/mm/highmem.c             |   54 +++-----------------------------------
 4 files changed, 26 insertions(+), 69 deletions(-)
arch/arc/Kconfig +1 -0
@@ -507,6 +507,7 @@ config LINUX_RAM_BASE
 config HIGHMEM
 	bool "High Memory Support"
 	select ARCH_DISCONTIGMEM_ENABLE
+	select KMAP_LOCAL
 	help
 	  With ARC 2G:2G address split, only upper 2G is directly addressable by
 	  kernel. Enable this to potentially allow access to rest of 2G and PAE
arch/arc/include/asm/highmem.h +20 -6
@@ -9,17 +9,29 @@
 #ifdef CONFIG_HIGHMEM
 
 #include <uapi/asm/page.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
+
+#define FIXMAP_SIZE		PGDIR_SIZE
+#define PKMAP_SIZE		PGDIR_SIZE
 
 /* start after vmalloc area */
 #define FIXMAP_BASE		(PAGE_OFFSET - FIXMAP_SIZE - PKMAP_SIZE)
-#define FIXMAP_SIZE		PGDIR_SIZE	/* only 1 PGD worth */
-#define KM_TYPE_NR		((FIXMAP_SIZE >> PAGE_SHIFT)/NR_CPUS)
-#define FIXMAP_ADDR(nr)		(FIXMAP_BASE + ((nr) << PAGE_SHIFT))
+
+#define FIX_KMAP_SLOTS		(KM_MAX_IDX * NR_CPUS)
+#define FIX_KMAP_BEGIN		(0UL)
+#define FIX_KMAP_END		((FIX_KMAP_BEGIN + FIX_KMAP_SLOTS) - 1)
+
+#define FIXADDR_TOP		(FIXMAP_BASE + (FIX_KMAP_END << PAGE_SHIFT))
+
+/*
+ * This should be converted to the asm-generic version, but of course this
+ * is needlessly different from all other architectures. Sigh - tglx
+ */
+#define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x)	(((FIXADDR_TOP - ((x) & PAGE_MASK))) >> PAGE_SHIFT)
 
 /* start after fixmap area */
 #define PKMAP_BASE		(FIXMAP_BASE + FIXMAP_SIZE)
-#define PKMAP_SIZE		PGDIR_SIZE
 #define LAST_PKMAP		(PKMAP_SIZE >> PAGE_SHIFT)
 #define LAST_PKMAP_MASK		(LAST_PKMAP - 1)
 #define PKMAP_ADDR(nr)		(PKMAP_BASE + ((nr) << PAGE_SHIFT))
@@ -29,11 +41,13 @@
 
 extern void kmap_init(void);
 
+#define arch_kmap_local_post_unmap(vaddr)			\
+	local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE)
+
 static inline void flush_cache_kmaps(void)
 {
 	flush_cache_all();
 }
-
 #endif
 
 #endif
arch/arc/include/asm/kmap_types.h deleted +0 -14
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com)
- */
-
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-/*
- * We primarily need to define KM_TYPE_NR here but that in turn
- * is a function of PGDIR_SIZE etc.
- * To avoid circular deps issue, put everything in asm/highmem.h
- */
-#endif
arch/arc/mm/highmem.c +5 -49

72 lines not on this page · raw message

#20 lore raw

[tip: core/mm] arc/mm/highmem: Use generic kmap atomic implementation

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     39cac191ff37939544af80d5d2af6b870fd94c9b
Gitweb:        https://git.kernel.org/tip/39cac191ff37939544af80d5d2af6b870fd94c9b
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:21 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:55 +01:00

arc/mm/highmem: Use generic kmap atomic implementation

Adopt the map ordering to match the other architectures and the generic code. Also make the maximum entries limited and not dependend on the number of CPUs. With the original implementation did the following calculation:

   nr_slots = mapsize >> PAGE_SHIFT;

The results in either 512 or 1024 total slots depending on configuration. The total slots have to be divided by the number of CPUs to get the number of slots per CPU (former KM_TYPE_NR). ARC supports up to 4k CPUs, so this just falls apart in random ways depending on the number of CPUs and the actual kmap (atomic) nesting. The comment in highmem.c:

* - fixmap anyhow needs a limited number of mappings. So 2M kvaddr == 256 PTE
* slots across NR_CPUS would be more than sufficient (generic code defines
* KM_TYPE_NR as 20).

is just wrong. KM_TYPE_NR (now KM_MAX_IDX) is the number of slots per CPU because kmap_local/atomic() needs to support nested mappings (thread, softirq, interrupt). While KM_MAX_IDX might be overestimated, the above reasoning is just wrong and clearly the highmem code was never tested with any system with more than a few CPUs.

Use the default number of slots and fail the build when it does not fit. Randomly failing at runtime is not a really good option.

---
 arch/arc/Kconfig                  |  1 +-
 arch/arc/include/asm/highmem.h    | 26 ++++++++++----
 arch/arc/include/asm/kmap_types.h | 14 +--------
 arch/arc/mm/highmem.c             | 54 ++----------------------------
 4 files changed, 26 insertions(+), 69 deletions(-)
 delete mode 100644 arch/arc/include/asm/kmap_types.h
arch/arc/Kconfig +1 -0
index 0a89cc9..d880400 100644
@@ -507,6 +507,7 @@ config LINUX_RAM_BASE
 config HIGHMEM
 	bool "High Memory Support"
 	select ARCH_DISCONTIGMEM_ENABLE
+	select KMAP_LOCAL
 	help
 	  With ARC 2G:2G address split, only upper 2G is directly addressable by
 	  kernel. Enable this to potentially allow access to rest of 2G and PAE
arch/arc/include/asm/highmem.h +20 -6
index 6e5eafb..a6b8e2c 100644
@@ -9,17 +9,29 @@
 #ifdef CONFIG_HIGHMEM
 
 #include <uapi/asm/page.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
+
+#define FIXMAP_SIZE		PGDIR_SIZE
+#define PKMAP_SIZE		PGDIR_SIZE
 
 /* start after vmalloc area */
 #define FIXMAP_BASE		(PAGE_OFFSET - FIXMAP_SIZE - PKMAP_SIZE)
-#define FIXMAP_SIZE		PGDIR_SIZE	/* only 1 PGD worth */
-#define KM_TYPE_NR		((FIXMAP_SIZE >> PAGE_SHIFT)/NR_CPUS)
-#define FIXMAP_ADDR(nr)		(FIXMAP_BASE + ((nr) << PAGE_SHIFT))
+
+#define FIX_KMAP_SLOTS		(KM_MAX_IDX * NR_CPUS)
+#define FIX_KMAP_BEGIN		(0UL)
+#define FIX_KMAP_END		((FIX_KMAP_BEGIN + FIX_KMAP_SLOTS) - 1)
+
+#define FIXADDR_TOP		(FIXMAP_BASE + (FIX_KMAP_END << PAGE_SHIFT))
+
+/*
+ * This should be converted to the asm-generic version, but of course this
+ * is needlessly different from all other architectures. Sigh - tglx
+ */
+#define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x)	(((FIXADDR_TOP - ((x) & PAGE_MASK))) >> PAGE_SHIFT)
 
 /* start after fixmap area */
 #define PKMAP_BASE		(FIXMAP_BASE + FIXMAP_SIZE)
-#define PKMAP_SIZE		PGDIR_SIZE
 #define LAST_PKMAP		(PKMAP_SIZE >> PAGE_SHIFT)
 #define LAST_PKMAP_MASK		(LAST_PKMAP - 1)
 #define PKMAP_ADDR(nr)		(PKMAP_BASE + ((nr) << PAGE_SHIFT))
@@ -29,11 +41,13 @@
 
 extern void kmap_init(void);
 
+#define arch_kmap_local_post_unmap(vaddr)			\
+	local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE)
+
 static inline void flush_cache_kmaps(void)
 {
 	flush_cache_all();
 }
-
 #endif
 
 #endif
arch/arc/include/asm/kmap_types.h deleted +0 -14
deleted file mode 100644
index fecf785..0000000
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com)
- */
-
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-/*
- * We primarily need to define KM_TYPE_NR here but that in turn
- * is a function of PGDIR_SIZE etc.
- * To avoid circular deps issue, put everything in asm/highmem.h
- */
-#endif
arch/arc/mm/highmem.c +5 -49

72 lines not on this page · raw message

#21 lore raw

PATCH v3 10/37 ARM: highmem: Switch to generic kmap atomic

In reply to Thomas Gleixner

No reason having the same code in every architecture.

---
V3: Remove the kmap types cruft

---
 arch/arm/Kconfig                  |    1 
 arch/arm/include/asm/fixmap.h     |    4 -
 arch/arm/include/asm/highmem.h    |   33 +++++++---
 arch/arm/include/asm/kmap_types.h |   10 ---
 arch/arm/mm/Makefile              |    1 
 arch/arm/mm/highmem.c             |  121 --------------------------------------
 6 files changed, 26 insertions(+), 144 deletions(-)
arch/arm/Kconfig +1 -0
@@ -1498,6 +1498,7 @@ config HAVE_ARCH_PFN_VALID
 config HIGHMEM
 	bool "High Memory Support"
 	depends on MMU
+	select KMAP_LOCAL
 	help
 	  The address space of ARM processors is only 4 Gigabytes large
 	  and it has to accommodate user address space, kernel address
arch/arm/include/asm/fixmap.h +2 -2
@@ -7,14 +7,14 @@
 #define FIXADDR_TOP		(FIXADDR_END - PAGE_SIZE)
 
 #include <linux/pgtable.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 
 enum fixed_addresses {
 	FIX_EARLYCON_MEM_BASE,
 	__end_of_permanent_fixed_addresses,
 
 	FIX_KMAP_BEGIN = __end_of_permanent_fixed_addresses,
-	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 
 	/* Support writing RO kernel text via kprobes, jump labels, etc. */
 	FIX_TEXT_POKE0,
arch/arm/include/asm/highmem.h +23 -10
@@ -2,7 +2,7 @@
 #ifndef _ASM_HIGHMEM_H
 #define _ASM_HIGHMEM_H
 
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 
 #define PKMAP_BASE		(PAGE_OFFSET - PMD_SIZE)
 #define LAST_PKMAP		PTRS_PER_PTE
@@ -46,19 +46,32 @@ extern pte_t *pkmap_page_table;
 
 #ifdef ARCH_NEEDS_KMAP_HIGH_GET
 extern void *kmap_high_get(struct page *page);
-#else
+
+static inline void *arch_kmap_local_high_get(struct page *page)
+{
+	if (IS_ENABLED(CONFIG_DEBUG_HIGHMEM) && !cache_is_vivt())
+		return NULL;
+	return kmap_high_get(page);
+}
+#define arch_kmap_local_high_get arch_kmap_local_high_get
+
+#else /* ARCH_NEEDS_KMAP_HIGH_GET */
 static inline void *kmap_high_get(struct page *page)
 {
 	return NULL;
 }
-#endif
+#endif /* !ARCH_NEEDS_KMAP_HIGH_GET */
 
-/*
- * The following functions are already defined by <linux/highmem.h>
- * when CONFIG_HIGHMEM is not set.
- */
-#ifdef CONFIG_HIGHMEM
-extern void *kmap_atomic_pfn(unsigned long pfn);
-#endif
+#define arch_kmap_local_post_map(vaddr, pteval)				\
+	local_flush_tlb_kernel_page(vaddr)
+
+#define arch_kmap_local_pre_unmap(vaddr)				\
+do {									\
+	if (cache_is_vivt())						\
+		__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);	\
+} while (0)
+
+#define arch_kmap_local_post_unmap(vaddr)				\
+	local_flush_tlb_kernel_page(vaddr)
 
 #endif
arch/arm/include/asm/kmap_types.h deleted +0 -10
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ARM_KMAP_TYPES_H
-#define __ARM_KMAP_TYPES_H
-
-/*
- * This is the "bare minimum".  AIO seems to require this.
- */
-#define KM_TYPE_NR 16
-
-#endif
arch/arm/mm/Makefile +0 -1
@@ -19,7 +19,6 @@ obj-$(CONFIG_MODULES)		+= proc-syms.o
 obj-$(CONFIG_DEBUG_VIRTUAL)	+= physaddr.o
 
 obj-$(CONFIG_ALIGNMENT_TRAP)	+= alignment.o
-obj-$(CONFIG_HIGHMEM)		+= highmem.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_ARM_PV_FIXUP)	+= pv-fixup-asm.o
 
arch/arm/mm/highmem.c deleted +0 -121

121 lines not on this page · raw message

#22 lore raw

[tip: core/mm] ARM: highmem: Switch to generic kmap atomic

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     2a15ba82fa6ca3f35502b3060f22118a938d2889
Gitweb:        https://git.kernel.org/tip/2a15ba82fa6ca3f35502b3060f22118a938d2889
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:22 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:56 +01:00

ARM: highmem: Switch to generic kmap atomic

No reason having the same code in every architecture.

---
 arch/arm/Kconfig                  |   1 +-
 arch/arm/include/asm/fixmap.h     |   4 +-
 arch/arm/include/asm/highmem.h    |  33 +++++---
 arch/arm/include/asm/kmap_types.h |  10 +--
 arch/arm/mm/Makefile              |   1 +-
 arch/arm/mm/highmem.c             | 121 +-----------------------------
 6 files changed, 26 insertions(+), 144 deletions(-)
 delete mode 100644 arch/arm/include/asm/kmap_types.h
 delete mode 100644 arch/arm/mm/highmem.c
arch/arm/Kconfig +1 -0
index fe2f17e..46f8900 100644
@@ -1498,6 +1498,7 @@ config HAVE_ARCH_PFN_VALID
 config HIGHMEM
 	bool "High Memory Support"
 	depends on MMU
+	select KMAP_LOCAL
 	help
 	  The address space of ARM processors is only 4 Gigabytes large
 	  and it has to accommodate user address space, kernel address
arch/arm/include/asm/fixmap.h +2 -2
index fc56fc3..c279a8a 100644
@@ -7,14 +7,14 @@
 #define FIXADDR_TOP		(FIXADDR_END - PAGE_SIZE)
 
 #include <linux/pgtable.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 
 enum fixed_addresses {
 	FIX_EARLYCON_MEM_BASE,
 	__end_of_permanent_fixed_addresses,
 
 	FIX_KMAP_BEGIN = __end_of_permanent_fixed_addresses,
-	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 
 	/* Support writing RO kernel text via kprobes, jump labels, etc. */
 	FIX_TEXT_POKE0,
arch/arm/include/asm/highmem.h +23 -10
index 31811be..a41de52 100644
@@ -2,7 +2,7 @@
 #ifndef _ASM_HIGHMEM_H
 #define _ASM_HIGHMEM_H
 
-#include <asm/kmap_types.h>
+#include <asm/fixmap.h>
 
 #define PKMAP_BASE		(PAGE_OFFSET - PMD_SIZE)
 #define LAST_PKMAP		PTRS_PER_PTE
@@ -46,19 +46,32 @@ extern pte_t *pkmap_page_table;
 
 #ifdef ARCH_NEEDS_KMAP_HIGH_GET
 extern void *kmap_high_get(struct page *page);
-#else
+
+static inline void *arch_kmap_local_high_get(struct page *page)
+{
+	if (IS_ENABLED(CONFIG_DEBUG_HIGHMEM) && !cache_is_vivt())
+		return NULL;
+	return kmap_high_get(page);
+}
+#define arch_kmap_local_high_get arch_kmap_local_high_get
+
+#else /* ARCH_NEEDS_KMAP_HIGH_GET */
 static inline void *kmap_high_get(struct page *page)
 {
 	return NULL;
 }
-#endif
+#endif /* !ARCH_NEEDS_KMAP_HIGH_GET */
 
-/*
- * The following functions are already defined by <linux/highmem.h>
- * when CONFIG_HIGHMEM is not set.
- */
-#ifdef CONFIG_HIGHMEM
-extern void *kmap_atomic_pfn(unsigned long pfn);
-#endif
+#define arch_kmap_local_post_map(vaddr, pteval)				\
+	local_flush_tlb_kernel_page(vaddr)
+
+#define arch_kmap_local_pre_unmap(vaddr)				\
+do {									\
+	if (cache_is_vivt())						\
+		__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);	\
+} while (0)
+
+#define arch_kmap_local_post_unmap(vaddr)				\
+	local_flush_tlb_kernel_page(vaddr)
 
 #endif
arch/arm/include/asm/kmap_types.h deleted +0 -10
deleted file mode 100644
index 5590940..0000000
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ARM_KMAP_TYPES_H
-#define __ARM_KMAP_TYPES_H
-
-/*
- * This is the "bare minimum".  AIO seems to require this.
- */
-#define KM_TYPE_NR 16
-
-#endif
arch/arm/mm/Makefile +0 -1
index 7cb1699..c4ce477 100644
@@ -19,7 +19,6 @@ obj-$(CONFIG_MODULES)		+= proc-syms.o
 obj-$(CONFIG_DEBUG_VIRTUAL)	+= physaddr.o
 
 obj-$(CONFIG_ALIGNMENT_TRAP)	+= alignment.o
-obj-$(CONFIG_HIGHMEM)		+= highmem.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_ARM_PV_FIXUP)	+= pv-fixup-asm.o
 
arch/arm/mm/highmem.c deleted +0 -121

121 lines not on this page · raw message

#23 lore raw

Re: [patch V3 10/37] ARM: highmem: Switch to generic kmap atomic

In reply to Thomas Gleixner

Hi Thomas,

Quoted 6 lines · Thomas Gleixner

No reason having the same code in every architecture.

This patch landed in linux-next 20201109 as commit 2a15ba82fa6c ("ARM:
highmem: Switch to generic kmap atomic"). However it causes a following warning on my test boards (Samsung Exynos SoC based):

Run /sbin/init as init process
INIT: version 2.88 booting

------------[ cut here ]------------
WARNING: CPU: 3 PID: 120 at mm/highmem.c:502 
kunmap_local_indexed+0x194/0x1d0
Modules linked in:
CPU: 3 PID: 120 Comm: init Not tainted 5.10.0-rc2-00010-g2a15ba82fa6c #1924
Hardware name: Samsung Exynos (Flattened Device Tree)
[<c0111514>] (unwind_backtrace) from [<c010ceb8>] (show_stack+0x10/0x14)
[<c010ceb8>] (show_stack) from [<c0b1b408>] (dump_stack+0xb4/0xd4)
[<c0b1b408>] (dump_stack) from [<c0126988>] (__warn+0x98/0x104)
[<c0126988>] (__warn) from [<c0126aa4>] (warn_slowpath_fmt+0xb0/0xb8)

[<c0126aa4>] (warn_slowpath_fmt) from [<c028e22c>] (kunmap_local_indexed+0x194/0x1d0)
[<c028e22c>] (kunmap_local_indexed) from [<c02d37f4>] (remove_arg_zero+0xa0/0x158)
[<c02d37f4>] (remove_arg_zero) from [<c034cfc8>] (load_script+0x250/0x318) [<c034cfc8>] (load_script) from [<c02d2f7c>] (bprm_execve+0x3d0/0x930) [<c02d2f7c>] (bprm_execve) from [<c02d3dc8>] (do_execveat_common+0x174/0x184)
[<c02d3dc8>] (do_execveat_common) from [<c02d4cec>] (sys_execve+0x30/0x38) [<c02d4cec>] (sys_execve) from [<c0100060>] (ret_fast_syscall+0x0/0x28)

Exception stack(0xc4561fa8 to 0xc4561ff0)

1fa0:                   b6f2bab8 bef7dac4 bef7dac4 bef7d8fc 004b9b58 bef7dac8
1fc0: b6f2bab8 bef7dac4 bef7d8fc 0000000b 004b8000 004bac44 bef7da3c bef7d8dc
1fe0: 0000002f bef7d89c b6d6dc74 b6d6d65c

irq event stamp: 1283
hardirqs last  enabled at (1293): [<c019f564>] console_unlock+0x430/0x6b0
hardirqs last disabled at (1302): [<c019f55c>] console_unlock+0x428/0x6b0
softirqs last  enabled at (1282): [<c0101768>] __do_softirq+0x528/0x674
softirqs last disabled at (1269): [<c012fed4>] irq_exit+0x1dc/0x1e8
---[ end trace 6f32a2fb4294655f ]---

I can do more tests to help fixing this issue. Just let me know what to do.

...

Best regards

Signature · 2 lines
Marek Szyprowski, PhD
Samsung R&D Institute Poland
#24 lore raw

Re: [patch V3 10/37] ARM: highmem: Switch to generic kmap atomic

Marek,

Quoted 3 lines · Marek Szyprowski

On 03.11.2020 10:27, Thomas Gleixner wrote:

I can do more tests to help fixing this issue. Just let me know what to do.

Just sent out the fix before I saw your report.

     https://lore.kernel.org/r/[email protected]

Thanks,

tglx

--
To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"[email protected]">[email protected]</a>

#25 lore raw

Re: [patch V3 10/37] ARM: highmem: Switch to generic kmap atomic

In reply to Marek Szyprowski
Quoted 1 line · Marek Szyprowski

I can do more tests to help fixing this issue. Just let me know what to do.

-> https://lkml.kernel.org/r/[email protected]

Sebastian

--
To unsubscribe, send a message with 'unsubscribe linux-aio' in the body to [email protected]. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"[email protected]">[email protected]</a>

#26 lore raw

PATCH v3 11/37 csky/mm/highmem: Switch to generic kmap atomic

In reply to Thomas Gleixner

No reason having the same code in every architecture.

---
V3: Does not compile with gcc 10

---
 arch/csky/Kconfig               |    1 
 arch/csky/include/asm/fixmap.h  |    4 +-
 arch/csky/include/asm/highmem.h |    6 ++-
 arch/csky/mm/highmem.c          |   75 ----------------------------------------
 4 files changed, 8 insertions(+), 78 deletions(-)
arch/csky/Kconfig +1 -0
@@ -286,6 +286,7 @@ config NR_CPUS
 config HIGHMEM
 	bool "High Memory Support"
 	depends on !CPU_CK610
+	select KMAP_LOCAL
 	default y
 
 config FORCE_MAX_ZONEORDER
arch/csky/include/asm/fixmap.h +2 -2
@@ -8,7 +8,7 @@
 #include <asm/memory.h>
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 enum fixed_addresses {
@@ -17,7 +17,7 @@ enum fixed_addresses {
 #endif
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,
-	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 #endif
 	__end_of_fixed_addresses
 };
arch/csky/include/asm/highmem.h +4 -2
@@ -9,7 +9,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #include <asm/cache.h>
 
 /* undef for production */
@@ -32,10 +32,12 @@ extern pte_t *pkmap_page_table;
 
 #define ARCH_HAS_KMAP_FLUSH_TLB
 extern void kmap_flush_tlb(unsigned long addr);
-extern void *kmap_atomic_pfn(unsigned long pfn);
 
 #define flush_cache_kmaps() do {} while (0)
 
+#define arch_kmap_local_post_map(vaddr, pteval)	kmap_flush_tlb(vaddr)
+#define arch_kmap_local_post_unmap(vaddr)	kmap_flush_tlb(vaddr)
+
 extern void kmap_init(void);
 
 #endif /* __KERNEL__ */
arch/csky/mm/highmem.c +1 -74

90 lines not on this page · raw message

#27 lore raw

[tip: core/mm] csky/mm/highmem: Switch to generic kmap atomic

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     5af627a043e39d3226eecd75753dcd2c920c16ec
Gitweb:        https://git.kernel.org/tip/5af627a043e39d3226eecd75753dcd2c920c16ec
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:23 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:56 +01:00

csky/mm/highmem: Switch to generic kmap atomic

No reason having the same code in every architecture.

---
 arch/csky/Kconfig               |  1 +-
 arch/csky/include/asm/fixmap.h  |  4 +-
 arch/csky/include/asm/highmem.h |  6 ++-
 arch/csky/mm/highmem.c          | 75 +--------------------------------
 4 files changed, 8 insertions(+), 78 deletions(-)
arch/csky/Kconfig +1 -0
index 268fad5..7a86481 100644
@@ -286,6 +286,7 @@ config NR_CPUS
 config HIGHMEM
 	bool "High Memory Support"
 	depends on !CPU_CK610
+	select KMAP_LOCAL
 	default y
 
 config FORCE_MAX_ZONEORDER
arch/csky/include/asm/fixmap.h +2 -2
index 81f9477..4b589cc 100644
@@ -8,7 +8,7 @@
 #include <asm/memory.h>
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 enum fixed_addresses {
@@ -17,7 +17,7 @@ enum fixed_addresses {
 #endif
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,
-	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 #endif
 	__end_of_fixed_addresses
 };
arch/csky/include/asm/highmem.h +4 -2
index 14645e3..1f4ed3f 100644
@@ -9,7 +9,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #include <asm/cache.h>
 
 /* undef for production */
@@ -32,10 +32,12 @@ extern pte_t *pkmap_page_table;
 
 #define ARCH_HAS_KMAP_FLUSH_TLB
 extern void kmap_flush_tlb(unsigned long addr);
-extern void *kmap_atomic_pfn(unsigned long pfn);
 
 #define flush_cache_kmaps() do {} while (0)
 
+#define arch_kmap_local_post_map(vaddr, pteval)	kmap_flush_tlb(vaddr)
+#define arch_kmap_local_post_unmap(vaddr)	kmap_flush_tlb(vaddr)
+
 extern void kmap_init(void);
 
 #endif /* __KERNEL__ */
arch/csky/mm/highmem.c +1 -74

90 lines not on this page · raw message

#28 lore raw

PATCH v3 12/37 microblaze/mm/highmem: Switch to generic kmap atomic

In reply to Thomas Gleixner

No reason having the same code in every architecture.

---
V3: Remove the kmap types cruft

---
 arch/microblaze/Kconfig               |    1 
 arch/microblaze/include/asm/fixmap.h  |    4 -
 arch/microblaze/include/asm/highmem.h |    6 ++
 arch/microblaze/mm/Makefile           |    1 
 arch/microblaze/mm/highmem.c          |   78 ----------------------------------
 arch/microblaze/mm/init.c             |    6 --
 6 files changed, 8 insertions(+), 88 deletions(-)
arch/microblaze/Kconfig +1 -0
@@ -155,6 +155,7 @@ config XILINX_UNCACHED_SHADOW
 config HIGHMEM
 	bool "High memory support"
 	depends on MMU
+	select KMAP_LOCAL
 	help
 	  The address space of Microblaze processors is only 4 Gigabytes large
 	  and it has to accommodate user address space, kernel address
arch/microblaze/include/asm/fixmap.h +2 -2
@@ -20,7 +20,7 @@
 #include <asm/page.h>
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 #define FIXADDR_TOP	((unsigned long)(-PAGE_SIZE))
@@ -47,7 +47,7 @@ enum fixed_addresses {
 	FIX_HOLE,
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
-	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * num_possible_cpus()) - 1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * num_possible_cpus()) - 1,
 #endif
 	__end_of_fixed_addresses
 };
arch/microblaze/include/asm/highmem.h +5 -1
@@ -25,7 +25,6 @@
 #include <linux/uaccess.h>
 #include <asm/fixmap.h>
 
-extern pte_t *kmap_pte;
 extern pte_t *pkmap_page_table;
 
 /*
@@ -52,6 +51,11 @@ extern pte_t *pkmap_page_table;
 
 #define flush_cache_kmaps()	{ flush_icache(); flush_dcache(); }
 
+#define arch_kmap_local_post_map(vaddr, pteval)	\
+	local_flush_tlb_page(NULL, vaddr);
+#define arch_kmap_local_post_unmap(vaddr)	\
+	local_flush_tlb_page(NULL, vaddr);
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_HIGHMEM_H */
arch/microblaze/mm/Makefile +0 -1
@@ -6,4 +6,3 @@
 obj-y := consistent.o init.o
 
 obj-$(CONFIG_MMU) += pgtable.o mmu_context.o fault.o
-obj-$(CONFIG_HIGHMEM) += highmem.o
arch/microblaze/mm/highmem.c deleted +0 -78

78 lines not on this page · raw message

arch/microblaze/mm/init.c +0 -6
@@ -49,17 +49,11 @@ unsigned long lowmem_size;
 EXPORT_SYMBOL(min_low_pfn);
 EXPORT_SYMBOL(max_low_pfn);
 
-#ifdef CONFIG_HIGHMEM
-pte_t *kmap_pte;
-EXPORT_SYMBOL(kmap_pte);
-
 static void __init highmem_init(void)
 {
 	pr_debug("%x\n", (u32)PKMAP_BASE);
 	map_page(PKMAP_BASE, 0, 0);	/* XXX gross */
 	pkmap_page_table = virt_to_kpte(PKMAP_BASE);
-
-	kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
 }
 
 static void highmem_setup(void)
#29 lore raw

[tip: core/mm] microblaze/mm/highmem: Switch to generic kmap atomic

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     7ac1b26b0a7288fc8f87aa8978891375f23740b2
Gitweb:        https://git.kernel.org/tip/7ac1b26b0a7288fc8f87aa8978891375f23740b2
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:24 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:56 +01:00

microblaze/mm/highmem: Switch to generic kmap atomic

No reason having the same code in every architecture.

---
 arch/microblaze/Kconfig               |  1 +-
 arch/microblaze/include/asm/fixmap.h  |  4 +-
 arch/microblaze/include/asm/highmem.h |  6 +-
 arch/microblaze/mm/Makefile           |  1 +-
 arch/microblaze/mm/highmem.c          | 78 +--------------------------
 arch/microblaze/mm/init.c             |  6 +--
 6 files changed, 8 insertions(+), 88 deletions(-)
 delete mode 100644 arch/microblaze/mm/highmem.c
arch/microblaze/Kconfig +1 -0
index 33925ff..7f6ca0a 100644
@@ -155,6 +155,7 @@ config XILINX_UNCACHED_SHADOW
 config HIGHMEM
 	bool "High memory support"
 	depends on MMU
+	select KMAP_LOCAL
 	help
 	  The address space of Microblaze processors is only 4 Gigabytes large
 	  and it has to accommodate user address space, kernel address
arch/microblaze/include/asm/fixmap.h +2 -2
index 0379ce5..e6e9288 100644
@@ -20,7 +20,7 @@
 #include <asm/page.h>
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 #define FIXADDR_TOP	((unsigned long)(-PAGE_SIZE))
@@ -47,7 +47,7 @@ enum fixed_addresses {
 	FIX_HOLE,
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
-	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * num_possible_cpus()) - 1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * num_possible_cpus()) - 1,
 #endif
 	__end_of_fixed_addresses
 };
arch/microblaze/include/asm/highmem.h +5 -1
index 284ca8f..4418633 100644
@@ -25,7 +25,6 @@
 #include <linux/uaccess.h>
 #include <asm/fixmap.h>
 
-extern pte_t *kmap_pte;
 extern pte_t *pkmap_page_table;
 
 /*
@@ -52,6 +51,11 @@ extern pte_t *pkmap_page_table;
 
 #define flush_cache_kmaps()	{ flush_icache(); flush_dcache(); }
 
+#define arch_kmap_local_post_map(vaddr, pteval)	\
+	local_flush_tlb_page(NULL, vaddr);
+#define arch_kmap_local_post_unmap(vaddr)	\
+	local_flush_tlb_page(NULL, vaddr);
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_HIGHMEM_H */
arch/microblaze/mm/Makefile +0 -1
index 1b16875..8ced711 100644
@@ -6,4 +6,3 @@
 obj-y := consistent.o init.o
 
 obj-$(CONFIG_MMU) += pgtable.o mmu_context.o fault.o
-obj-$(CONFIG_HIGHMEM) += highmem.o
arch/microblaze/mm/highmem.c deleted +0 -78

78 lines not on this page · raw message

arch/microblaze/mm/init.c +0 -6
index 45da639..1f4b5b3 100644
@@ -49,17 +49,11 @@ unsigned long lowmem_size;
 EXPORT_SYMBOL(min_low_pfn);
 EXPORT_SYMBOL(max_low_pfn);
 
-#ifdef CONFIG_HIGHMEM
-pte_t *kmap_pte;
-EXPORT_SYMBOL(kmap_pte);
-
 static void __init highmem_init(void)
 {
 	pr_debug("%x\n", (u32)PKMAP_BASE);
 	map_page(PKMAP_BASE, 0, 0);	/* XXX gross */
 	pkmap_page_table = virt_to_kpte(PKMAP_BASE);
-
-	kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
 }
 
 static void highmem_setup(void)
#30 lore raw

PATCH v3 13/37 mips/mm/highmem: Switch to generic kmap atomic

In reply to Thomas Gleixner

No reason having the same code in every architecture

---
V3: Remove the kmap types cruft

---
 arch/mips/Kconfig                  |    1 
 arch/mips/include/asm/fixmap.h     |    4 -
 arch/mips/include/asm/highmem.h    |    6 +-
 arch/mips/include/asm/kmap_types.h |   13 ------
 arch/mips/mm/highmem.c             |   77 -------------------------------------
 arch/mips/mm/init.c                |    4 -
 6 files changed, 6 insertions(+), 99 deletions(-)
arch/mips/Kconfig +1 -0
@@ -2719,6 +2719,7 @@ config WAR_MIPS34K_MISSED_ITLB
 config HIGHMEM
 	bool "High Memory Support"
 	depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM && !CPU_MIPS32_3_5_EVA
+	select KMAP_LOCAL
 
 config CPU_SUPPORTS_HIGHMEM
 	bool
arch/mips/include/asm/fixmap.h +2 -2
@@ -17,7 +17,7 @@
 #include <spaces.h>
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 /*
@@ -52,7 +52,7 @@ enum fixed_addresses {
 #ifdef CONFIG_HIGHMEM
 	/* reserved pte's for temporary kernel mappings */
 	FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
-	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 #endif
 	__end_of_fixed_addresses
 };
arch/mips/include/asm/highmem.h +3 -3
@@ -24,7 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
 #include <asm/cpu-features.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 
 /* declarations for highmem.c */
 extern unsigned long highstart_pfn, highend_pfn;
@@ -48,11 +48,11 @@ extern pte_t *pkmap_page_table;
 
 #define ARCH_HAS_KMAP_FLUSH_TLB
 extern void kmap_flush_tlb(unsigned long addr);
-extern void *kmap_atomic_pfn(unsigned long pfn);
 
 #define flush_cache_kmaps()	BUG_ON(cpu_has_dc_aliases)
 
-extern void kmap_init(void);
+#define arch_kmap_local_post_map(vaddr, pteval)	local_flush_tlb_one(vaddr)
+#define arch_kmap_local_post_unmap(vaddr)	local_flush_tlb_one(vaddr)
 
 #endif /* __KERNEL__ */
 
arch/mips/include/asm/kmap_types.h deleted +0 -13
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define	 __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif
arch/mips/mm/highmem.c +0 -77

86 lines not on this page · raw message

arch/mips/mm/init.c +0 -4
@@ -36,7 +36,6 @@
 #include <asm/cachectl.h>
 #include <asm/cpu.h>
 #include <asm/dma.h>
-#include <asm/kmap_types.h>
 #include <asm/maar.h>
 #include <asm/mmu_context.h>
 #include <asm/sections.h>
@@ -402,9 +401,6 @@ void __init paging_init(void)
 
 	pagetable_init();
 
-#ifdef CONFIG_HIGHMEM
-	kmap_init();
-#endif
 #ifdef CONFIG_ZONE_DMA
 	max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
 #endif
#31 lore raw

[tip: core/mm] mips/mm/highmem: Switch to generic kmap atomic

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     a4c33e83bca133ff979e13c784c7605e1ac143df
Gitweb:        https://git.kernel.org/tip/a4c33e83bca133ff979e13c784c7605e1ac143df
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:25 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:56 +01:00

mips/mm/highmem: Switch to generic kmap atomic

No reason having the same code in every architecture

---
 arch/mips/Kconfig                  |  1 +-
 arch/mips/include/asm/fixmap.h     |  4 +-
 arch/mips/include/asm/highmem.h    |  6 +-
 arch/mips/include/asm/kmap_types.h | 13 +-----
 arch/mips/mm/highmem.c             | 77 +-----------------------------
 arch/mips/mm/init.c                |  4 +--
 6 files changed, 6 insertions(+), 99 deletions(-)
 delete mode 100644 arch/mips/include/asm/kmap_types.h
arch/mips/Kconfig +1 -0
index 2000bb2..6b762be 100644
@@ -2719,6 +2719,7 @@ config WAR_MIPS34K_MISSED_ITLB
 config HIGHMEM
 	bool "High Memory Support"
 	depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM && !CPU_MIPS32_3_5_EVA
+	select KMAP_LOCAL
 
 config CPU_SUPPORTS_HIGHMEM
 	bool
arch/mips/include/asm/fixmap.h +2 -2
index 743535b..beea147 100644
@@ -17,7 +17,7 @@
 #include <spaces.h>
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 /*
@@ -52,7 +52,7 @@ enum fixed_addresses {
 #ifdef CONFIG_HIGHMEM
 	/* reserved pte's for temporary kernel mappings */
 	FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
-	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 #endif
 	__end_of_fixed_addresses
 };
arch/mips/include/asm/highmem.h +3 -3
index f1f788b..19edf8e 100644
@@ -24,7 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
 #include <asm/cpu-features.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 
 /* declarations for highmem.c */
 extern unsigned long highstart_pfn, highend_pfn;
@@ -48,11 +48,11 @@ extern pte_t *pkmap_page_table;
 
 #define ARCH_HAS_KMAP_FLUSH_TLB
 extern void kmap_flush_tlb(unsigned long addr);
-extern void *kmap_atomic_pfn(unsigned long pfn);
 
 #define flush_cache_kmaps()	BUG_ON(cpu_has_dc_aliases)
 
-extern void kmap_init(void);
+#define arch_kmap_local_post_map(vaddr, pteval)	local_flush_tlb_one(vaddr)
+#define arch_kmap_local_post_unmap(vaddr)	local_flush_tlb_one(vaddr)
 
 #endif /* __KERNEL__ */
 
arch/mips/include/asm/kmap_types.h deleted +0 -13
deleted file mode 100644
index 16665dc..0000000
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define	 __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif
arch/mips/mm/highmem.c +0 -77

86 lines not on this page · raw message

arch/mips/mm/init.c +0 -4
index 07e84a7..bc80893 100644
@@ -36,7 +36,6 @@
 #include <asm/cachectl.h>
 #include <asm/cpu.h>
 #include <asm/dma.h>
-#include <asm/kmap_types.h>
 #include <asm/maar.h>
 #include <asm/mmu_context.h>
 #include <asm/sections.h>
@@ -402,9 +401,6 @@ void __init paging_init(void)
 
 	pagetable_init();
 
-#ifdef CONFIG_HIGHMEM
-	kmap_init();
-#endif
 #ifdef CONFIG_ZONE_DMA
 	max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
 #endif
#32 lore raw

PATCH v3 14/37 nds32/mm/highmem: Switch to generic kmap atomic

In reply to Thomas Gleixner

The mapping code is odd and looks broken. See FIXME in the comment.

Also fix the harmless off by one in the FIX_KMAP_END define.

Cc Nick Hu <[email protected]>
Cc Greentime Hu <[email protected]>
Cc Vincent Chen <[email protected]>

---
V3: Remove the kmap types cruft

---
 arch/nds32/Kconfig.cpu           |    1 
 arch/nds32/include/asm/fixmap.h  |    4 +--
 arch/nds32/include/asm/highmem.h |   22 +++++++++++++----
 arch/nds32/mm/Makefile           |    1 
 arch/nds32/mm/highmem.c          |   48 ---------------------------------------
 5 files changed, 19 insertions(+), 57 deletions(-)
arch/nds32/Kconfig.cpu +1 -0
@@ -157,6 +157,7 @@ config HW_SUPPORT_UNALIGNMENT_ACCESS
 config HIGHMEM
 	bool "High Memory Support"
 	depends on MMU && !CPU_CACHE_ALIASING
+	select KMAP_LOCAL
 	help
 	  The address space of Andes processors is only 4 Gigabytes large
 	  and it has to accommodate user address space, kernel address
arch/nds32/include/asm/fixmap.h +2 -2
@@ -6,7 +6,7 @@
 
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 enum fixed_addresses {
@@ -14,7 +14,7 @@ enum fixed_addresses {
 	FIX_KMAP_RESERVED,
 	FIX_KMAP_BEGIN,
 #ifdef CONFIG_HIGHMEM
-	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS),
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 #endif
 	FIX_EARLYCON_MEM_BASE,
 	__end_of_fixed_addresses
arch/nds32/include/asm/highmem.h +16 -6
@@ -5,7 +5,6 @@
 #define _ASM_HIGHMEM_H
 
 #include <asm/proc-fns.h>
-#include <asm/kmap_types.h>
 #include <asm/fixmap.h>
 
 /*
@@ -45,11 +44,22 @@ extern pte_t *pkmap_page_table;
 extern void kmap_init(void);
 
 /*
- * The following functions are already defined by <linux/highmem.h>
- * when CONFIG_HIGHMEM is not set.
+ * FIXME: The below looks broken vs. a kmap_atomic() in task context which
+ * is interupted and another kmap_atomic() happens in interrupt context.
+ * But what do I know about nds32. -- tglx
  */
-#ifdef CONFIG_HIGHMEM
-extern void *kmap_atomic_pfn(unsigned long pfn);
-#endif
+#define arch_kmap_local_post_map(vaddr, pteval)			\
+	do {							\
+		__nds32__tlbop_inv(vaddr);			\
+		__nds32__mtsr_dsb(vaddr, NDS32_SR_TLB_VPN);	\
+		__nds32__tlbop_rwr(pteval);			\
+		__nds32__isb();					\
+	} while (0)
+
+#define arch_kmap_local_pre_unmap(vaddr)			\
+	do {							\
+		__nds32__tlbop_inv(vaddr);			\
+		__nds32__isb();					\
+	} while (0)
 
 #endif
arch/nds32/mm/Makefile +0 -1
@@ -3,7 +3,6 @@ obj-y				:= extable.o tlb.o fault.o init
                                    mm-nds32.o cacheflush.o proc.o
 
 obj-$(CONFIG_ALIGNMENT_TRAP)	+= alignment.o
-obj-$(CONFIG_HIGHMEM)           += highmem.o
 
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_proc.o     = $(CC_FLAGS_FTRACE)
arch/nds32/mm/highmem.c deleted +0 -48

48 lines not on this page · raw message

#33 lore raw

[tip: core/mm] nds32/mm/highmem: Switch to generic kmap atomic

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     5f037ea3b26767e0b1bdc522948321b282268b49
Gitweb:        https://git.kernel.org/tip/5f037ea3b26767e0b1bdc522948321b282268b49
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:26 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:57 +01:00

nds32/mm/highmem: Switch to generic kmap atomic

The mapping code is odd and looks broken. See FIXME in the comment.

Also fix the harmless off by one in the FIX_KMAP_END define.

---
 arch/nds32/Kconfig.cpu           |  1 +-
 arch/nds32/include/asm/fixmap.h  |  4 +--
 arch/nds32/include/asm/highmem.h | 22 ++++++++++----
 arch/nds32/mm/Makefile           |  1 +-
 arch/nds32/mm/highmem.c          | 48 +-------------------------------
 5 files changed, 19 insertions(+), 57 deletions(-)
 delete mode 100644 arch/nds32/mm/highmem.c
arch/nds32/Kconfig.cpu +1 -0
index f88a12f..c107599 100644
@@ -157,6 +157,7 @@ config HW_SUPPORT_UNALIGNMENT_ACCESS
 config HIGHMEM
 	bool "High Memory Support"
 	depends on MMU && !CPU_CACHE_ALIASING
+	select KMAP_LOCAL
 	help
 	  The address space of Andes processors is only 4 Gigabytes large
 	  and it has to accommodate user address space, kernel address
arch/nds32/include/asm/fixmap.h +2 -2
index 5a4bf11..2fa09a2 100644
@@ -6,7 +6,7 @@
 
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 enum fixed_addresses {
@@ -14,7 +14,7 @@ enum fixed_addresses {
 	FIX_KMAP_RESERVED,
 	FIX_KMAP_BEGIN,
 #ifdef CONFIG_HIGHMEM
-	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS),
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 #endif
 	FIX_EARLYCON_MEM_BASE,
 	__end_of_fixed_addresses
arch/nds32/include/asm/highmem.h +16 -6
index fe986d0..16159a8 100644
@@ -5,7 +5,6 @@
 #define _ASM_HIGHMEM_H
 
 #include <asm/proc-fns.h>
-#include <asm/kmap_types.h>
 #include <asm/fixmap.h>
 
 /*
@@ -45,11 +44,22 @@ extern pte_t *pkmap_page_table;
 extern void kmap_init(void);
 
 /*
- * The following functions are already defined by <linux/highmem.h>
- * when CONFIG_HIGHMEM is not set.
+ * FIXME: The below looks broken vs. a kmap_atomic() in task context which
+ * is interupted and another kmap_atomic() happens in interrupt context.
+ * But what do I know about nds32. -- tglx
  */
-#ifdef CONFIG_HIGHMEM
-extern void *kmap_atomic_pfn(unsigned long pfn);
-#endif
+#define arch_kmap_local_post_map(vaddr, pteval)			\
+	do {							\
+		__nds32__tlbop_inv(vaddr);			\
+		__nds32__mtsr_dsb(vaddr, NDS32_SR_TLB_VPN);	\
+		__nds32__tlbop_rwr(pteval);			\
+		__nds32__isb();					\
+	} while (0)
+
+#define arch_kmap_local_pre_unmap(vaddr)			\
+	do {							\
+		__nds32__tlbop_inv(vaddr);			\
+		__nds32__isb();					\
+	} while (0)
 
 #endif
arch/nds32/mm/Makefile +0 -1
index 897ecaf..14fb2e8 100644
@@ -3,7 +3,6 @@ obj-y				:= extable.o tlb.o fault.o init.o mmap.o \
                                    mm-nds32.o cacheflush.o proc.o
 
 obj-$(CONFIG_ALIGNMENT_TRAP)	+= alignment.o
-obj-$(CONFIG_HIGHMEM)           += highmem.o
 
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_proc.o     = $(CC_FLAGS_FTRACE)
arch/nds32/mm/highmem.c deleted +0 -48

48 lines not on this page · raw message

#34 lore raw

PATCH v3 15/37 powerpc/mm/highmem: Switch to generic kmap atomic

In reply to Thomas Gleixner

No reason having the same code in every architecture

Cc Michael Ellerman <[email protected]>
Cc Benjamin Herrenschmidt <[email protected]>
Cc Paul Mackerras <[email protected]>

---
V3: Remove the kmap types cruft

---
 arch/powerpc/Kconfig                  |    1 
 arch/powerpc/include/asm/fixmap.h     |    4 +-
 arch/powerpc/include/asm/highmem.h    |    7 ++-
 arch/powerpc/include/asm/kmap_types.h |   13 ------
 arch/powerpc/mm/Makefile              |    1 
 arch/powerpc/mm/highmem.c             |   67 ----------------------------------
 arch/powerpc/mm/mem.c                 |    7 ---
 7 files changed, 8 insertions(+), 92 deletions(-)
arch/powerpc/Kconfig +1 -0
@@ -409,6 +409,7 @@ menu "Kernel options"
 config HIGHMEM
 	bool "High memory support"
 	depends on PPC32
+	select KMAP_LOCAL
 
 source "kernel/Kconfig.hz"
 
arch/powerpc/include/asm/fixmap.h +2 -2
@@ -20,7 +20,7 @@
 #include <asm/page.h>
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 #ifdef CONFIG_KASAN
@@ -55,7 +55,7 @@ enum fixed_addresses {
 	FIX_EARLY_DEBUG_BASE = FIX_EARLY_DEBUG_TOP+(ALIGN(SZ_128K, PAGE_SIZE)/PAGE_SIZE)-1,
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
-	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 #endif
 #ifdef CONFIG_PPC_8xx
 	/* For IMMR we need an aligned 512K area */
arch/powerpc/include/asm/highmem.h +5 -2
@@ -24,12 +24,10 @@
 #ifdef __KERNEL__
 
 #include <linux/interrupt.h>
-#include <asm/kmap_types.h>
 #include <asm/cacheflush.h>
 #include <asm/page.h>
 #include <asm/fixmap.h>
 
-extern pte_t *kmap_pte;
 extern pte_t *pkmap_page_table;
 
 /*
@@ -60,6 +58,11 @@ extern pte_t *pkmap_page_table;
 
 #define flush_cache_kmaps()	flush_cache_all()
 
+#define arch_kmap_local_post_map(vaddr, pteval)	\
+	local_flush_tlb_page(NULL, vaddr)
+#define arch_kmap_local_post_unmap(vaddr)	\
+	local_flush_tlb_page(NULL, vaddr)
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_HIGHMEM_H */
arch/powerpc/include/asm/kmap_types.h deleted +0 -13
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _ASM_POWERPC_KMAP_TYPES_H
-#define _ASM_POWERPC_KMAP_TYPES_H
-
-#ifdef __KERNEL__
-
-/*
- */
-
-#define KM_TYPE_NR 16
-
-#endif	/* __KERNEL__ */
-#endif	/* _ASM_POWERPC_KMAP_TYPES_H */
arch/powerpc/mm/Makefile +0 -1
@@ -16,7 +16,6 @@ obj-$(CONFIG_NEED_MULTIPLE_NODES) += num
 obj-$(CONFIG_PPC_MM_SLICES)	+= slice.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
-obj-$(CONFIG_HIGHMEM)		+= highmem.o
 obj-$(CONFIG_PPC_COPRO_BASE)	+= copro_fault.o
 obj-$(CONFIG_PPC_PTDUMP)	+= ptdump/
 obj-$(CONFIG_KASAN)		+= kasan/
arch/powerpc/mm/highmem.c deleted +0 -67

67 lines not on this page · raw message

arch/powerpc/mm/mem.c +0 -7
@@ -61,11 +61,6 @@
 unsigned long long memory_limit;
 bool init_mem_is_free;
 
-#ifdef CONFIG_HIGHMEM
-pte_t *kmap_pte;
-EXPORT_SYMBOL(kmap_pte);
-#endif
-
 pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 			      unsigned long size, pgprot_t vma_prot)
 {
@@ -235,8 +230,6 @@ void __init paging_init(void)
 
 	map_kernel_page(PKMAP_BASE, 0, __pgprot(0));	/* XXX gross */
 	pkmap_page_table = virt_to_kpte(PKMAP_BASE);
-
-	kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
 #endif /* CONFIG_HIGHMEM */
 
 	printk(KERN_DEBUG "Top of RAM: 0x%llx, Total RAM: 0x%llx\n",
#35 lore raw

[tip: core/mm] powerpc/mm/highmem: Switch to generic kmap atomic

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     47da42b27a56f3ee5abace2858b69e277703f707
Gitweb:        https://git.kernel.org/tip/47da42b27a56f3ee5abace2858b69e277703f707
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:27 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:57 +01:00

powerpc/mm/highmem: Switch to generic kmap atomic

No reason having the same code in every architecture

Cc Michael Ellerman <[email protected]>
Cc Benjamin Herrenschmidt <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Arnd Bergmann <[email protected]>
---
 arch/powerpc/Kconfig                  |  1 +-
 arch/powerpc/include/asm/fixmap.h     |  4 +-
 arch/powerpc/include/asm/highmem.h    |  7 ++-
 arch/powerpc/include/asm/kmap_types.h | 13 +-----
 arch/powerpc/mm/Makefile              |  1 +-
 arch/powerpc/mm/highmem.c             | 67 +--------------------------
 arch/powerpc/mm/mem.c                 |  7 +---
 7 files changed, 8 insertions(+), 92 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/kmap_types.h
 delete mode 100644 arch/powerpc/mm/highmem.c
arch/powerpc/Kconfig +1 -0
index e9f13fe..d4cfddc 100644
@@ -409,6 +409,7 @@ menu "Kernel options"
 config HIGHMEM
 	bool "High memory support"
 	depends on PPC32
+	select KMAP_LOCAL
 
 source "kernel/Kconfig.hz"
 
arch/powerpc/include/asm/fixmap.h +2 -2
index 6bfc879..8d03c16 100644
@@ -20,7 +20,7 @@
 #include <asm/page.h>
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 #ifdef CONFIG_KASAN
@@ -55,7 +55,7 @@ enum fixed_addresses {
 	FIX_EARLY_DEBUG_BASE = FIX_EARLY_DEBUG_TOP+(ALIGN(SZ_128K, PAGE_SIZE)/PAGE_SIZE)-1,
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,	/* reserved pte's for temporary kernel mappings */
-	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
 #endif
 #ifdef CONFIG_PPC_8xx
 	/* For IMMR we need an aligned 512K area */
arch/powerpc/include/asm/highmem.h +5 -2
index 104026f..80a5ae7 100644
@@ -24,12 +24,10 @@
 #ifdef __KERNEL__
 
 #include <linux/interrupt.h>
-#include <asm/kmap_types.h>
 #include <asm/cacheflush.h>
 #include <asm/page.h>
 #include <asm/fixmap.h>
 
-extern pte_t *kmap_pte;
 extern pte_t *pkmap_page_table;
 
 /*
@@ -60,6 +58,11 @@ extern pte_t *pkmap_page_table;
 
 #define flush_cache_kmaps()	flush_cache_all()
 
+#define arch_kmap_local_post_map(vaddr, pteval)	\
+	local_flush_tlb_page(NULL, vaddr)
+#define arch_kmap_local_post_unmap(vaddr)	\
+	local_flush_tlb_page(NULL, vaddr)
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_HIGHMEM_H */
arch/powerpc/include/asm/kmap_types.h deleted +0 -13
deleted file mode 100644
index c8fa182..0000000
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _ASM_POWERPC_KMAP_TYPES_H
-#define _ASM_POWERPC_KMAP_TYPES_H
-
-#ifdef __KERNEL__
-
-/*
- */
-
-#define KM_TYPE_NR 16
-
-#endif	/* __KERNEL__ */
-#endif	/* _ASM_POWERPC_KMAP_TYPES_H */
arch/powerpc/mm/Makefile +0 -1
index 5e14798..1c552b5 100644
@@ -16,7 +16,6 @@ obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
 obj-$(CONFIG_PPC_MM_SLICES)	+= slice.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
-obj-$(CONFIG_HIGHMEM)		+= highmem.o
 obj-$(CONFIG_PPC_COPRO_BASE)	+= copro_fault.o
 obj-$(CONFIG_PPC_PTDUMP)	+= ptdump/
 obj-$(CONFIG_KASAN)		+= kasan/
arch/powerpc/mm/highmem.c deleted +0 -67

67 lines not on this page · raw message

arch/powerpc/mm/mem.c +0 -7
index 01ec2a2..375a989 100644
@@ -61,11 +61,6 @@
 unsigned long long memory_limit;
 bool init_mem_is_free;
 
-#ifdef CONFIG_HIGHMEM
-pte_t *kmap_pte;
-EXPORT_SYMBOL(kmap_pte);
-#endif
-
 pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 			      unsigned long size, pgprot_t vma_prot)
 {
@@ -235,8 +230,6 @@ void __init paging_init(void)
 
 	map_kernel_page(PKMAP_BASE, 0, __pgprot(0));	/* XXX gross */
 	pkmap_page_table = virt_to_kpte(PKMAP_BASE);
-
-	kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
 #endif /* CONFIG_HIGHMEM */
 
 	printk(KERN_DEBUG "Top of RAM: 0x%llx, Total RAM: 0x%llx\n",
#36 lore raw

PATCH v3 16/37 sparc/mm/highmem: Switch to generic kmap atomic

In reply to Thomas Gleixner

No reason having the same code in every architecture

---
V3: Remove the kmap types cruft

---
 arch/sparc/Kconfig                  |    1 
 arch/sparc/include/asm/highmem.h    |    8 +-
 arch/sparc/include/asm/kmap_types.h |   11 ---
 arch/sparc/include/asm/vaddrs.h     |    4 -
 arch/sparc/mm/Makefile              |    3 
 arch/sparc/mm/highmem.c             |  115 ------------------------------------
 arch/sparc/mm/srmmu.c               |    2 
 7 files changed, 8 insertions(+), 136 deletions(-)
arch/sparc/Kconfig +1 -0
@@ -139,6 +139,7 @@ config MMU
 config HIGHMEM
 	bool
 	default y if SPARC32
+	select KMAP_LOCAL
 
 config ZONE_DMA
 	bool
arch/sparc/include/asm/highmem.h +5 -3
@@ -24,7 +24,6 @@
 #include <linux/interrupt.h>
 #include <linux/pgtable.h>
 #include <asm/vaddrs.h>
-#include <asm/kmap_types.h>
 #include <asm/pgtsrmmu.h>
 
 /* declarations for highmem.c */
@@ -33,8 +32,6 @@ extern unsigned long highstart_pfn, high
 #define kmap_prot __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE)
 extern pte_t *pkmap_page_table;
 
-void kmap_init(void) __init;
-
 /*
  * Right now we initialize only a single pte table. It can be extended
  * easily, subsequent pte tables have to be allocated in one physical
@@ -53,6 +50,11 @@ void kmap_init(void) __init;
 
 #define flush_cache_kmaps()	flush_cache_all()
 
+/* FIXME: Use __flush_tlb_one(vaddr) instead of flush_cache_all() -- Anton */
+#define arch_kmap_local_post_map(vaddr, pteval)	flush_cache_all()
+#define arch_kmap_local_post_unmap(vaddr)	flush_cache_all()
+
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_HIGHMEM_H */
arch/sparc/include/asm/kmap_types.h deleted +0 -11
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-/* Dummy header just to define km_type.  None of this
- * is actually used on sparc.  -DaveM
- */
-
-#include <asm-generic/kmap_types.h>
-
-#endif
arch/sparc/include/asm/vaddrs.h +2 -2
@@ -32,13 +32,13 @@
 #define SRMMU_NOCACHE_ALCRATIO	64	/* 256 pages per 64MB of system RAM */
 
 #ifndef __ASSEMBLY__
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 
 enum fixed_addresses {
 	FIX_HOLE,
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,
-	FIX_KMAP_END = (KM_TYPE_NR * NR_CPUS),
+	FIX_KMAP_END = (KM_MAX_IDX * NR_CPUS),
 #endif
 	__end_of_fixed_addresses
 };
arch/sparc/mm/Makefile +0 -3
@@ -15,6 +15,3 @@ obj-$(CONFIG_SPARC32)   += leon_mm.o
 
 # Only used by sparc64
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-
-# Only used by sparc32
-obj-$(CONFIG_HIGHMEM)   += highmem.o
arch/sparc/mm/highmem.c deleted +0 -115

115 lines not on this page · raw message

arch/sparc/mm/srmmu.c +0 -2
@@ -971,8 +971,6 @@ void __init srmmu_paging_init(void)
 
 	sparc_context_init(num_contexts);
 
-	kmap_init();
-
 	{
 		unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 };
#37 lore raw

[tip: core/mm] sparc/mm/highmem: Switch to generic kmap atomic

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     3293efa9780712ad8504689e0c296d2bd33827d5
Gitweb:        https://git.kernel.org/tip/3293efa9780712ad8504689e0c296d2bd33827d5
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:28 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:57 +01:00

sparc/mm/highmem: Switch to generic kmap atomic

No reason having the same code in every architecture

---
 arch/sparc/Kconfig                  |   1 +-
 arch/sparc/include/asm/highmem.h    |   8 +-
 arch/sparc/include/asm/kmap_types.h |  11 +---
 arch/sparc/include/asm/vaddrs.h     |   4 +-
 arch/sparc/mm/Makefile              |   3 +-
 arch/sparc/mm/highmem.c             | 115 +---------------------------
 arch/sparc/mm/srmmu.c               |   2 +-
 7 files changed, 8 insertions(+), 136 deletions(-)
 delete mode 100644 arch/sparc/include/asm/kmap_types.h
 delete mode 100644 arch/sparc/mm/highmem.c
arch/sparc/Kconfig +1 -0
index a6ca135..e841708 100644
@@ -139,6 +139,7 @@ config MMU
 config HIGHMEM
 	bool
 	default y if SPARC32
+	select KMAP_LOCAL
 
 config ZONE_DMA
 	bool
arch/sparc/include/asm/highmem.h +5 -3
index 6c35f0d..8751162 100644
@@ -24,7 +24,6 @@
 #include <linux/interrupt.h>
 #include <linux/pgtable.h>
 #include <asm/vaddrs.h>
-#include <asm/kmap_types.h>
 #include <asm/pgtsrmmu.h>
 
 /* declarations for highmem.c */
@@ -33,8 +32,6 @@ extern unsigned long highstart_pfn, highend_pfn;
 #define kmap_prot __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE)
 extern pte_t *pkmap_page_table;
 
-void kmap_init(void) __init;
-
 /*
  * Right now we initialize only a single pte table. It can be extended
  * easily, subsequent pte tables have to be allocated in one physical
@@ -53,6 +50,11 @@ void kmap_init(void) __init;
 
 #define flush_cache_kmaps()	flush_cache_all()
 
+/* FIXME: Use __flush_tlb_one(vaddr) instead of flush_cache_all() -- Anton */
+#define arch_kmap_local_post_map(vaddr, pteval)	flush_cache_all()
+#define arch_kmap_local_post_unmap(vaddr)	flush_cache_all()
+
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_HIGHMEM_H */
arch/sparc/include/asm/kmap_types.h deleted +0 -11
deleted file mode 100644
index 55a99b6..0000000
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-/* Dummy header just to define km_type.  None of this
- * is actually used on sparc.  -DaveM
- */
-
-#include <asm-generic/kmap_types.h>
-
-#endif
arch/sparc/include/asm/vaddrs.h +2 -2
index 84d054b..4fec034 100644
@@ -32,13 +32,13 @@
 #define SRMMU_NOCACHE_ALCRATIO	64	/* 256 pages per 64MB of system RAM */
 
 #ifndef __ASSEMBLY__
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 
 enum fixed_addresses {
 	FIX_HOLE,
 #ifdef CONFIG_HIGHMEM
 	FIX_KMAP_BEGIN,
-	FIX_KMAP_END = (KM_TYPE_NR * NR_CPUS),
+	FIX_KMAP_END = (KM_MAX_IDX * NR_CPUS),
 #endif
 	__end_of_fixed_addresses
 };
arch/sparc/mm/Makefile +0 -3
index b078205..68db1f8 100644
@@ -15,6 +15,3 @@ obj-$(CONFIG_SPARC32)   += leon_mm.o
 
 # Only used by sparc64
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-
-# Only used by sparc32
-obj-$(CONFIG_HIGHMEM)   += highmem.o
arch/sparc/mm/highmem.c deleted +0 -115

115 lines not on this page · raw message

arch/sparc/mm/srmmu.c +0 -2
index 0070f8b..a03caa5 100644
@@ -971,8 +971,6 @@ void __init srmmu_paging_init(void)
 
 	sparc_context_init(num_contexts);
 
-	kmap_init();
-
 	{
 		unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 };
 
#38 lore raw

PATCH v3 17/37 xtensa/mm/highmem: Switch to generic kmap atomic

In reply to Thomas Gleixner

No reason having the same code in every architecture

---
V3: Remove the kmap types cruft

---
 arch/xtensa/Kconfig               |    1 
 arch/xtensa/include/asm/fixmap.h  |    4 +--
 arch/xtensa/include/asm/highmem.h |   12 ++++++++-
 arch/xtensa/mm/highmem.c          |   46 ++++----------------------------------
 4 files changed, 18 insertions(+), 45 deletions(-)
arch/xtensa/Kconfig +1 -0
@@ -666,6 +666,7 @@ endchoice
 config HIGHMEM
 	bool "High Memory Support"
 	depends on MMU
+	select KMAP_LOCAL
 	help
 	  Linux can use the full amount of RAM in the system by
 	  default. However, the default MMUv2 setup only maps the
arch/xtensa/include/asm/fixmap.h +2 -2
@@ -16,7 +16,7 @@
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
 #include <linux/pgtable.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 /*
@@ -39,7 +39,7 @@ enum fixed_addresses {
 	/* reserved pte's for temporary kernel mappings */
 	FIX_KMAP_BEGIN,
 	FIX_KMAP_END = FIX_KMAP_BEGIN +
-		(KM_TYPE_NR * NR_CPUS * DCACHE_N_COLORS) - 1,
+		(KM_MAX_IDX * NR_CPUS * DCACHE_N_COLORS) - 1,
 #endif
 	__end_of_fixed_addresses
 };
arch/xtensa/include/asm/highmem.h +10 -2
@@ -16,9 +16,8 @@
 #include <linux/pgtable.h>
 #include <asm/cacheflush.h>
 #include <asm/fixmap.h>
-#include <asm/kmap_types.h>
 
-#define PKMAP_BASE		((FIXADDR_START - \
+#define PKMAP_BASE		((FIXADDR_START -			\
 				  (LAST_PKMAP + 1) * PAGE_SIZE) & PMD_MASK)
 #define LAST_PKMAP		(PTRS_PER_PTE * DCACHE_N_COLORS)
 #define LAST_PKMAP_MASK		(LAST_PKMAP - 1)
@@ -68,6 +67,15 @@ static inline void flush_cache_kmaps(voi
 	flush_cache_all();
 }
 
+enum fixed_addresses kmap_local_map_idx(int type, unsigned long pfn);
+#define arch_kmap_local_map_idx		kmap_local_map_idx
+
+enum fixed_addresses kmap_local_unmap_idx(int type, unsigned long addr);
+#define arch_kmap_local_unmap_idx	kmap_local_unmap_idx
+
+#define arch_kmap_local_post_unmap(vaddr)	\
+	local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE)
+
 void kmap_init(void);
 
 #endif
arch/xtensa/mm/highmem.c +5 -41

72 lines not on this page · raw message

#39 lore raw

[tip: core/mm] xtensa/mm/highmem: Switch to generic kmap atomic

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     629ed3f7dad2a914b3a89fad49b358e363e3e6d1
Gitweb:        https://git.kernel.org/tip/629ed3f7dad2a914b3a89fad49b358e363e3e6d1
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:29 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:57 +01:00

xtensa/mm/highmem: Switch to generic kmap atomic

No reason having the same code in every architecture

---
 arch/xtensa/Kconfig               |  1 +-
 arch/xtensa/include/asm/fixmap.h  |  4 +--
 arch/xtensa/include/asm/highmem.h | 12 ++++++--
 arch/xtensa/mm/highmem.c          | 46 +++---------------------------
 4 files changed, 18 insertions(+), 45 deletions(-)
arch/xtensa/Kconfig +1 -0
index d0dfa50..dc22ef3 100644
@@ -666,6 +666,7 @@ endchoice
 config HIGHMEM
 	bool "High Memory Support"
 	depends on MMU
+	select KMAP_LOCAL
 	help
 	  Linux can use the full amount of RAM in the system by
 	  default. However, the default MMUv2 setup only maps the
arch/xtensa/include/asm/fixmap.h +2 -2
index a06ffb0..92049b6 100644
@@ -16,7 +16,7 @@
 #ifdef CONFIG_HIGHMEM
 #include <linux/threads.h>
 #include <linux/pgtable.h>
-#include <asm/kmap_types.h>
+#include <asm/kmap_size.h>
 #endif
 
 /*
@@ -39,7 +39,7 @@ enum fixed_addresses {
 	/* reserved pte's for temporary kernel mappings */
 	FIX_KMAP_BEGIN,
 	FIX_KMAP_END = FIX_KMAP_BEGIN +
-		(KM_TYPE_NR * NR_CPUS * DCACHE_N_COLORS) - 1,
+		(KM_MAX_IDX * NR_CPUS * DCACHE_N_COLORS) - 1,
 #endif
 	__end_of_fixed_addresses
 };
arch/xtensa/include/asm/highmem.h +10 -2
index eac5032..0fc3b1c 100644
@@ -16,9 +16,8 @@
 #include <linux/pgtable.h>
 #include <asm/cacheflush.h>
 #include <asm/fixmap.h>
-#include <asm/kmap_types.h>
 
-#define PKMAP_BASE		((FIXADDR_START - \
+#define PKMAP_BASE		((FIXADDR_START -			\
 				  (LAST_PKMAP + 1) * PAGE_SIZE) & PMD_MASK)
 #define LAST_PKMAP		(PTRS_PER_PTE * DCACHE_N_COLORS)
 #define LAST_PKMAP_MASK		(LAST_PKMAP - 1)
@@ -68,6 +67,15 @@ static inline void flush_cache_kmaps(void)
 	flush_cache_all();
 }
 
+enum fixed_addresses kmap_local_map_idx(int type, unsigned long pfn);
+#define arch_kmap_local_map_idx		kmap_local_map_idx
+
+enum fixed_addresses kmap_local_unmap_idx(int type, unsigned long addr);
+#define arch_kmap_local_unmap_idx	kmap_local_unmap_idx
+
+#define arch_kmap_local_post_unmap(vaddr)	\
+	local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE)
+
 void kmap_init(void);
 
 #endif
arch/xtensa/mm/highmem.c +5 -41

72 lines not on this page · raw message

#40 lore raw

PATCH v3 18/37 highmem: Get rid of kmap_types.h

In reply to Thomas Gleixner

The header is not longer used and on alpha, ia64, openrisc, parisc and um it was completely unused anyway as these architectures have no highmem support.

---
V3: New patch

---
 arch/alpha/include/asm/kmap_types.h  |   15 ---------------
 arch/ia64/include/asm/kmap_types.h   |   13 -------------
 arch/openrisc/mm/init.c              |    1 -
 arch/openrisc/mm/ioremap.c           |    1 -
 arch/parisc/include/asm/kmap_types.h |   13 -------------
 arch/um/include/asm/fixmap.h         |    1 -
 arch/um/include/asm/kmap_types.h     |   13 -------------
 include/asm-generic/Kbuild           |    1 -
 include/asm-generic/kmap_types.h     |   11 -----------
 include/linux/highmem.h              |    2 --
 10 files changed, 71 deletions(-)
arch/alpha/include/asm/kmap_types.h deleted +0 -15
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-/* Dummy header just to define km_type. */
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define  __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif
arch/ia64/include/asm/kmap_types.h deleted +0 -13
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_KMAP_TYPES_H
-#define _ASM_IA64_KMAP_TYPES_H
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define  __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif /* _ASM_IA64_KMAP_TYPES_H */
arch/openrisc/mm/init.c +0 -1
@@ -33,7 +33,6 @@
 #include <asm/io.h>
 #include <asm/tlb.h>
 #include <asm/mmu_context.h>
-#include <asm/kmap_types.h>
 #include <asm/fixmap.h>
 #include <asm/tlbflush.h>
 #include <asm/sections.h>
arch/openrisc/mm/ioremap.c +0 -1
@@ -15,7 +15,6 @@
 #include <linux/io.h>
 #include <linux/pgtable.h>
 #include <asm/pgalloc.h>
-#include <asm/kmap_types.h>
 #include <asm/fixmap.h>
 #include <asm/bug.h>
 #include <linux/sched.h>
arch/parisc/include/asm/kmap_types.h deleted +0 -13
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define  __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif
arch/um/include/asm/fixmap.h +0 -1
@@ -3,7 +3,6 @@
 #define __UM_FIXMAP_H
 
 #include <asm/processor.h>
-#include <asm/kmap_types.h>
 #include <asm/archparam.h>
 #include <asm/page.h>
 #include <linux/threads.h>
arch/um/include/asm/kmap_types.h deleted +0 -13
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* 
- * Copyright (C) 2002 Jeff Dike ([email protected])
- */
-
-#ifndef __UM_KMAP_TYPES_H
-#define __UM_KMAP_TYPES_H
-
-/* No more #include "asm/arch/kmap_types.h" ! */
-
-#define KM_TYPE_NR 14
-
-#endif
include/asm-generic/Kbuild +0 -1
@@ -30,7 +30,6 @@ mandatory-y += irq.h
 mandatory-y += irq_regs.h
 mandatory-y += irq_work.h
 mandatory-y += kdebug.h
-mandatory-y += kmap_types.h
 mandatory-y += kmap_size.h
 mandatory-y += kprobes.h
 mandatory-y += linkage.h
include/asm-generic/kmap_types.h deleted +0 -11
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_GENERIC_KMAP_TYPES_H
-#define _ASM_GENERIC_KMAP_TYPES_H
-
-#ifdef __WITH_KM_FENCE
-# define KM_TYPE_NR 41
-#else
-# define KM_TYPE_NR 20
-#endif
-
-#endif
include/linux/highmem.h +0 -2
@@ -29,8 +29,6 @@ static inline void invalidate_kernel_vma
 }
 #endif
 
-#include <asm/kmap_types.h>
-
 /*
  * Outside of CONFIG_HIGHMEM to support X86 32bit iomap_atomic() cruft.
  */
#41 lore raw

[tip: core/mm] highmem: Get rid of kmap_types.h

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     d7029e4549691ecaf1ead536d3322a00bda85659
Gitweb:        https://git.kernel.org/tip/d7029e4549691ecaf1ead536d3322a00bda85659
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:30 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:58 +01:00

highmem: Get rid of kmap_types.h

The header is not longer used and on alpha, ia64, openrisc, parisc and um it was completely unused anyway as these architectures have no highmem support.

---
 arch/alpha/include/asm/kmap_types.h  | 15 ---------------
 arch/ia64/include/asm/kmap_types.h   | 13 -------------
 arch/openrisc/mm/init.c              |  1 -
 arch/openrisc/mm/ioremap.c           |  1 -
 arch/parisc/include/asm/kmap_types.h | 13 -------------
 arch/um/include/asm/fixmap.h         |  1 -
 arch/um/include/asm/kmap_types.h     | 13 -------------
 include/asm-generic/Kbuild           |  1 -
 include/asm-generic/kmap_types.h     | 11 -----------
 include/linux/highmem.h              |  2 --
 10 files changed, 71 deletions(-)
 delete mode 100644 arch/alpha/include/asm/kmap_types.h
 delete mode 100644 arch/ia64/include/asm/kmap_types.h
 delete mode 100644 arch/parisc/include/asm/kmap_types.h
 delete mode 100644 arch/um/include/asm/kmap_types.h
 delete mode 100644 include/asm-generic/kmap_types.h
arch/alpha/include/asm/kmap_types.h deleted +0 -15
deleted file mode 100644
index 651714b..0000000
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-/* Dummy header just to define km_type. */
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define  __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif
arch/ia64/include/asm/kmap_types.h deleted +0 -13
deleted file mode 100644
index 5c268cf..0000000
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_KMAP_TYPES_H
-#define _ASM_IA64_KMAP_TYPES_H
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define  __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif /* _ASM_IA64_KMAP_TYPES_H */
arch/openrisc/mm/init.c +0 -1
index 8348fea..bf9b231 100644
@@ -33,7 +33,6 @@
 #include <asm/io.h>
 #include <asm/tlb.h>
 #include <asm/mmu_context.h>
-#include <asm/kmap_types.h>
 #include <asm/fixmap.h>
 #include <asm/tlbflush.h>
 #include <asm/sections.h>
arch/openrisc/mm/ioremap.c +0 -1
index a978590..5aed97a 100644
@@ -15,7 +15,6 @@
 #include <linux/io.h>
 #include <linux/pgtable.h>
 #include <asm/pgalloc.h>
-#include <asm/kmap_types.h>
 #include <asm/fixmap.h>
 #include <asm/bug.h>
 #include <linux/sched.h>
arch/parisc/include/asm/kmap_types.h deleted +0 -13
deleted file mode 100644
index 3e70b5c..0000000
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-#define  __WITH_KM_FENCE
-#endif
-
-#include <asm-generic/kmap_types.h>
-
-#undef __WITH_KM_FENCE
-
-#endif
arch/um/include/asm/fixmap.h +0 -1
index 2c697a1..2efac58 100644
@@ -3,7 +3,6 @@
 #define __UM_FIXMAP_H
 
 #include <asm/processor.h>
-#include <asm/kmap_types.h>
 #include <asm/archparam.h>
 #include <asm/page.h>
 #include <linux/threads.h>
arch/um/include/asm/kmap_types.h deleted +0 -13
deleted file mode 100644
index b0bd12d..0000000
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* 
- * Copyright (C) 2002 Jeff Dike ([email protected])
- */
-
-#ifndef __UM_KMAP_TYPES_H
-#define __UM_KMAP_TYPES_H
-
-/* No more #include "asm/arch/kmap_types.h" ! */
-
-#define KM_TYPE_NR 14
-
-#endif
include/asm-generic/Kbuild +0 -1
index ed62d38..4365b9a 100644
@@ -30,7 +30,6 @@ mandatory-y += irq.h
 mandatory-y += irq_regs.h
 mandatory-y += irq_work.h
 mandatory-y += kdebug.h
-mandatory-y += kmap_types.h
 mandatory-y += kmap_size.h
 mandatory-y += kprobes.h
 mandatory-y += linkage.h
include/asm-generic/kmap_types.h deleted +0 -11
deleted file mode 100644
index 9f95b7b..0000000
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_GENERIC_KMAP_TYPES_H
-#define _ASM_GENERIC_KMAP_TYPES_H
-
-#ifdef __WITH_KM_FENCE
-# define KM_TYPE_NR 41
-#else
-# define KM_TYPE_NR 20
-#endif
-
-#endif
include/linux/highmem.h +0 -2
index 1222a31..de78869 100644
@@ -29,8 +29,6 @@ static inline void invalidate_kernel_vmap_range(void *vaddr, int size)
 }
 #endif
 
-#include <asm/kmap_types.h>
-
 /*
  * Outside of CONFIG_HIGHMEM to support X86 32bit iomap_atomic() cruft.
  */
#42 lore raw

PATCH v3 19/37 mm/highmem: Remove the old kmap_atomic cruft

In reply to Thomas Gleixner

All users gone.

---
 include/linux/highmem.h |   63 +++---------------------------------------------
 mm/highmem.c            |    7 -----
 2 files changed, 5 insertions(+), 65 deletions(-)
include/linux/highmem.h +4 -59
@@ -86,31 +86,16 @@ static inline void kunmap(struct page *p
  * be used in IRQ contexts, so in some (very limited) cases we need
  * it.
  */
-
-#ifndef CONFIG_KMAP_LOCAL
-void *kmap_atomic_high_prot(struct page *page, pgprot_t prot);
-void kunmap_atomic_high(void *kvaddr);
-
 static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
 {
 	preempt_disable();
 	pagefault_disable();
-	if (!PageHighMem(page))
-		return page_address(page);
-	return kmap_atomic_high_prot(page, prot);
-}
-
-static inline void __kunmap_atomic(void *vaddr)
-{
-	kunmap_atomic_high(vaddr);
+	return __kmap_local_page_prot(page, prot);
 }
-#else /* !CONFIG_KMAP_LOCAL */
 
-static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+static inline void *kmap_atomic(struct page *page)
 {
-	preempt_disable();
-	pagefault_disable();
-	return __kmap_local_page_prot(page, prot);
+	return kmap_atomic_prot(page, kmap_prot);
 }
 
 static inline void *kmap_atomic_pfn(unsigned long pfn)
@@ -125,13 +110,6 @@ static inline void __kunmap_atomic(void
 	kunmap_local_indexed(addr);
 }
 
-#endif /* CONFIG_KMAP_LOCAL */
-
-static inline void *kmap_atomic(struct page *page)
-{
-	return kmap_atomic_prot(page, kmap_prot);
-}
-
 /* declarations for linux/mm/highmem.c */
 unsigned int nr_free_highpages(void);
 extern atomic_long_t _totalhigh_pages;
@@ -212,41 +190,8 @@ static inline void __kunmap_atomic(void
 
 #define kmap_flush_unused()	do {} while(0)
 
-#endif /* CONFIG_HIGHMEM */
-
-#if !defined(CONFIG_KMAP_LOCAL)
-#if defined(CONFIG_HIGHMEM)
-
-DECLARE_PER_CPU(int, __kmap_atomic_idx);
-
-static inline int kmap_atomic_idx_push(void)
-{
-	int idx = __this_cpu_inc_return(__kmap_atomic_idx) - 1;
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-	WARN_ON_ONCE(in_irq() && !irqs_disabled());
-	BUG_ON(idx >= KM_TYPE_NR);
-#endif
-	return idx;
-}
-
-static inline int kmap_atomic_idx(void)
-{
-	return __this_cpu_read(__kmap_atomic_idx) - 1;
-}
 
-static inline void kmap_atomic_idx_pop(void)
-{
-#ifdef CONFIG_DEBUG_HIGHMEM
-	int idx = __this_cpu_dec_return(__kmap_atomic_idx);
-
-	BUG_ON(idx < 0);
-#else
-	__this_cpu_dec(__kmap_atomic_idx);
-#endif
-}
-#endif
-#endif
+#endif /* CONFIG_HIGHMEM */
 
 /*
  * Prevent people trying to call kunmap_atomic() as if it were kunmap()
mm/highmem.c +1 -6
@@ -31,12 +31,6 @@
 #include <asm/tlbflush.h>
 #include <linux/vmalloc.h>
 
-#ifndef CONFIG_KMAP_LOCAL
-#ifdef CONFIG_HIGHMEM
-DEFINE_PER_CPU(int, __kmap_atomic_idx);
-#endif
-#endif
-
 /*
  * Virtual_count is not a pure "count".
  *  0 means that it is not mapped, and has not been mapped
@@ -410,6 +404,7 @@ static inline void kmap_local_idx_pop(vo
 #ifndef arch_kmap_local_post_map
 # define arch_kmap_local_post_map(vaddr, pteval)	do { } while (0)
 #endif
+
 #ifndef arch_kmap_local_pre_unmap
 # define arch_kmap_local_pre_unmap(vaddr)		do { } while (0)
 #endif
#43 lore raw

[tip: core/mm] mm/highmem: Remove the old kmap_atomic cruft

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     3c1016b53c311906878c703af1e2b29855a9a962
Gitweb:        https://git.kernel.org/tip/3c1016b53c311906878c703af1e2b29855a9a962
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:31 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:58 +01:00

mm/highmem: Remove the old kmap_atomic cruft

All users gone.

---
 include/linux/highmem.h | 63 ++--------------------------------------
 mm/highmem.c            |  7 +----
 2 files changed, 5 insertions(+), 65 deletions(-)
include/linux/highmem.h +4 -59
index de78869..3180a8f 100644
@@ -86,31 +86,16 @@ static inline void kunmap(struct page *page)
  * be used in IRQ contexts, so in some (very limited) cases we need
  * it.
  */
-
-#ifndef CONFIG_KMAP_LOCAL
-void *kmap_atomic_high_prot(struct page *page, pgprot_t prot);
-void kunmap_atomic_high(void *kvaddr);
-
 static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
 {
 	preempt_disable();
 	pagefault_disable();
-	if (!PageHighMem(page))
-		return page_address(page);
-	return kmap_atomic_high_prot(page, prot);
-}
-
-static inline void __kunmap_atomic(void *vaddr)
-{
-	kunmap_atomic_high(vaddr);
+	return __kmap_local_page_prot(page, prot);
 }
-#else /* !CONFIG_KMAP_LOCAL */
 
-static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+static inline void *kmap_atomic(struct page *page)
 {
-	preempt_disable();
-	pagefault_disable();
-	return __kmap_local_page_prot(page, prot);
+	return kmap_atomic_prot(page, kmap_prot);
 }
 
 static inline void *kmap_atomic_pfn(unsigned long pfn)
@@ -125,13 +110,6 @@ static inline void __kunmap_atomic(void *addr)
 	kunmap_local_indexed(addr);
 }
 
-#endif /* CONFIG_KMAP_LOCAL */
-
-static inline void *kmap_atomic(struct page *page)
-{
-	return kmap_atomic_prot(page, kmap_prot);
-}
-
 /* declarations for linux/mm/highmem.c */
 unsigned int nr_free_highpages(void);
 extern atomic_long_t _totalhigh_pages;
@@ -212,41 +190,8 @@ static inline void __kunmap_atomic(void *addr)
 
 #define kmap_flush_unused()	do {} while(0)
 
-#endif /* CONFIG_HIGHMEM */
-
-#if !defined(CONFIG_KMAP_LOCAL)
-#if defined(CONFIG_HIGHMEM)
-
-DECLARE_PER_CPU(int, __kmap_atomic_idx);
-
-static inline int kmap_atomic_idx_push(void)
-{
-	int idx = __this_cpu_inc_return(__kmap_atomic_idx) - 1;
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-	WARN_ON_ONCE(in_irq() && !irqs_disabled());
-	BUG_ON(idx >= KM_TYPE_NR);
-#endif
-	return idx;
-}
-
-static inline int kmap_atomic_idx(void)
-{
-	return __this_cpu_read(__kmap_atomic_idx) - 1;
-}
 
-static inline void kmap_atomic_idx_pop(void)
-{
-#ifdef CONFIG_DEBUG_HIGHMEM
-	int idx = __this_cpu_dec_return(__kmap_atomic_idx);
-
-	BUG_ON(idx < 0);
-#else
-	__this_cpu_dec(__kmap_atomic_idx);
-#endif
-}
-#endif
-#endif
+#endif /* CONFIG_HIGHMEM */
 
 /*
  * Prevent people trying to call kunmap_atomic() as if it were kunmap()
mm/highmem.c +1 -6
index 77677c6..499dfaf 100644
@@ -31,12 +31,6 @@
 #include <asm/tlbflush.h>
 #include <linux/vmalloc.h>
 
-#ifndef CONFIG_KMAP_LOCAL
-#ifdef CONFIG_HIGHMEM
-DEFINE_PER_CPU(int, __kmap_atomic_idx);
-#endif
-#endif
-
 /*
  * Virtual_count is not a pure "count".
  *  0 means that it is not mapped, and has not been mapped
@@ -410,6 +404,7 @@ static inline void kmap_local_idx_pop(void)
 #ifndef arch_kmap_local_post_map
 # define arch_kmap_local_post_map(vaddr, pteval)	do { } while (0)
 #endif
+
 #ifndef arch_kmap_local_pre_unmap
 # define arch_kmap_local_pre_unmap(vaddr)		do { } while (0)
 #endif
#44 lore raw

PATCH v3 20/37 io-mapping: Cleanup atomic iomap

In reply to Thomas Gleixner

Switch the atomic iomap implementation over to kmap_local and stick the preempt/pagefault mechanics into the generic code similar to the kmap_atomic variants.

Rename the x86 map function in preparation for a non-atomic variant.

---
V2: New patch to make review easier

---
 arch/x86/include/asm/iomap.h |    9 +--------
 arch/x86/mm/iomap_32.c       |    6 ++----
 include/linux/io-mapping.h   |    8 ++++++--
 3 files changed, 9 insertions(+), 14 deletions(-)
arch/x86/include/asm/iomap.h +1 -8
@@ -13,14 +13,7 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
-void __iomem *iomap_atomic_pfn_prot(unsigned long pfn, pgprot_t prot);
-
-static inline void iounmap_atomic(void __iomem *vaddr)
-{
-	kunmap_local_indexed((void __force *)vaddr);
-	pagefault_enable();
-	preempt_enable();
-}
+void __iomem *__iomap_local_pfn_prot(unsigned long pfn, pgprot_t prot);
 
 int iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot);
 
arch/x86/mm/iomap_32.c +2 -4
@@ -44,7 +44,7 @@ void iomap_free(resource_size_t base, un
 }
 EXPORT_SYMBOL_GPL(iomap_free);
 
-void __iomem *iomap_atomic_pfn_prot(unsigned long pfn, pgprot_t prot)
+void __iomem *__iomap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
 {
 	/*
 	 * For non-PAT systems, translate non-WB request to UC- just in
@@ -60,8 +60,6 @@ void __iomem *iomap_atomic_pfn_prot(unsi
 	/* Filter out unsupported __PAGE_KERNEL* bits: */
 	pgprot_val(prot) &= __default_kernel_pte_mask;
 
-	preempt_disable();
-	pagefault_disable();
 	return (void __force __iomem *)__kmap_local_pfn_prot(pfn, prot);
 }
-EXPORT_SYMBOL_GPL(iomap_atomic_pfn_prot);
+EXPORT_SYMBOL_GPL(__iomap_local_pfn_prot);
include/linux/io-mapping.h +6 -2
@@ -69,13 +69,17 @@ io_mapping_map_atomic_wc(struct io_mappi
 
 	BUG_ON(offset >= mapping->size);
 	phys_addr = mapping->base + offset;
-	return iomap_atomic_pfn_prot(PHYS_PFN(phys_addr), mapping->prot);
+	preempt_disable();
+	pagefault_disable();
+	return __iomap_local_pfn_prot(PHYS_PFN(phys_addr), mapping->prot);
 }
 
 static inline void
 io_mapping_unmap_atomic(void __iomem *vaddr)
 {
-	iounmap_atomic(vaddr);
+	kunmap_local_indexed((void __force *)vaddr);
+	pagefault_enable();
+	preempt_enable();
 }
 
 static inline void __iomem *
#45 lore raw

[tip: core/mm] io-mapping: Cleanup atomic iomap

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     351191ad55c8a1eccaf23e4187c62056229c0779
Gitweb:        https://git.kernel.org/tip/351191ad55c8a1eccaf23e4187c62056229c0779
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:32 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:58 +01:00

io-mapping: Cleanup atomic iomap

Switch the atomic iomap implementation over to kmap_local and stick the preempt/pagefault mechanics into the generic code similar to the kmap_atomic variants.

Rename the x86 map function in preparation for a non-atomic variant.

---
 arch/x86/include/asm/iomap.h |  9 +--------
 arch/x86/mm/iomap_32.c       |  6 ++----
 include/linux/io-mapping.h   |  8 ++++++--
 3 files changed, 9 insertions(+), 14 deletions(-)
arch/x86/include/asm/iomap.h +1 -8
index 0be7a30..e2de092 100644
@@ -13,14 +13,7 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
-void __iomem *iomap_atomic_pfn_prot(unsigned long pfn, pgprot_t prot);
-
-static inline void iounmap_atomic(void __iomem *vaddr)
-{
-	kunmap_local_indexed((void __force *)vaddr);
-	pagefault_enable();
-	preempt_enable();
-}
+void __iomem *__iomap_local_pfn_prot(unsigned long pfn, pgprot_t prot);
 
 int iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot);
 
arch/x86/mm/iomap_32.c +2 -4
index e0a40d7..9aaa756 100644
@@ -44,7 +44,7 @@ void iomap_free(resource_size_t base, unsigned long size)
 }
 EXPORT_SYMBOL_GPL(iomap_free);
 
-void __iomem *iomap_atomic_pfn_prot(unsigned long pfn, pgprot_t prot)
+void __iomem *__iomap_local_pfn_prot(unsigned long pfn, pgprot_t prot)
 {
 	/*
 	 * For non-PAT systems, translate non-WB request to UC- just in
@@ -60,8 +60,6 @@ void __iomem *iomap_atomic_pfn_prot(unsigned long pfn, pgprot_t prot)
 	/* Filter out unsupported __PAGE_KERNEL* bits: */
 	pgprot_val(prot) &= __default_kernel_pte_mask;
 
-	preempt_disable();
-	pagefault_disable();
 	return (void __force __iomem *)__kmap_local_pfn_prot(pfn, prot);
 }
-EXPORT_SYMBOL_GPL(iomap_atomic_pfn_prot);
+EXPORT_SYMBOL_GPL(__iomap_local_pfn_prot);
include/linux/io-mapping.h +6 -2
index 3b0940b..60e7c83 100644
@@ -69,13 +69,17 @@ io_mapping_map_atomic_wc(struct io_mapping *mapping,
 
 	BUG_ON(offset >= mapping->size);
 	phys_addr = mapping->base + offset;
-	return iomap_atomic_pfn_prot(PHYS_PFN(phys_addr), mapping->prot);
+	preempt_disable();
+	pagefault_disable();
+	return __iomap_local_pfn_prot(PHYS_PFN(phys_addr), mapping->prot);
 }
 
 static inline void
 io_mapping_unmap_atomic(void __iomem *vaddr)
 {
-	iounmap_atomic(vaddr);
+	kunmap_local_indexed((void __force *)vaddr);
+	pagefault_enable();
+	preempt_enable();
 }
 
 static inline void __iomem *
#46 lore raw

PATCH v3 21/37 Documentation/io-mapping: Remove outdated blurb

In reply to Thomas Gleixner

The implementation details in the documentation are outdated and not really helpful. Remove them.

---
V3: New patch

---
 Documentation/driver-api/io-mapping.rst |   22 ----------------------
 1 file changed, 22 deletions(-)
Documentation/driver-api/io-mapping.rst +0 -22
@@ -73,25 +73,3 @@ for pages mapped with io_mapping_map_wc.
 At driver close time, the io_mapping object must be freed::
 
 	void io_mapping_free(struct io_mapping *mapping)
-
-Current Implementation
-======================
-
-The initial implementation of these functions uses existing mapping
-mechanisms and so provides only an abstraction layer and no new
-functionality.
-
-On 64-bit processors, io_mapping_create_wc calls ioremap_wc for the whole
-range, creating a permanent kernel-visible mapping to the resource. The
-map_atomic and map functions add the requested offset to the base of the
-virtual address returned by ioremap_wc.
-
-On 32-bit processors with HIGHMEM defined, io_mapping_map_atomic_wc uses
-kmap_atomic_pfn to map the specified page in an atomic fashion;
-kmap_atomic_pfn isn't really supposed to be used with device pages, but it
-provides an efficient mapping for this usage.
-
-On 32-bit processors without HIGHMEM defined, io_mapping_map_atomic_wc and
-io_mapping_map_wc both use ioremap_wc, a terribly inefficient function which
-performs an IPI to inform all processors about the new mapping. This results
-in a significant performance penalty.
#47 lore raw

[tip: core/mm] Documentation/io-mapping: Remove outdated blurb

The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     9bf6f7bab3bad4b30f108fca25aa5297dff0973f
Gitweb:        https://git.kernel.org/tip/9bf6f7bab3bad4b30f108fca25aa5297dff0973f
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:33 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:58 +01:00

Documentation/io-mapping: Remove outdated blurb

The implementation details in the documentation are outdated and not really helpful. Remove them.

---
 Documentation/driver-api/io-mapping.rst | 22 ----------------------
 1 file changed, 22 deletions(-)
Documentation/driver-api/io-mapping.rst +0 -22
index a966239..e33b882 100644
@@ -73,25 +73,3 @@ for pages mapped with io_mapping_map_wc.
 At driver close time, the io_mapping object must be freed::
 
 	void io_mapping_free(struct io_mapping *mapping)
-
-Current Implementation
-======================
-
-The initial implementation of these functions uses existing mapping
-mechanisms and so provides only an abstraction layer and no new
-functionality.
-
-On 64-bit processors, io_mapping_create_wc calls ioremap_wc for the whole
-range, creating a permanent kernel-visible mapping to the resource. The
-map_atomic and map functions add the requested offset to the base of the
-virtual address returned by ioremap_wc.
-
-On 32-bit processors with HIGHMEM defined, io_mapping_map_atomic_wc uses
-kmap_atomic_pfn to map the specified page in an atomic fashion;
-kmap_atomic_pfn isn't really supposed to be used with device pages, but it
-provides an efficient mapping for this usage.
-
-On 32-bit processors without HIGHMEM defined, io_mapping_map_atomic_wc and
-io_mapping_map_wc both use ioremap_wc, a terribly inefficient function which
-performs an IPI to inform all processors about the new mapping. This results
-in a significant performance penalty.
#48 lore raw

PATCH v3 22/37 highmem: High implementation details and document API

In reply to Thomas Gleixner

Move the gory details of kmap & al into a private header and only document the interfaces which are usable by drivers.

---
V3: New patch

---
 include/linux/highmem-internal.h |  174 +++++++++++++++++++++++++
 include/linux/highmem.h          |  270 ++++++++++++++-------------------------
 mm/highmem.c                     |   11 -
 3 files changed, 276 insertions(+), 179 deletions(-)
include/linux/highmem-internal.h new file +174 -0
@@ -0,0 +1,174 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_HIGHMEM_INTERNAL_H
+#define _LINUX_HIGHMEM_INTERNAL_H
+
+/*
+ * Outside of CONFIG_HIGHMEM to support X86 32bit iomap_atomic() cruft.
+ */
+#ifdef CONFIG_KMAP_LOCAL
+void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot);
+void *__kmap_local_page_prot(struct page *page, pgprot_t prot);
+void kunmap_local_indexed(void *vaddr);
+#endif
+
+#ifdef CONFIG_HIGHMEM
+#include <asm/highmem.h>
+
+#ifndef ARCH_HAS_KMAP_FLUSH_TLB
+static inline void kmap_flush_tlb(unsigned long addr) { }
+#endif
+
+#ifndef kmap_prot
+#define kmap_prot PAGE_KERNEL
+#endif
+
+void *kmap_high(struct page *page);
+void kunmap_high(struct page *page);
+void __kmap_flush_unused(void);
+struct page *__kmap_to_page(void *addr);
+
+static inline void *kmap(struct page *page)
+{
+	void *addr;
+
+	might_sleep();
+	if (!PageHighMem(page))
+		addr = page_address(page);
+	else
+		addr = kmap_high(page);
+	kmap_flush_tlb((unsigned long)addr);
+	return addr;
+}
+
+static inline void kunmap(struct page *page)
+{
+	might_sleep();
+	if (!PageHighMem(page))
+		return;
+	kunmap_high(page);
+}
+
+static inline struct page *kmap_to_page(void *addr)
+{
+	return __kmap_to_page(addr);
+}
+
+static inline void kmap_flush_unused(void)
+{
+	__kmap_flush_unused();
+}
+
+static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+{
+	preempt_disable();
+	pagefault_disable();
+	return __kmap_local_page_prot(page, prot);
+}
+
+static inline void *kmap_atomic(struct page *page)
+{
+	return kmap_atomic_prot(page, kmap_prot);
+}
+
+static inline void *kmap_atomic_pfn(unsigned long pfn)
+{
+	preempt_disable();
+	pagefault_disable();
+	return __kmap_local_pfn_prot(pfn, kmap_prot);
+}
+
+static inline void __kunmap_atomic(void *addr)
+{
+	kunmap_local_indexed(addr);
+	pagefault_enable();
+	preempt_enable();
+}
+
+unsigned int __nr_free_highpages(void);
+extern atomic_long_t _totalhigh_pages;
+
+static inline unsigned int nr_free_highpages(void)
+{
+	return __nr_free_highpages();
+}
+
+static inline unsigned long totalhigh_pages(void)
+{
+	return (unsigned long)atomic_long_read(&_totalhigh_pages);
+}
+
+static inline void totalhigh_pages_inc(void)
+{
+	atomic_long_inc(&_totalhigh_pages);
+}
+
+static inline void totalhigh_pages_add(long count)
+{
+	atomic_long_add(count, &_totalhigh_pages);
+}
+
+#else /* CONFIG_HIGHMEM */
+
+static inline struct page *kmap_to_page(void *addr)
+{
+	return virt_to_page(addr);
+}
+
+static inline void *kmap(struct page *page)
+{
+	might_sleep();
+	return page_address(page);
+}
+
+static inline void kunmap_high(struct page *page) { }
+static inline void kmap_flush_unused(void) { }
+
+static inline void kunmap(struct page *page)
+{
+#ifdef ARCH_HAS_FLUSH_ON_KUNMAP
+	kunmap_flush_on_unmap(page_address(page));
+#endif
+}
+
+static inline void *kmap_atomic(struct page *page)
+{
+	preempt_disable();
+	pagefault_disable();
+	return page_address(page);
+}
+
+static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+{
+	return kmap_atomic(page);
+}
+
+static inline void *kmap_atomic_pfn(unsigned long pfn)
+{
+	return kmap_atomic(pfn_to_page(pfn));
+}
+
+static inline void __kunmap_atomic(void *addr)
+{
+#ifdef ARCH_HAS_FLUSH_ON_KUNMAP
+	kunmap_flush_on_unmap(addr);
+#endif
+	pagefault_enable();
+	preempt_enable();
+}
+
+static inline unsigned int nr_free_highpages(void) { return 0; }
+static inline unsigned long totalhigh_pages(void) { return 0UL; }
+
+#endif /* CONFIG_HIGHMEM */
+
+/*
+ * Prevent people trying to call kunmap_atomic() as if it were kunmap()
+ * kunmap_atomic() should get the return value of kmap_atomic, not the page.
+ */
+#define kunmap_atomic(__addr)					\
+do {								\
+	BUILD_BUG_ON(__same_type((__addr), struct page *));	\
+	__kunmap_atomic(__addr);				\
+} while (0)
+
+#endif
include/linux/highmem.h +98 -172

297 lines not on this page · raw message

mm/highmem.c +4 -7
@@ -104,7 +104,7 @@ static inline wait_queue_head_t *get_pkm
 atomic_long_t _totalhigh_pages __read_mostly;
 EXPORT_SYMBOL(_totalhigh_pages);
 
-unsigned int nr_free_highpages (void)
+unsigned int __nr_free_highpages (void)
 {
 	struct zone *zone;
 	unsigned int pages = 0;
@@ -141,7 +141,7 @@ pte_t * pkmap_page_table;
 		do { spin_unlock(&kmap_lock); (void)(flags); } while (0)
 #endif
 
-struct page *kmap_to_page(void *vaddr)
+struct page *__kmap_to_page(void *vaddr)
 {
 	unsigned long addr = (unsigned long)vaddr;
 
@@ -152,7 +152,7 @@ struct page *kmap_to_page(void *vaddr)
 
 	return virt_to_page(addr);
 }
-EXPORT_SYMBOL(kmap_to_page);
+EXPORT_SYMBOL(__kmap_to_page);
 
 static void flush_all_zero_pkmaps(void)
 {
@@ -194,10 +194,7 @@ static void flush_all_zero_pkmaps(void)
 		flush_tlb_kernel_range(PKMAP_ADDR(0), PKMAP_ADDR(LAST_PKMAP));
 }
 
-/**
- * kmap_flush_unused - flush all unused kmap mappings in order to remove stray mappings
- */
-void kmap_flush_unused(void)
+void __kmap_flush_unused(void)
 {
 	lock_kmap();
 	flush_all_zero_pkmaps();
#49 lore raw

Re: [patch V3 22/37] highmem: High implementation details and document API

Quoted 11 lines · Thomas Gleixner
include/linux/highmem-internal.h new file +10 -0
+static inline void *kmap(struct page *page)
+{
+       void *addr;
+
+       might_sleep();
+       if (!PageHighMem(page))
+               addr = page_address(page);
+       else
+               addr = kmap_high(page);
+       kmap_flush_tlb((unsigned long)addr);

include/linux/highmem-internal.h line 49

Quoted 10 lines
include/linux/highmem-internal.h new file +10 -0
+       return addr;
+}
+
+static inline void kunmap(struct page *page)
+{
+       might_sleep();
+       if (!PageHighMem(page))
+               return;
+       kunmap_high(page);
+}

I have no complaints about the patch, but it strikes me that if people want to actually have much better debug coverage, this is where it should be (I like the "every other address" thing too, don't get me wrong).

In particular, instead of these PageHighMem(page) tests, I think something like this would be better:

   #ifdef CONFIG_DEBUG_HIGHMEM
     #define page_use_kmap(page) ((page),1)
   #else
     #define page_use_kmap(page) PageHighMem(page)
   #endif

adn then replace those "if (!PageHighMem(page))" tests with "if (!page_use_kmap())" instead.

IOW, in debug mode, it would _always_ remap the page, whether it's highmem or not. That would really stress the highmem code and find any fragilities.

No?

Anyway, this is all sepatrate from the series, which still looks fine to me. Just a reaction to seeing the patch, and Thomas' earlier mention that the highmem debugging doesn't actually do much.

Linus

#50 lore raw

Re: [patch V3 22/37] highmem: High implementation details and document API

Quoted 14 lines · Linus Torvalds

I have no complaints about the patch, but it strikes me that if people want to actually have much better debug coverage, this is where it should be (I like the "every other address" thing too, don't get me wrong).

In particular, instead of these PageHighMem(page) tests, I think something like this would be better:

   #ifdef CONFIG_DEBUG_HIGHMEM
     #define page_use_kmap(page) ((page),1)
   #else
     #define page_use_kmap(page) PageHighMem(page)
   #endif
Quoted 6 lines

adn then replace those "if (!PageHighMem(page))" tests with "if (!page_use_kmap())" instead.

IOW, in debug mode, it would _always_ remap the page, whether it's highmem or not. That would really stress the highmem code and find any fragilities.

Yes, that makes a lot of sense. We just have to avoid that for the architectures with aliasing issues.

Quoted 3 lines

Anyway, this is all sepatrate from the series, which still looks fine to me. Just a reaction to seeing the patch, and Thomas' earlier mention that the highmem debugging doesn't actually do much.

Right, forcing it for both kmap and kmap_local is straight forward. I'll cook a patch on top for that.

Thanks,

tglx

#51 lore raw

[tip: core/mm] highmem: High implementation details and document API

In reply to Thomas Gleixner
The following commit has been merged into the core/mm branch of tip:

The following commit has been merged into the core/mm branch of tip:

Commit-ID:     13f876ba77ebd5125799bb042201f22cf73df154
Gitweb:        https://git.kernel.org/tip/13f876ba77ebd5125799bb042201f22cf73df154
Author:        Thomas Gleixner <[email protected]>
AuthorDate:    Tue, 03 Nov 2020 10:27:34 +01:00
Committer:     Thomas Gleixner <[email protected]>
CommitterDate: Fri, 06 Nov 2020 23:14:59 +01:00

highmem: High implementation details and document API

Move the gory details of kmap & al into a private header and only document the interfaces which are usable by drivers.

---
 include/linux/highmem-internal.h | 174 ++++++++++++++++++++-
 include/linux/highmem.h          | 266 ++++++++++--------------------
 mm/highmem.c                     |  11 +-
 3 files changed, 274 insertions(+), 177 deletions(-)
 create mode 100644 include/linux/highmem-internal.h
include/linux/highmem-internal.h new file +174 -0
new file mode 100644
index 0000000..6ceed90
@@ -0,0 +1,174 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_HIGHMEM_INTERNAL_H
+#define _LINUX_HIGHMEM_INTERNAL_H
+
+/*
+ * Outside of CONFIG_HIGHMEM to support X86 32bit iomap_atomic() cruft.
+ */
+#ifdef CONFIG_KMAP_LOCAL
+void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot);
+void *__kmap_local_page_prot(struct page *page, pgprot_t prot);
+void kunmap_local_indexed(void *vaddr);
+#endif
+
+#ifdef CONFIG_HIGHMEM
+#include <asm/highmem.h>
+
+#ifndef ARCH_HAS_KMAP_FLUSH_TLB
+static inline void kmap_flush_tlb(unsigned long addr) { }
+#endif
+
+#ifndef kmap_prot
+#define kmap_prot PAGE_KERNEL
+#endif
+
+void *kmap_high(struct page *page);
+void kunmap_high(struct page *page);
+void __kmap_flush_unused(void);
+struct page *__kmap_to_page(void *addr);
+
+static inline void *kmap(struct page *page)
+{
+	void *addr;
+
+	might_sleep();
+	if (!PageHighMem(page))
+		addr = page_address(page);
+	else
+		addr = kmap_high(page);
+	kmap_flush_tlb((unsigned long)addr);
+	return addr;
+}
+
+static inline void kunmap(struct page *page)
+{
+	might_sleep();
+	if (!PageHighMem(page))
+		return;
+	kunmap_high(page);
+}
+
+static inline struct page *kmap_to_page(void *addr)
+{
+	return __kmap_to_page(addr);
+}
+
+static inline void kmap_flush_unused(void)
+{
+	__kmap_flush_unused();
+}
+
+static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+{
+	preempt_disable();
+	pagefault_disable();
+	return __kmap_local_page_prot(page, prot);
+}
+
+static inline void *kmap_atomic(struct page *page)
+{
+	return kmap_atomic_prot(page, kmap_prot);
+}
+
+static inline void *kmap_atomic_pfn(unsigned long pfn)
+{
+	preempt_disable();
+	pagefault_disable();
+	return __kmap_local_pfn_prot(pfn, kmap_prot);
+}
+
+static inline void __kunmap_atomic(void *addr)
+{
+	kunmap_local_indexed(addr);
+	pagefault_enable();
+	preempt_enable();
+}
+
+unsigned int __nr_free_highpages(void);
+extern atomic_long_t _totalhigh_pages;
+
+static inline unsigned int nr_free_highpages(void)
+{
+	return __nr_free_highpages();
+}
+
+static inline unsigned long totalhigh_pages(void)
+{
+	return (unsigned long)atomic_long_read(&_totalhigh_pages);
+}
+
+static inline void totalhigh_pages_inc(void)
+{
+	atomic_long_inc(&_totalhigh_pages);
+}
+
+static inline void totalhigh_pages_add(long count)
+{
+	atomic_long_add(count, &_totalhigh_pages);
+}
+
+#else /* CONFIG_HIGHMEM */
+
+static inline struct page *kmap_to_page(void *addr)
+{
+	return virt_to_page(addr);
+}
+
+static inline void *kmap(struct page *page)
+{
+	might_sleep();
+	return page_address(page);
+}
+
+static inline void kunmap_high(struct page *page) { }
+static inline void kmap_flush_unused(void) { }
+
+static inline void kunmap(struct page *page)
+{
+#ifdef ARCH_HAS_FLUSH_ON_KUNMAP
+	kunmap_flush_on_unmap(page_address(page));
+#endif
+}
+
+static inline void *kmap_atomic(struct page *page)
+{
+	preempt_disable();
+	pagefault_disable();
+	return page_address(page);
+}
+
+static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+{
+	return kmap_atomic(page);
+}
+
+static inline void *kmap_atomic_pfn(unsigned long pfn)
+{
+	return kmap_atomic(pfn_to_page(pfn));
+}
+
+static inline void __kunmap_atomic(void *addr)
+{
+#ifdef ARCH_HAS_FLUSH_ON_KUNMAP
+	kunmap_flush_on_unmap(addr);
+#endif
+	pagefault_enable();
+	preempt_enable();
+}
+
+static inline unsigned int nr_free_highpages(void) { return 0; }
+static inline unsigned long totalhigh_pages(void) { return 0UL; }
+
+#endif /* CONFIG_HIGHMEM */
+
+/*
+ * Prevent people trying to call kunmap_atomic() as if it were kunmap()
+ * kunmap_atomic() should get the return value of kmap_atomic, not the page.
+ */
+#define kunmap_atomic(__addr)					\
+do {								\
+	BUILD_BUG_ON(__same_type((__addr), struct page *));	\
+	__kunmap_atomic(__addr);				\
+} while (0)
+
+#endif
include/linux/highmem.h +96 -170

295 lines not on this page · raw message

mm/highmem.c +4 -7
index 499dfaf..54bd233 100644
@@ -104,7 +104,7 @@ static inline wait_queue_head_t *get_pkmap_wait_queue_head(unsigned int color)
 atomic_long_t _totalhigh_pages __read_mostly;
 EXPORT_SYMBOL(_totalhigh_pages);
 
-unsigned int nr_free_highpages (void)
+unsigned int __nr_free_highpages (void)
 {
 	struct zone *zone;
 	unsigned int pages = 0;
@@ -141,7 +141,7 @@ pte_t * pkmap_page_table;
 		do { spin_unlock(&kmap_lock); (void)(flags); } while (0)
 #endif
 
-struct page *kmap_to_page(void *vaddr)
+struct page *__kmap_to_page(void *vaddr)
 {
 	unsigned long addr = (unsigned long)vaddr;
 
@@ -152,7 +152,7 @@ struct page *kmap_to_page(void *vaddr)
 
 	return virt_to_page(addr);
 }
-EXPORT_SYMBOL(kmap_to_page);
+EXPORT_SYMBOL(__kmap_to_page);
 
 static void flush_all_zero_pkmaps(void)
 {
@@ -194,10 +194,7 @@ static void flush_all_zero_pkmaps(void)
 		flush_tlb_kernel_range(PKMAP_ADDR(0), PKMAP_ADDR(LAST_PKMAP));
 }
 
-/**
- * kmap_flush_unused - flush all unused kmap mappings in order to remove stray mappings
- */
-void kmap_flush_unused(void)
+void __kmap_flush_unused(void)
 {
 	lock_kmap();
 	flush_all_zero_pkmaps();
#52 lore raw

PATCH v3 23/37 sched: Make migrate_disable/enable() independent of RT

In reply to Thomas Gleixner

Now that the scheduler can deal with migrate disable properly, there is no real compelling reason to make it only available for RT.

There are quite some code pathes which needlessly disable preemption in order to prevent migration and some constructs like kmap_atomic() enforce it implicitly.

Making it available independent of RT allows to provide a preemptible variant of kmap_atomic() and makes the code more consistent in general.

FIXME: Rework the comment in preempt.h

Cc Peter Zijlstra <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Juri Lelli <[email protected]>
Cc Vincent Guittot <[email protected]>
Cc Dietmar Eggemann <[email protected]>
Cc Steven Rostedt <[email protected]>
Cc Ben Segall <[email protected]>
Cc Mel Gorman <[email protected]>
Cc Daniel Bristot de Oliveira <[email protected]>
---
 include/linux/kernel.h  |   21 ++++++++++++++-------
 include/linux/preempt.h |   38 +++-----------------------------------
 include/linux/sched.h   |    2 +-
 kernel/sched/core.c     |   45 +++++++++++++++++++++++++++++++++++----------
 kernel/sched/sched.h    |    4 ++--
 lib/smp_processor_id.c  |    2 +-
 6 files changed, 56 insertions(+), 56 deletions(-)
include/linux/kernel.h +14 -7
@@ -204,6 +204,7 @@ extern int _cond_resched(void);
 extern void ___might_sleep(const char *file, int line, int preempt_offset);
 extern void __might_sleep(const char *file, int line, int preempt_offset);
 extern void __cant_sleep(const char *file, int line, int preempt_offset);
+extern void __cant_migrate(const char *file, int line);
 
 /**
  * might_sleep - annotation for functions that can sleep
@@ -227,6 +228,18 @@ extern void __cant_sleep(const char *fil
 # define cant_sleep() \
 	do { __cant_sleep(__FILE__, __LINE__, 0); } while (0)
 # define sched_annotate_sleep()	(current->task_state_change = 0)
+
+/**
+ * cant_migrate - annotation for functions that cannot migrate
+ *
+ * Will print a stack trace if executed in code which is migratable
+ */
+# define cant_migrate()							\
+	do {								\
+		if (IS_ENABLED(CONFIG_SMP))				\
+			__cant_migrate(__FILE__, __LINE__);		\
+	} while (0)
+
 /**
  * non_block_start - annotate the start of section where sleeping is prohibited
  *
@@ -251,6 +264,7 @@ extern void __cant_sleep(const char *fil
 				   int preempt_offset) { }
 # define might_sleep() do { might_resched(); } while (0)
 # define cant_sleep() do { } while (0)
+# define cant_migrate()		do { } while (0)
 # define sched_annotate_sleep() do { } while (0)
 # define non_block_start() do { } while (0)
 # define non_block_end() do { } while (0)
@@ -258,13 +272,6 @@ extern void __cant_sleep(const char *fil
 
 #define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0)
 
-#ifndef CONFIG_PREEMPT_RT
-# define cant_migrate()		cant_sleep()
-#else
-  /* Placeholder for now */
-# define cant_migrate()		do { } while (0)
-#endif
-
 /**
  * abs - return absolute value of an argument
  * @x: the value.  If it is unsigned type, it is converted to signed type first.
include/linux/preempt.h +3 -35
@@ -322,7 +322,7 @@ static inline void preempt_notifier_init
 
 #endif
 
-#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT)
+#ifdef CONFIG_SMP
 
 /*
  * Migrate-Disable and why it is undesired.
@@ -382,43 +382,11 @@ static inline void preempt_notifier_init
 extern void migrate_disable(void);
 extern void migrate_enable(void);
 
-#elif defined(CONFIG_PREEMPT_RT)
+#else
 
 static inline void migrate_disable(void) { }
 static inline void migrate_enable(void) { }
 
-#else /* !CONFIG_PREEMPT_RT */
-
-/**
- * migrate_disable - Prevent migration of the current task
- *
- * Maps to preempt_disable() which also disables preemption. Use
- * migrate_disable() to annotate that the intent is to prevent migration,
- * but not necessarily preemption.
- *
- * Can be invoked nested like preempt_disable() and needs the corresponding
- * number of migrate_enable() invocations.
- */
-static __always_inline void migrate_disable(void)
-{
-	preempt_disable();
-}
-
-/**
- * migrate_enable - Allow migration of the current task
- *
- * Counterpart to migrate_disable().
- *
- * As migrate_disable() can be invoked nested, only the outermost invocation
- * reenables migration.
- *
- * Currently mapped to preempt_enable().
- */
-static __always_inline void migrate_enable(void)
-{
-	preempt_enable();
-}
-
-#endif /* CONFIG_SMP && CONFIG_PREEMPT_RT */
+#endif /* CONFIG_SMP */
 
 #endif /* __LINUX_PREEMPT_H */
include/linux/sched.h +1 -1
@@ -715,7 +715,7 @@ struct task_struct {
 	const cpumask_t			*cpus_ptr;
 	cpumask_t			cpus_mask;
 	void				*migration_pending;
-#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT)
+#ifdef CONFIG_SMP
 	unsigned short			migration_disabled;
 #endif
 	unsigned short			migration_flags;
kernel/sched/core.c +35 -10

81 lines not on this page · raw message

kernel/sched/sched.h +2 -2
@@ -1056,7 +1056,7 @@ struct rq {
 	struct cpuidle_state	*idle_state;
 #endif
 
-#if defined(CONFIG_PREEMPT_RT) && defined(CONFIG_SMP)
+#ifdef CONFIG_SMP
 	unsigned int		nr_pinned;
 #endif
 	unsigned int		push_busy;
@@ -1092,7 +1092,7 @@ static inline int cpu_of(struct rq *rq)
 
 static inline bool is_migration_disabled(struct task_struct *p)
 {
-#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT)
+#ifdef CONFIG_SMP
 	return p->migration_disabled;
 #else
 	return false;
lib/smp_processor_id.c +1 -1
@@ -26,7 +26,7 @@ unsigned int check_preemption_disabled(c
 	if (current->nr_cpus_allowed == 1)
 		goto out;
 
-#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT_RT)
+#ifdef CONFIG_SMP
 	if (current->migration_disabled)
 		goto out;
 #endif
#53 lore raw

PATCH v3 24/37 sched: highmem: Store local kmaps in task struct

In reply to Thomas Gleixner

Instead of storing the map per CPU provide and use per task storage. That prepares for local kmaps which are preemptible.

The context switch code is preparatory and not yet in use because kmap_atomic() runs with preemption disabled. Will be made usable in the next step.

The context switch logic is safe even when an interrupt happens after clearing or before restoring the kmaps. The kmap index in task struct is not modified so any nesting kmap in an interrupt will use unused indices and on return the counter is the same as before.

Also add an assert into the return to user space code. Going back to user space with an active kmap local is a nono.

---
V3: Handle the debug case correctly

---
 include/linux/highmem-internal.h |   10 +++
 include/linux/sched.h            |    9 +++
 kernel/entry/common.c            |    2 
 kernel/fork.c                    |    1 
 kernel/sched/core.c              |   18 +++++++
 mm/highmem.c                     |   99 +++++++++++++++++++++++++++++++++++----
 6 files changed, 129 insertions(+), 10 deletions(-)
include/linux/highmem-internal.h +10 -0
@@ -9,6 +9,16 @@
 void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot);
 void *__kmap_local_page_prot(struct page *page, pgprot_t prot);
 void kunmap_local_indexed(void *vaddr);
+void kmap_local_fork(struct task_struct *tsk);
+void __kmap_local_sched_out(void);
+void __kmap_local_sched_in(void);
+static inline void kmap_assert_nomap(void)
+{
+	DEBUG_LOCKS_WARN_ON(current->kmap_ctrl.idx);
+}
+#else
+static inline void kmap_local_fork(struct task_struct *tsk) { }
+static inline void kmap_assert_nomap(void) { }
 #endif
 
 #ifdef CONFIG_HIGHMEM
include/linux/sched.h +9 -0
@@ -34,6 +34,7 @@
 #include <linux/rseq.h>
 #include <linux/seqlock.h>
 #include <linux/kcsan.h>
+#include <asm/kmap_size.h>
 
 /* task_struct member predeclarations (sorted alphabetically): */
 struct audit_context;
@@ -629,6 +630,13 @@ struct wake_q_node {
 	struct wake_q_node *next;
 };
 
+struct kmap_ctrl {
+#ifdef CONFIG_KMAP_LOCAL
+	int				idx;
+	pte_t				pteval[KM_TYPE_NR];
+#endif
+};
+
 struct task_struct {
 #ifdef CONFIG_THREAD_INFO_IN_TASK
 	/*
@@ -1294,6 +1302,7 @@ struct task_struct {
 	unsigned int			sequential_io;
 	unsigned int			sequential_io_avg;
 #endif
+	struct kmap_ctrl		kmap_ctrl;
 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
 	unsigned long			task_state_change;
 #endif
kernel/entry/common.c +2 -0
@@ -2,6 +2,7 @@
 
 #include <linux/context_tracking.h>
 #include <linux/entry-common.h>
+#include <linux/highmem.h>
 #include <linux/livepatch.h>
 #include <linux/audit.h>
 
@@ -194,6 +195,7 @@ static void exit_to_user_mode_prepare(st
 
 	/* Ensure that the address limit is intact and no locks are held */
 	addr_limit_user_check();
+	kmap_assert_nomap();
 	lockdep_assert_irqs_disabled();
 	lockdep_sys_exit();
 }
kernel/fork.c +1 -0
@@ -930,6 +930,7 @@ static struct task_struct *dup_task_stru
 	account_kernel_stack(tsk, 1);
 
 	kcov_task_init(tsk);
+	kmap_local_fork(tsk);
 
 #ifdef CONFIG_FAULT_INJECTION
 	tsk->fail_nth = 0;
kernel/sched/core.c +18 -0
@@ -4053,6 +4053,22 @@ static inline void finish_lock_switch(st
 # define finish_arch_post_lock_switch()	do { } while (0)
 #endif
 
+static inline void kmap_local_sched_out(void)
+{
+#ifdef CONFIG_KMAP_LOCAL
+	if (unlikely(current->kmap_ctrl.idx))
+		__kmap_local_sched_out();
+#endif
+}
+
+static inline void kmap_local_sched_in(void)
+{
+#ifdef CONFIG_KMAP_LOCAL
+	if (unlikely(current->kmap_ctrl.idx))
+		__kmap_local_sched_in();
+#endif
+}
+
 /**
  * prepare_task_switch - prepare to switch tasks
  * @rq: the runqueue preparing to switch
@@ -4075,6 +4091,7 @@ prepare_task_switch(struct rq *rq, struc
 	perf_event_task_sched_out(prev, next);
 	rseq_preempt(prev);
 	fire_sched_out_preempt_notifiers(prev, next);
+	kmap_local_sched_out();
 	prepare_task(next);
 	prepare_arch_switch(next);
 }
@@ -4141,6 +4158,7 @@ static struct rq *finish_task_switch(str
 	finish_lock_switch(rq);
 	finish_arch_post_lock_switch();
 	kcov_finish_switch(current);
+	kmap_local_sched_in();
 
 	fire_sched_in_preempt_notifiers(current);
 	/*
mm/highmem.c +89 -10

136 lines not on this page · raw message

#54 lore raw

Re: [patch V3 24/37] sched: highmem: Store local kmaps in task struct

include/linux/sched.h struct wake_q_node { · line 636

Quoted 4 lines · Thomas Gleixner
include/linux/sched.h +4 -0
+struct kmap_ctrl {
+#ifdef CONFIG_KMAP_LOCAL
+	int				idx;
+	pte_t				pteval[KM_TYPE_NR];

I'm a moron. Fixed it on the test machine ...

#55 lore raw

PATCH v4 24/37 sched: highmem: Store local kmaps in task struct

In reply to Thomas Gleixner

Instead of storing the map per CPU provide and use per task storage. That prepares for local kmaps which are preemptible.

The context switch code is preparatory and not yet in use because kmap_atomic() runs with preemption disabled. Will be made usable in the next step.

The context switch logic is safe even when an interrupt happens after clearing or before restoring the kmaps. The kmap index in task struct is not modified so any nesting kmap in an interrupt will use unused indices and on return the counter is the same as before.

Also add an assert into the return to user space code. Going back to user space with an active kmap local is a nono.

---
V4: Use the version which actually compiles and works
V3: Handle the debug case correctly

---
 include/linux/highmem-internal.h |   10 +++
 include/linux/sched.h            |    9 +++
 kernel/entry/common.c            |    2 
 kernel/fork.c                    |    1 
 kernel/sched/core.c              |   18 +++++++
 mm/highmem.c                     |   99 +++++++++++++++++++++++++++++++++++----
 6 files changed, 129 insertions(+), 10 deletions(-)
include/linux/highmem-internal.h +10 -0
@@ -9,6 +9,16 @@
 void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot);
 void *__kmap_local_page_prot(struct page *page, pgprot_t prot);
 void kunmap_local_indexed(void *vaddr);
+void kmap_local_fork(struct task_struct *tsk);
+void __kmap_local_sched_out(void);
+void __kmap_local_sched_in(void);
+static inline void kmap_assert_nomap(void)
+{
+	DEBUG_LOCKS_WARN_ON(current->kmap_ctrl.idx);
+}
+#else
+static inline void kmap_local_fork(struct task_struct *tsk) { }
+static inline void kmap_assert_nomap(void) { }
 #endif
 
 #ifdef CONFIG_HIGHMEM
include/linux/sched.h +9 -0
@@ -34,6 +34,7 @@
 #include <linux/rseq.h>
 #include <linux/seqlock.h>
 #include <linux/kcsan.h>
+#include <asm/kmap_size.h>
 
 /* task_struct member predeclarations (sorted alphabetically): */
 struct audit_context;
@@ -629,6 +630,13 @@ struct wake_q_node {
 	struct wake_q_node *next;
 };
 
+struct kmap_ctrl {
+#ifdef CONFIG_KMAP_LOCAL
+	int				idx;
+	pte_t				pteval[KM_MAX_IDX];
+#endif
+};
+
 struct task_struct {
 #ifdef CONFIG_THREAD_INFO_IN_TASK
 	/*
@@ -1294,6 +1302,7 @@ struct task_struct {
 	unsigned int			sequential_io;
 	unsigned int			sequential_io_avg;
 #endif
+	struct kmap_ctrl		kmap_ctrl;
 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
 	unsigned long			task_state_change;
 #endif
kernel/entry/common.c +2 -0
@@ -2,6 +2,7 @@
 
 #include <linux/context_tracking.h>
 #include <linux/entry-common.h>
+#include <linux/highmem.h>
 #include <linux/livepatch.h>
 #include <linux/audit.h>
 
@@ -194,6 +195,7 @@ static void exit_to_user_mode_prepare(st
 
 	/* Ensure that the address limit is intact and no locks are held */
 	addr_limit_user_check();
+	kmap_assert_nomap();
 	lockdep_assert_irqs_disabled();
 	lockdep_sys_exit();
 }
kernel/fork.c +1 -0
@@ -930,6 +930,7 @@ static struct task_struct *dup_task_stru
 	account_kernel_stack(tsk, 1);
 
 	kcov_task_init(tsk);
+	kmap_local_fork(tsk);
 
 #ifdef CONFIG_FAULT_INJECTION
 	tsk->fail_nth = 0;
kernel/sched/core.c +18 -0
@@ -4053,6 +4053,22 @@ static inline void finish_lock_switch(st
 # define finish_arch_post_lock_switch()	do { } while (0)
 #endif
 
+static inline void kmap_local_sched_out(void)
+{
+#ifdef CONFIG_KMAP_LOCAL
+	if (unlikely(current->kmap_ctrl.idx))
+		__kmap_local_sched_out();
+#endif
+}
+
+static inline void kmap_local_sched_in(void)
+{
+#ifdef CONFIG_KMAP_LOCAL
+	if (unlikely(current->kmap_ctrl.idx))
+		__kmap_local_sched_in();
+#endif
+}
+
 /**
  * prepare_task_switch - prepare to switch tasks
  * @rq: the runqueue preparing to switch
@@ -4075,6 +4091,7 @@ prepare_task_switch(struct rq *rq, struc
 	perf_event_task_sched_out(prev, next);
 	rseq_preempt(prev);
 	fire_sched_out_preempt_notifiers(prev, next);
+	kmap_local_sched_out();
 	prepare_task(next);
 	prepare_arch_switch(next);
 }
@@ -4141,6 +4158,7 @@ static struct rq *finish_task_switch(str
 	finish_lock_switch(rq);
 	finish_arch_post_lock_switch();
 	kcov_finish_switch(current);
+	kmap_local_sched_in();
 
 	fire_sched_in_preempt_notifiers(current);
 	/*
mm/highmem.c +89 -10

136 lines not on this page · raw message

#56 lore raw

PATCH v3 25/37 mm/highmem: Provide kmap_local*

In reply to Thomas Gleixner

Now that the kmap atomic index is stored in task struct provide a preemptible variant. On context switch the maps of an outgoing task are removed and the map of the incoming task are restored. That's obviously slow, but highmem is slow anyway.

The kmap_local.*() functions can be invoked from both preemptible and atomic context. kmap local sections disable migration to keep the resulting virtual mapping address correct, but disable neither pagefaults nor preemption.

A wholesale conversion of kmap_atomic to be fully preemptible is not possible because some of the usage sites might rely on the preemption disable for serialization or on the implicit pagefault disable. Needs to be done on a case by case basis.

---
V3: Move migrate disable into the actual highmem mapping code so it only
affects real highmem mappings.

V2: Make it more consistent and add commentry

---
 include/linux/highmem-internal.h |   48 +++++++++++++++++++++++++++++++++++++++
 include/linux/highmem.h          |   43 +++++++++++++++++++++-------------
 mm/highmem.c                     |    6 ++++
 3 files changed, 81 insertions(+), 16 deletions(-)
include/linux/highmem-internal.h +48 -0
@@ -69,6 +69,26 @@ static inline void kmap_flush_unused(voi
 	__kmap_flush_unused();
 }
 
+static inline void *kmap_local_page(struct page *page)
+{
+	return __kmap_local_page_prot(page, kmap_prot);
+}
+
+static inline void *kmap_local_page_prot(struct page *page, pgprot_t prot)
+{
+	return __kmap_local_page_prot(page, prot);
+}
+
+static inline void *kmap_local_pfn(unsigned long pfn)
+{
+	return __kmap_local_pfn_prot(pfn, kmap_prot);
+}
+
+static inline void __kunmap_local(void *vaddr)
+{
+	kunmap_local_indexed(vaddr);
+}
+
 static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
 {
 	preempt_disable();
@@ -141,6 +161,28 @@ static inline void kunmap(struct page *p
 #endif
 }
 
+static inline void *kmap_local_page(struct page *page)
+{
+	return page_address(page);
+}
+
+static inline void *kmap_local_page_prot(struct page *page, pgprot_t prot)
+{
+	return kmap_local_page(page);
+}
+
+static inline void *kmap_local_pfn(unsigned long pfn)
+{
+	return kmap_local_page(pfn_to_page(pfn));
+}
+
+static inline void __kunmap_local(void *addr)
+{
+#ifdef ARCH_HAS_FLUSH_ON_KUNMAP
+	kunmap_flush_on_unmap(addr);
+#endif
+}
+
 static inline void *kmap_atomic(struct page *page)
 {
 	preempt_disable();
@@ -182,4 +224,10 @@ do {								\
 	__kunmap_atomic(__addr);				\
 } while (0)
 
+#define kunmap_local(__addr)					\
+do {								\
+	BUILD_BUG_ON(__same_type((__addr), struct page *));	\
+	__kunmap_local(__addr);					\
+} while (0)
+
 #endif
include/linux/highmem.h +27 -16

73 lines not on this page · raw message

mm/highmem.c +6 -0
@@ -450,6 +450,11 @@ void *__kmap_local_pfn_prot(unsigned lon
 	unsigned long vaddr;
 	int idx;
 
+	/*
+	 * Disable migration so resulting virtual address is stable
+	 * accross preemption.
+	 */
+	migrate_disable();
 	preempt_disable();
 	idx = arch_kmap_local_map_idx(kmap_local_idx_push(), pfn);
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
@@ -505,6 +510,7 @@ void kunmap_local_indexed(void *vaddr)
 	current->kmap_ctrl.pteval[kmap_local_idx()] = __pte(0);
 	kmap_local_idx_pop();
 	preempt_enable();
+	migrate_enable();
 }
 EXPORT_SYMBOL(kunmap_local_indexed);
#57 lore raw

PATCH v3 26/37 io-mapping: Provide iomap_local variant

In reply to Thomas Gleixner

Similar to kmap local provide a iomap local variant which only disables migration, but neither disables pagefaults nor preemption.

---
V3: Restrict migrate disable to the 32bit mapping case and update documentation.

V2: Split out from the large combo patch and add the !IOMAP_ATOMIC variants

---
 Documentation/driver-api/io-mapping.rst |   76 +++++++++++++++++++-------------
 include/linux/io-mapping.h              |   30 +++++++++++-
 2 files changed, 74 insertions(+), 32 deletions(-)
Documentation/driver-api/io-mapping.rst +46 -30
@@ -20,55 +20,71 @@ as it would consume too much of the kern
 mappable, while 'size' indicates how large a mapping region to
 enable. Both are in bytes.
 
-This _wc variant provides a mapping which may only be used
-with the io_mapping_map_atomic_wc or io_mapping_map_wc.
+This _wc variant provides a mapping which may only be used with
+io_mapping_map_atomic_wc(), io_mapping_map_local_wc() or
+io_mapping_map_wc().
+
+With this mapping object, individual pages can be mapped either temporarily
+or long term, depending on the requirements. Of course, temporary maps are
+more efficient. They come in two flavours::
 
-With this mapping object, individual pages can be mapped either atomically
-or not, depending on the necessary scheduling environment. Of course, atomic
-maps are more efficient::
+	void *io_mapping_map_local_wc(struct io_mapping *mapping,
+				      unsigned long offset)
 
 	void *io_mapping_map_atomic_wc(struct io_mapping *mapping,
 				       unsigned long offset)
 
-'offset' is the offset within the defined mapping region.
-Accessing addresses beyond the region specified in the
-creation function yields undefined results. Using an offset
-which is not page aligned yields an undefined result. The
-return value points to a single page in CPU address space.
-
-This _wc variant returns a write-combining map to the
-page and may only be used with mappings created by
-io_mapping_create_wc
+'offset' is the offset within the defined mapping region.  Accessing
+addresses beyond the region specified in the creation function yields
+undefined results. Using an offset which is not page aligned yields an
+undefined result. The return value points to a single page in CPU address
+space.
 
-Note that the task may not sleep while holding this page
-mapped.
+This _wc variant returns a write-combining map to the page and may only be
+used with mappings created by io_mapping_create_wc()
 
-::
+Temporary mappings are only valid in the context of the caller. The mapping
+is not guaranteed to be globaly visible.
 
-	void io_mapping_unmap_atomic(void *vaddr)
+io_mapping_map_local_wc() has a side effect on X86 32bit as it disables
+migration to make the mapping code work. No caller can rely on this side
+effect.
+
+io_mapping_map_atomic_wc() has the side effect of disabling preemption and
+pagefaults. Don't use in new code. Use io_mapping_map_local_wc() instead.
 
-'vaddr' must be the value returned by the last
-io_mapping_map_atomic_wc call. This unmaps the specified
-page and allows the task to sleep once again.
+Nested mappings need to be undone in reverse order because the mapping
+code uses a stack for keeping track of them::
 
-If you need to sleep while holding the lock, you can use the non-atomic
-variant, although they may be significantly slower.
+ addr1 = io_mapping_map_local_wc(map1, offset1);
+ addr2 = io_mapping_map_local_wc(map2, offset2);
+ ...
+ io_mapping_unmap_local(addr2);
+ io_mapping_unmap_local(addr1);
 
-::
+The mappings are released with::
+
+	void io_mapping_unmap_local(void *vaddr)
+	void io_mapping_unmap_atomic(void *vaddr)
+
+'vaddr' must be the value returned by the last io_mapping_map_local_wc() or
+io_mapping_map_atomic_wc() call. This unmaps the specified mapping and
+undoes the side effects of the mapping functions.
+
+If you need to sleep while holding a mapping, you can use the regular
+variant, although this may be significantly slower::
 
 	void *io_mapping_map_wc(struct io_mapping *mapping,
 				unsigned long offset)
 
-This works like io_mapping_map_atomic_wc except it allows
-the task to sleep while holding the page mapped.
-
+This works like io_mapping_map_atomic/local_wc() except it has no side
+effects and the pointer is globaly visible.
 
-::
+The mappings are released with::
 
 	void io_mapping_unmap(void *vaddr)
 
-This works like io_mapping_unmap_atomic, except it is used
-for pages mapped with io_mapping_map_wc.
+Use for pages mapped with io_mapping_map_wc().
 
 At driver close time, the io_mapping object must be freed::
 
include/linux/io-mapping.h +28 -2
@@ -83,6 +83,21 @@ io_mapping_unmap_atomic(void __iomem *va
 }
 
 static inline void __iomem *
+io_mapping_map_local_wc(struct io_mapping *mapping, unsigned long offset)
+{
+	resource_size_t phys_addr;
+
+	BUG_ON(offset >= mapping->size);
+	phys_addr = mapping->base + offset;
+	return __iomap_local_pfn_prot(PHYS_PFN(phys_addr), mapping->prot);
+}
+
+static inline void io_mapping_unmap_local(void __iomem *vaddr)
+{
+	kunmap_local_indexed((void __force *)vaddr);
+}
+
+static inline void __iomem *
 io_mapping_map_wc(struct io_mapping *mapping,
 		  unsigned long offset,
 		  unsigned long size)
@@ -101,7 +116,7 @@ io_mapping_unmap(void __iomem *vaddr)
 	iounmap(vaddr);
 }
 
-#else
+#else  /* HAVE_ATOMIC_IOMAP */
 
 #include <linux/uaccess.h>
 
@@ -166,7 +181,18 @@ io_mapping_unmap_atomic(void __iomem *va
 	preempt_enable();
 }
 
-#endif /* HAVE_ATOMIC_IOMAP */
+static inline void __iomem *
+io_mapping_map_local_wc(struct io_mapping *mapping, unsigned long offset)
+{
+	return io_mapping_map_wc(mapping, offset, PAGE_SIZE);
+}
+
+static inline void io_mapping_unmap_local(void __iomem *vaddr)
+{
+	io_mapping_unmap(vaddr);
+}
+
+#endif /* !HAVE_ATOMIC_IOMAP */
 
 static inline struct io_mapping *
 io_mapping_create_wc(resource_size_t base,
#58 lore raw

PATCH v3 27/37 x86/crashdump/32: Simplify copy_oldmem_page()

In reply to Thomas Gleixner

Replace kmap_atomic_pfn() with kmap_local_pfn() which is preemptible and can take page faults.

Remove the indirection of the dump page and the related cruft which is not longer required.

---
V3: New patch

---
 arch/x86/kernel/crash_dump_32.c |   48 ++++++++--------------------------------
 1 file changed, 10 insertions(+), 38 deletions(-)
arch/x86/kernel/crash_dump_32.c +10 -38
@@ -13,8 +13,6 @@
 
 #include <linux/uaccess.h>
 
-static void *kdump_buf_page;
-
 static inline bool is_crashed_pfn_valid(unsigned long pfn)
 {
 #ifndef CONFIG_X86_PAE
@@ -41,15 +39,11 @@ static inline bool is_crashed_pfn_valid(
  * @userbuf: if set, @buf is in user address space, use copy_to_user(),
  *	otherwise @buf is in kernel address space, use memcpy().
  *
- * Copy a page from "oldmem". For this page, there is no pte mapped
- * in the current kernel. We stitch up a pte, similar to kmap_atomic.
- *
- * Calling copy_to_user() in atomic context is not desirable. Hence first
- * copying the data to a pre-allocated kernel page and then copying to user
- * space in non-atomic context.
+ * Copy a page from "oldmem". For this page, there might be no pte mapped
+ * in the current kernel.
  */
-ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
-                               size_t csize, unsigned long offset, int userbuf)
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize,
+			 unsigned long offset, int userbuf)
 {
 	void  *vaddr;
 
@@ -59,38 +53,16 @@ ssize_t copy_oldmem_page(unsigned long p
 	if (!is_crashed_pfn_valid(pfn))
 		return -EFAULT;
 
-	vaddr = kmap_atomic_pfn(pfn);
+	vaddr = kmap_local_pfn(pfn);
 
 	if (!userbuf) {
-		memcpy(buf, (vaddr + offset), csize);
-		kunmap_atomic(vaddr);
+		memcpy(buf, vaddr + offset, csize);
 	} else {
-		if (!kdump_buf_page) {
-			printk(KERN_WARNING "Kdump: Kdump buffer page not"
-				" allocated\n");
-			kunmap_atomic(vaddr);
-			return -EFAULT;
-		}
-		copy_page(kdump_buf_page, vaddr);
-		kunmap_atomic(vaddr);
-		if (copy_to_user(buf, (kdump_buf_page + offset), csize))
-			return -EFAULT;
+		if (copy_to_user(buf, vaddr + offset, csize))
+			csize = -EFAULT;
 	}
 
-	return csize;
-}
+	kunmap_local(vaddr);
 
-static int __init kdump_buf_page_init(void)
-{
-	int ret = 0;
-
-	kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!kdump_buf_page) {
-		printk(KERN_WARNING "Kdump: Failed to allocate kdump buffer"
-			 " page\n");
-		ret = -ENOMEM;
-	}
-
-	return ret;
+	return csize;
 }
-arch_initcall(kdump_buf_page_init);
#59 lore raw

PATCH v3 28/37 mips/crashdump: Simplify copy_oldmem_page()

In reply to Thomas Gleixner

Replace kmap_atomic_pfn() with kmap_local_pfn() which is preemptible and can take page faults.

Remove the indirection of the dump page and the related cruft which is not longer required.

---
V3: New patch

---
 arch/mips/kernel/crash_dump.c |   42 +++++++-----------------------------------
 1 file changed, 7 insertions(+), 35 deletions(-)
arch/mips/kernel/crash_dump.c +7 -35
@@ -5,8 +5,6 @@
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 
-static void *kdump_buf_page;
-
 /**
  * copy_oldmem_page - copy one page from "oldmem"
  * @pfn: page frame number to be copied
@@ -17,51 +15,25 @@ static void *kdump_buf_page;
  * @userbuf: if set, @buf is in user address space, use copy_to_user(),
  *	otherwise @buf is in kernel address space, use memcpy().
  *
- * Copy a page from "oldmem". For this page, there is no pte mapped
+ * Copy a page from "oldmem". For this page, there might be no pte mapped
  * in the current kernel.
- *
- * Calling copy_to_user() in atomic context is not desirable. Hence first
- * copying the data to a pre-allocated kernel page and then copying to user
- * space in non-atomic context.
  */
-ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
-			 size_t csize, unsigned long offset, int userbuf)
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize,
+			 unsigned long offset, int userbuf)
 {
 	void  *vaddr;
 
 	if (!csize)
 		return 0;
 
-	vaddr = kmap_atomic_pfn(pfn);
+	vaddr = kmap_local_pfn(pfn);
 
 	if (!userbuf) {
-		memcpy(buf, (vaddr + offset), csize);
-		kunmap_atomic(vaddr);
+		memcpy(buf, vaddr + offset, csize);
 	} else {
-		if (!kdump_buf_page) {
-			pr_warn("Kdump: Kdump buffer page not allocated\n");
-
-			return -EFAULT;
-		}
-		copy_page(kdump_buf_page, vaddr);
-		kunmap_atomic(vaddr);
-		if (copy_to_user(buf, (kdump_buf_page + offset), csize))
-			return -EFAULT;
+		if (copy_to_user(buf, vaddr + offset, csize))
+			csize = -EFAULT;
 	}
 
 	return csize;
 }
-
-static int __init kdump_buf_page_init(void)
-{
-	int ret = 0;
-
-	kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!kdump_buf_page) {
-		pr_warn("Kdump: Failed to allocate kdump buffer page\n");
-		ret = -ENOMEM;
-	}
-
-	return ret;
-}
-arch_initcall(kdump_buf_page_init);
#60 lore raw

PATCH v3 29/37 ARM: mm: Replace kmap_atomic_pfn()

In reply to Thomas Gleixner

There is no requirement to disable pagefaults and preemption for these cache management mappings.

Replace kmap_atomic_pfn() with kmap_local_pfn(). This allows to remove kmap_atomic_pfn() in the next step.

---
V3: New patch

---
 arch/arm/mm/cache-feroceon-l2.c |    6 +++---
 arch/arm/mm/cache-xsc3l2.c      |    4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)
arch/arm/mm/cache-feroceon-l2.c +3 -3
@@ -49,9 +49,9 @@ static inline unsigned long l2_get_va(un
 	 * we simply install a virtual mapping for it only for the
 	 * TLB lookup to occur, hence no need to flush the untouched
 	 * memory mapping afterwards (note: a cache flush may happen
-	 * in some circumstances depending on the path taken in kunmap_atomic).
+	 * in some circumstances depending on the path taken in kunmap_local).
 	 */
-	void *vaddr = kmap_atomic_pfn(paddr >> PAGE_SHIFT);
+	void *vaddr = kmap_local_pfn(paddr >> PAGE_SHIFT);
 	return (unsigned long)vaddr + (paddr & ~PAGE_MASK);
 #else
 	return __phys_to_virt(paddr);
@@ -61,7 +61,7 @@ static inline unsigned long l2_get_va(un
 static inline void l2_put_va(unsigned long vaddr)
 {
 #ifdef CONFIG_HIGHMEM
-	kunmap_atomic((void *)vaddr);
+	kunmap_local((void *)vaddr);
 #endif
 }
 
arch/arm/mm/cache-xsc3l2.c +2 -2
@@ -59,7 +59,7 @@ static inline void l2_unmap_va(unsigned
 {
 #ifdef CONFIG_HIGHMEM
 	if (va != -1)
-		kunmap_atomic((void *)va);
+		kunmap_local((void *)va);
 #endif
 }
 
@@ -75,7 +75,7 @@ static inline unsigned long l2_map_va(un
 		 * in place for it.
 		 */
 		l2_unmap_va(prev_va);
-		va = (unsigned long)kmap_atomic_pfn(pa >> PAGE_SHIFT);
+		va = (unsigned long)kmap_local_pfn(pa >> PAGE_SHIFT);
 	}
 	return va + (pa_offset >> (32 - PAGE_SHIFT));
 #else
#61 lore raw

PATCH v3 30/37 highmem: Remove kmap_atomic_pfn()

In reply to Thomas Gleixner

No more users.

---
V3: New patch

---
 include/linux/highmem-internal.h |   12 ------------
 1 file changed, 12 deletions(-)
include/linux/highmem-internal.h +0 -12
@@ -99,13 +99,6 @@ static inline void *kmap_atomic(struct p
 	return kmap_atomic_prot(page, kmap_prot);
 }
 
-static inline void *kmap_atomic_pfn(unsigned long pfn)
-{
-	preempt_disable();
-	pagefault_disable();
-	return __kmap_local_pfn_prot(pfn, kmap_prot);
-}
-
 static inline void __kunmap_atomic(void *addr)
 {
 	kunmap_local_indexed(addr);
@@ -193,11 +186,6 @@ static inline void *kmap_atomic_prot(str
 	return kmap_atomic(page);
 }
 
-static inline void *kmap_atomic_pfn(unsigned long pfn)
-{
-	return kmap_atomic(pfn_to_page(pfn));
-}
-
 static inline void __kunmap_atomic(void *addr)
 {
 #ifdef ARCH_HAS_FLUSH_ON_KUNMAP
#62 lore raw

PATCH v3 31/37 drm/ttm: Replace kmap_atomic() usage

In reply to Thomas Gleixner

There is no reason to disable pagefaults and preemption as a side effect of kmap_atomic_prot().

Use kmap_local_page_prot() instead and document the reasoning for the mapping usage with the given pgprot.

Remove the NULL pointer check for the map. These functions return a valid address for valid pages and the return was bogus anyway as it would have left preemption and pagefaults disabled.

Cc Christian Koenig <[email protected]>
Cc Huang Rui <[email protected]>
Cc David Airlie <[email protected]>
Cc Daniel Vetter <[email protected]>

---
V3: New patch

---
 drivers/gpu/drm/ttm/ttm_bo_util.c |   20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)
drivers/gpu/drm/ttm/ttm_bo_util.c +12 -8
@@ -181,13 +181,15 @@ static int ttm_copy_io_ttm_page(struct t
 		return -ENOMEM;
 
 	src = (void *)((unsigned long)src + (page << PAGE_SHIFT));
-	dst = kmap_atomic_prot(d, prot);
-	if (!dst)
-		return -ENOMEM;
+	/*
+	 * Ensure that a highmem page is mapped with the correct
+	 * pgprot. For non highmem the mapping is already there.
+	 */
+	dst = kmap_local_page_prot(d, prot);
 
 	memcpy_fromio(dst, src, PAGE_SIZE);
 
-	kunmap_atomic(dst);
+	kunmap_local(dst);
 
 	return 0;
 }
@@ -203,13 +205,15 @@ static int ttm_copy_ttm_io_page(struct t
 		return -ENOMEM;
 
 	dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT));
-	src = kmap_atomic_prot(s, prot);
-	if (!src)
-		return -ENOMEM;
+	/*
+	 * Ensure that a highmem page is mapped with the correct
+	 * pgprot. For non highmem the mapping is already there.
+	 */
+	src = kmap_local_page_prot(s, prot);
 
 	memcpy_toio(dst, src, PAGE_SIZE);
 
-	kunmap_atomic(src);
+	kunmap_local(src);
 
 	return 0;
 }
#63 lore raw

PATCH v3 32/37 drm/vmgfx: Replace kmap_atomic()

In reply to Thomas Gleixner

There is no reason to disable pagefaults and preemption as a side effect of kmap_atomic_prot().

Use kmap_local_page_prot() instead and document the reasoning for the mapping usage with the given pgprot.

Remove the NULL pointer check for the map. These functions return a valid address for valid pages and the return was bogus anyway as it would have left preemption and pagefaults disabled.

Cc VMware Graphics <[email protected]>
Cc Roland Scheidegger <[email protected]>
Cc David Airlie <[email protected]>
Cc Daniel Vetter <[email protected]>

---
V3: New patch

---
 drivers/gpu/drm/vmwgfx/vmwgfx_blit.c |   30 ++++++++++++------------------
 1 file changed, 12 insertions(+), 18 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_blit.c +12 -18
@@ -375,12 +375,12 @@ static int vmw_bo_cpu_blit_line(struct v
 		copy_size = min_t(u32, copy_size, PAGE_SIZE - src_page_offset);
 
 		if (unmap_src) {
-			kunmap_atomic(d->src_addr);
+			kunmap_local(d->src_addr);
 			d->src_addr = NULL;
 		}
 
 		if (unmap_dst) {
-			kunmap_atomic(d->dst_addr);
+			kunmap_local(d->dst_addr);
 			d->dst_addr = NULL;
 		}
 
@@ -388,12 +388,8 @@ static int vmw_bo_cpu_blit_line(struct v
 			if (WARN_ON_ONCE(dst_page >= d->dst_num_pages))
 				return -EINVAL;
 
-			d->dst_addr =
-				kmap_atomic_prot(d->dst_pages[dst_page],
-						 d->dst_prot);
-			if (!d->dst_addr)
-				return -ENOMEM;
-
+			d->dst_addr = kmap_local_page_prot(d->dst_pages[dst_page],
+							   d->dst_prot);
 			d->mapped_dst = dst_page;
 		}
 
@@ -401,12 +397,8 @@ static int vmw_bo_cpu_blit_line(struct v
 			if (WARN_ON_ONCE(src_page >= d->src_num_pages))
 				return -EINVAL;
 
-			d->src_addr =
-				kmap_atomic_prot(d->src_pages[src_page],
-						 d->src_prot);
-			if (!d->src_addr)
-				return -ENOMEM;
-
+			d->src_addr = kmap_local_page_prot(d->src_pages[src_page],
+							   d->src_prot);
 			d->mapped_src = src_page;
 		}
 		diff->do_cpy(diff, d->dst_addr + dst_page_offset,
@@ -436,8 +428,10 @@ static int vmw_bo_cpu_blit_line(struct v
  *
  * Performs a CPU blit from one buffer object to another avoiding a full
  * bo vmap which may exhaust- or fragment vmalloc space.
- * On supported architectures (x86), we're using kmap_atomic which avoids
- * cross-processor TLB- and cache flushes and may, on non-HIGHMEM systems
+ *
+ * On supported architectures (x86), we're using kmap_local_prot() which
+ * avoids cross-processor TLB- and cache flushes. kmap_local_prot() will
+ * either map a highmem page with the proper pgprot on HIGHMEM=y systems or
  * reference already set-up mappings.
  *
  * Neither of the buffer objects may be placed in PCI memory
@@ -500,9 +494,9 @@ int vmw_bo_cpu_blit(struct ttm_buffer_ob
 	}
 out:
 	if (d.src_addr)
-		kunmap_atomic(d.src_addr);
+		kunmap_local(d.src_addr);
 	if (d.dst_addr)
-		kunmap_atomic(d.dst_addr);
+		kunmap_local(d.dst_addr);
 
 	return ret;
 }
#64 lore raw

PATCH v3 33/37 highmem: Remove kmap_atomic_prot()

In reply to Thomas Gleixner

No more users.

---
V3: New patch

---
 include/linux/highmem-internal.h |   14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)
include/linux/highmem-internal.h +2 -12
@@ -87,16 +87,11 @@ static inline void __kunmap_local(void *
 	kunmap_local_indexed(vaddr);
 }
 
-static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+static inline void *kmap_atomic(struct page *page)
 {
 	preempt_disable();
 	pagefault_disable();
-	return __kmap_local_page_prot(page, prot);
-}
-
-static inline void *kmap_atomic(struct page *page)
-{
-	return kmap_atomic_prot(page, kmap_prot);
+	return __kmap_local_page_prot(page, kmap_prot);
 }
 
 static inline void __kunmap_atomic(void *addr)
@@ -181,11 +176,6 @@ static inline void *kmap_atomic(struct p
 	return page_address(page);
 }
 
-static inline void *kmap_atomic_prot(struct page *page, pgprot_t prot)
-{
-	return kmap_atomic(page);
-}
-
 static inline void __kunmap_atomic(void *addr)
 {
 #ifdef ARCH_HAS_FLUSH_ON_KUNMAP
#65 lore raw

PATCH v3 34/37 drm/qxl: Replace io_mapping_map_atomic_wc()

In reply to Thomas Gleixner

None of these mapping requires the side effect of disabling pagefaults and preemption.

Use io_mapping_map_local_wc() instead, rename the related functions accordingly and clean up qxl_process_single_command() to use a plain copy_from_user() as the local maps are not disabling pagefaults.

---
V3: New patch

---
 drivers/gpu/drm/qxl/qxl_image.c   |   18 +++++++++---------
 drivers/gpu/drm/qxl/qxl_ioctl.c   |   27 +++++++++++++--------------
 drivers/gpu/drm/qxl/qxl_object.c  |   12 ++++++------
 drivers/gpu/drm/qxl/qxl_object.h  |    4 ++--
 drivers/gpu/drm/qxl/qxl_release.c |    4 ++--
 5 files changed, 32 insertions(+), 33 deletions(-)
drivers/gpu/drm/qxl/qxl_image.c +9 -9
@@ -124,12 +124,12 @@ qxl_image_init_helper(struct qxl_device
 				  wrong (check the bitmaps are sent correctly
 				  first) */
 
-	ptr = qxl_bo_kmap_atomic_page(qdev, chunk_bo, 0);
+	ptr = qxl_bo_kmap_local_page(qdev, chunk_bo, 0);
 	chunk = ptr;
 	chunk->data_size = height * chunk_stride;
 	chunk->prev_chunk = 0;
 	chunk->next_chunk = 0;
-	qxl_bo_kunmap_atomic_page(qdev, chunk_bo, ptr);
+	qxl_bo_kunmap_local_page(qdev, chunk_bo, ptr);
 
 	{
 		void *k_data, *i_data;
@@ -143,7 +143,7 @@ qxl_image_init_helper(struct qxl_device
 			i_data = (void *)data;
 
 			while (remain > 0) {
-				ptr = qxl_bo_kmap_atomic_page(qdev, chunk_bo, page << PAGE_SHIFT);
+				ptr = qxl_bo_kmap_local_page(qdev, chunk_bo, page << PAGE_SHIFT);
 
 				if (page == 0) {
 					chunk = ptr;
@@ -157,7 +157,7 @@ qxl_image_init_helper(struct qxl_device
 
 				memcpy(k_data, i_data, size);
 
-				qxl_bo_kunmap_atomic_page(qdev, chunk_bo, ptr);
+				qxl_bo_kunmap_local_page(qdev, chunk_bo, ptr);
 				i_data += size;
 				remain -= size;
 				page++;
@@ -175,10 +175,10 @@ qxl_image_init_helper(struct qxl_device
 					page_offset = offset_in_page(out_offset);
 					size = min((int)(PAGE_SIZE - page_offset), remain);
 
-					ptr = qxl_bo_kmap_atomic_page(qdev, chunk_bo, page_base);
+					ptr = qxl_bo_kmap_local_page(qdev, chunk_bo, page_base);
 					k_data = ptr + page_offset;
 					memcpy(k_data, i_data, size);
-					qxl_bo_kunmap_atomic_page(qdev, chunk_bo, ptr);
+					qxl_bo_kunmap_local_page(qdev, chunk_bo, ptr);
 					remain -= size;
 					i_data += size;
 					out_offset += size;
@@ -189,7 +189,7 @@ qxl_image_init_helper(struct qxl_device
 	qxl_bo_kunmap(chunk_bo);
 
 	image_bo = dimage->bo;
-	ptr = qxl_bo_kmap_atomic_page(qdev, image_bo, 0);
+	ptr = qxl_bo_kmap_local_page(qdev, image_bo, 0);
 	image = ptr;
 
 	image->descriptor.id = 0;
@@ -212,7 +212,7 @@ qxl_image_init_helper(struct qxl_device
 		break;
 	default:
 		DRM_ERROR("unsupported image bit depth\n");
-		qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr);
+		qxl_bo_kunmap_local_page(qdev, image_bo, ptr);
 		return -EINVAL;
 	}
 	image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN;
@@ -222,7 +222,7 @@ qxl_image_init_helper(struct qxl_device
 	image->u.bitmap.palette = 0;
 	image->u.bitmap.data = qxl_bo_physical_address(qdev, chunk_bo, 0);
 
-	qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr);
+	qxl_bo_kunmap_local_page(qdev, image_bo, ptr);
 
 	return 0;
 }
drivers/gpu/drm/qxl/qxl_ioctl.c +13 -14
@@ -89,11 +89,11 @@ apply_reloc(struct qxl_device *qdev, str
 {
 	void *reloc_page;
 
-	reloc_page = qxl_bo_kmap_atomic_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK);
+	reloc_page = qxl_bo_kmap_local_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK);
 	*(uint64_t *)(reloc_page + (info->dst_offset & ~PAGE_MASK)) = qxl_bo_physical_address(qdev,
 											      info->src_bo,
 											      info->src_offset);
-	qxl_bo_kunmap_atomic_page(qdev, info->dst_bo, reloc_page);
+	qxl_bo_kunmap_local_page(qdev, info->dst_bo, reloc_page);
 }
 
 static void
@@ -105,9 +105,9 @@ apply_surf_reloc(struct qxl_device *qdev
 	if (info->src_bo && !info->src_bo->is_primary)
 		id = info->src_bo->surface_id;
 
-	reloc_page = qxl_bo_kmap_atomic_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK);
+	reloc_page = qxl_bo_kmap_local_page(qdev, info->dst_bo, info->dst_offset & PAGE_MASK);
 	*(uint32_t *)(reloc_page + (info->dst_offset & ~PAGE_MASK)) = id;
-	qxl_bo_kunmap_atomic_page(qdev, info->dst_bo, reloc_page);
+	qxl_bo_kunmap_local_page(qdev, info->dst_bo, reloc_page);
 }
 
 /* return holding the reference to this object */
@@ -149,7 +149,6 @@ static int qxl_process_single_command(st
 	struct qxl_bo *cmd_bo;
 	void *fb_cmd;
 	int i, ret, num_relocs;
-	int unwritten;
 
 	switch (cmd->type) {
 	case QXL_CMD_DRAW:
@@ -185,21 +184,21 @@ static int qxl_process_single_command(st
 		goto out_free_reloc;
 
 	/* TODO copy slow path code from i915 */
-	fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_MASK));
-	unwritten = __copy_from_user_inatomic_nocache
-		(fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_MASK),
-		 u64_to_user_ptr(cmd->command), cmd->command_size);
+	fb_cmd = qxl_bo_kmap_local_page(qdev, cmd_bo, (release->release_offset & PAGE_MASK));
 
-	{
+	if (copy_from_user(fb_cmd + sizeof(union qxl_release_info) +
+			   (release->release_offset & ~PAGE_MASK),
+			   u64_to_user_ptr(cmd->command), cmd->command_size)) {
+		ret = -EFAULT;
+	} else {
 		struct qxl_drawable *draw = fb_cmd;
 
 		draw->mm_time = qdev->rom->mm_clock;
 	}
 
-	qxl_bo_kunmap_atomic_page(qdev, cmd_bo, fb_cmd);
-	if (unwritten) {
-		DRM_ERROR("got unwritten %d\n", unwritten);
-		ret = -EFAULT;
+	qxl_bo_kunmap_local_page(qdev, cmd_bo, fb_cmd);
+	if (ret) {
+		DRM_ERROR("copy from user failed %d\n", ret);
 		goto out_free_release;
 	}
 
drivers/gpu/drm/qxl/qxl_object.c +6 -6
@@ -172,8 +172,8 @@ int qxl_bo_kmap(struct qxl_bo *bo, void
 	return 0;
 }
 
-void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev,
-			      struct qxl_bo *bo, int page_offset)
+void *qxl_bo_kmap_local_page(struct qxl_device *qdev,
+			     struct qxl_bo *bo, int page_offset)
 {
 	unsigned long offset;
 	void *rptr;
@@ -188,7 +188,7 @@ void *qxl_bo_kmap_atomic_page(struct qxl
 		goto fallback;
 
 	offset = bo->tbo.mem.start << PAGE_SHIFT;
-	return io_mapping_map_atomic_wc(map, offset + page_offset);
+	return io_mapping_map_local_wc(map, offset + page_offset);
 fallback:
 	if (bo->kptr) {
 		rptr = bo->kptr + (page_offset * PAGE_SIZE);
@@ -214,14 +214,14 @@ void qxl_bo_kunmap(struct qxl_bo *bo)
 	ttm_bo_kunmap(&bo->kmap);
 }
 
-void qxl_bo_kunmap_atomic_page(struct qxl_device *qdev,
-			       struct qxl_bo *bo, void *pmap)
+void qxl_bo_kunmap_local_page(struct qxl_device *qdev,
+			      struct qxl_bo *bo, void *pmap)
 {
 	if ((bo->tbo.mem.mem_type != TTM_PL_VRAM) &&
 	    (bo->tbo.mem.mem_type != TTM_PL_PRIV))
 		goto fallback;
 
-	io_mapping_unmap_atomic(pmap);
+	io_mapping_unmap_local(pmap);
 	return;
  fallback:
 	qxl_bo_kunmap(bo);
drivers/gpu/drm/qxl/qxl_object.h +2 -2
@@ -88,8 +88,8 @@ extern int qxl_bo_create(struct qxl_devi
 			 struct qxl_bo **bo_ptr);
 extern int qxl_bo_kmap(struct qxl_bo *bo, void **ptr);
 extern void qxl_bo_kunmap(struct qxl_bo *bo);
-void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, int page_offset);
-void qxl_bo_kunmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, void *map);
+void *qxl_bo_kmap_local_page(struct qxl_device *qdev, struct qxl_bo *bo, int page_offset);
+void qxl_bo_kunmap_local_page(struct qxl_device *qdev, struct qxl_bo *bo, void *map);
 extern struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo);
 extern void qxl_bo_unref(struct qxl_bo **bo);
 extern int qxl_bo_pin(struct qxl_bo *bo);
drivers/gpu/drm/qxl/qxl_release.c +2 -2
@@ -408,7 +408,7 @@ union qxl_release_info *qxl_release_map(
 	union qxl_release_info *info;
 	struct qxl_bo *bo = release->release_bo;
 
-	ptr = qxl_bo_kmap_atomic_page(qdev, bo, release->release_offset & PAGE_MASK);
+	ptr = qxl_bo_kmap_local_page(qdev, bo, release->release_offset & PAGE_MASK);
 	if (!ptr)
 		return NULL;
 	info = ptr + (release->release_offset & ~PAGE_MASK);
@@ -423,7 +423,7 @@ void qxl_release_unmap(struct qxl_device
 	void *ptr;
 
 	ptr = ((void *)info) - (release->release_offset & ~PAGE_MASK);
-	qxl_bo_kunmap_atomic_page(qdev, bo, ptr);
+	qxl_bo_kunmap_local_page(qdev, bo, ptr);
 }
 
 void qxl_release_fence_buffer_objects(struct qxl_release *release)
#66 lore raw

PATCH v3 35/37 drm/nouveau/device: Replace io_mapping_map_atomic_wc()

In reply to Thomas Gleixner

Neither fbmem_peek() nor fbmem_poke() require to disable pagefaults and preemption as a side effect of io_mapping_map_atomic_wc().

Use io_mapping_map_local_wc() instead.

---
V3: New patch

---
 drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/nouveau/nvkm/subdev/devinit/fbmem.h +4 -4
@@ -60,19 +60,19 @@ fbmem_fini(struct io_mapping *fb)
 static inline u32
 fbmem_peek(struct io_mapping *fb, u32 off)
 {
-	u8 __iomem *p = io_mapping_map_atomic_wc(fb, off & PAGE_MASK);
+	u8 __iomem *p = io_mapping_map_local_wc(fb, off & PAGE_MASK);
 	u32 val = ioread32(p + (off & ~PAGE_MASK));
-	io_mapping_unmap_atomic(p);
+	io_mapping_unmap_local(p);
 	return val;
 }
 
 static inline void
 fbmem_poke(struct io_mapping *fb, u32 off, u32 val)
 {
-	u8 __iomem *p = io_mapping_map_atomic_wc(fb, off & PAGE_MASK);
+	u8 __iomem *p = io_mapping_map_local_wc(fb, off & PAGE_MASK);
 	iowrite32(val, p + (off & ~PAGE_MASK));
 	wmb();
-	io_mapping_unmap_atomic(p);
+	io_mapping_unmap_local(p);
 }
 
 static inline bool
#67 lore raw

PATCH v3 36/37 drm/i915: Replace io_mapping_map_atomic_wc()

In reply to Thomas Gleixner

None of these mapping requires the side effect of disabling pagefaults and preemption.

Use io_mapping_map_local_wc() instead, and clean up gtt_user_read() and gtt_user_write() to use a plain copy_from_user() as the local maps are not disabling pagefaults.

Cc Jani Nikula <[email protected]>
Cc Joonas Lahtinen <[email protected]>
Cc Rodrigo Vivi <[email protected]>
Cc David Airlie <[email protected]>
Cc Daniel Vetter <[email protected]>

---
V3: New patch

---
 drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c |    7 +---
 drivers/gpu/drm/i915/i915_gem.c                |   40 ++++++++-----------------
 drivers/gpu/drm/i915/selftests/i915_gem.c      |    4 +-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c  |    8 ++---
 4 files changed, 22 insertions(+), 37 deletions(-)
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +3 -4
@@ -1081,7 +1081,7 @@ static void reloc_cache_reset(struct rel
 		struct i915_ggtt *ggtt = cache_to_ggtt(cache);
 
 		intel_gt_flush_ggtt_writes(ggtt->vm.gt);
-		io_mapping_unmap_atomic((void __iomem *)vaddr);
+		io_mapping_unmap_local((void __iomem *)vaddr);
 
 		if (drm_mm_node_allocated(&cache->node)) {
 			ggtt->vm.clear_range(&ggtt->vm,
@@ -1147,7 +1147,7 @@ static void *reloc_iomap(struct drm_i915
 
 	if (cache->vaddr) {
 		intel_gt_flush_ggtt_writes(ggtt->vm.gt);
-		io_mapping_unmap_atomic((void __force __iomem *) unmask_page(cache->vaddr));
+		io_mapping_unmap_local((void __force __iomem *) unmask_page(cache->vaddr));
 	} else {
 		struct i915_vma *vma;
 		int err;
@@ -1195,8 +1195,7 @@ static void *reloc_iomap(struct drm_i915
 		offset += page << PAGE_SHIFT;
 	}
 
-	vaddr = (void __force *)io_mapping_map_atomic_wc(&ggtt->iomap,
-							 offset);
+	vaddr = (void __force *)io_mapping_map_local_wc(&ggtt->iomap, offset);
 	cache->page = page;
 	cache->vaddr = (unsigned long)vaddr;
 
drivers/gpu/drm/i915/i915_gem.c +13 -27
@@ -379,22 +379,15 @@ gtt_user_read(struct io_mapping *mapping
 	      char __user *user_data, int length)
 {
 	void __iomem *vaddr;
-	unsigned long unwritten;
+	bool fail = false;
 
 	/* We can use the cpu mem copy function because this is X86. */
-	vaddr = io_mapping_map_atomic_wc(mapping, base);
-	unwritten = __copy_to_user_inatomic(user_data,
-					    (void __force *)vaddr + offset,
-					    length);
-	io_mapping_unmap_atomic(vaddr);
-	if (unwritten) {
-		vaddr = io_mapping_map_wc(mapping, base, PAGE_SIZE);
-		unwritten = copy_to_user(user_data,
-					 (void __force *)vaddr + offset,
-					 length);
-		io_mapping_unmap(vaddr);
-	}
-	return unwritten;
+	vaddr = io_mapping_map_local_wc(mapping, base);
+	if (copy_to_user(user_data, (void __force *)vaddr + offset, length))
+		fail = true;
+	io_mapping_unmap_local(vaddr);
+
+	return fail;
 }
 
 static int
@@ -557,21 +550,14 @@ ggtt_write(struct io_mapping *mapping,
 	   char __user *user_data, int length)
 {
 	void __iomem *vaddr;
-	unsigned long unwritten;
+	bool fail = false;
 
 	/* We can use the cpu mem copy function because this is X86. */
-	vaddr = io_mapping_map_atomic_wc(mapping, base);
-	unwritten = __copy_from_user_inatomic_nocache((void __force *)vaddr + offset,
-						      user_data, length);
-	io_mapping_unmap_atomic(vaddr);
-	if (unwritten) {
-		vaddr = io_mapping_map_wc(mapping, base, PAGE_SIZE);
-		unwritten = copy_from_user((void __force *)vaddr + offset,
-					   user_data, length);
-		io_mapping_unmap(vaddr);
-	}
-
-	return unwritten;
+	vaddr = io_mapping_map_local_wc(mapping, base);
+	if (copy_from_user((void __force *)vaddr + offset, user_data, length))
+		fail = true;
+	io_mapping_unmap_local(vaddr);
+	return fail;
 }
 
 /**
drivers/gpu/drm/i915/selftests/i915_gem.c +2 -2
@@ -57,12 +57,12 @@ static void trash_stolen(struct drm_i915
 
 		ggtt->vm.insert_page(&ggtt->vm, dma, slot, I915_CACHE_NONE, 0);
 
-		s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
+		s = io_mapping_map_local_wc(&ggtt->iomap, slot);
 		for (x = 0; x < PAGE_SIZE / sizeof(u32); x++) {
 			prng = next_pseudo_random32(prng);
 			iowrite32(prng, &s[x]);
 		}
-		io_mapping_unmap_atomic(s);
+		io_mapping_unmap_local(s);
 	}
 
 	ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +4 -4
@@ -1200,9 +1200,9 @@ static int igt_ggtt_page(void *arg)
 		u64 offset = tmp.start + order[n] * PAGE_SIZE;
 		u32 __iomem *vaddr;
 
-		vaddr = io_mapping_map_atomic_wc(&ggtt->iomap, offset);
+		vaddr = io_mapping_map_local_wc(&ggtt->iomap, offset);
 		iowrite32(n, vaddr + n);
-		io_mapping_unmap_atomic(vaddr);
+		io_mapping_unmap_local(vaddr);
 	}
 	intel_gt_flush_ggtt_writes(ggtt->vm.gt);
 
@@ -1212,9 +1212,9 @@ static int igt_ggtt_page(void *arg)
 		u32 __iomem *vaddr;
 		u32 val;
 
-		vaddr = io_mapping_map_atomic_wc(&ggtt->iomap, offset);
+		vaddr = io_mapping_map_local_wc(&ggtt->iomap, offset);
 		val = ioread32(vaddr + n);
-		io_mapping_unmap_atomic(vaddr);
+		io_mapping_unmap_local(vaddr);
 
 		if (val != n) {
 			pr_err("insert page failed: found %d, expected %d\n",
#68 lore raw

PATCH v3 37/37 io-mapping: Remove io_mapping_map_atomic_wc()

In reply to Thomas Gleixner

No more users. Get rid of it and remove the traces in documentation.

---
V3: New patch

---
 Documentation/driver-api/io-mapping.rst |   22 +++++-----------
 include/linux/io-mapping.h              |   42 +-------------------------------
 2 files changed, 9 insertions(+), 55 deletions(-)
Documentation/driver-api/io-mapping.rst +7 -15
@@ -21,19 +21,15 @@ mappable, while 'size' indicates how lar
 enable. Both are in bytes.
 
 This _wc variant provides a mapping which may only be used with
-io_mapping_map_atomic_wc(), io_mapping_map_local_wc() or
-io_mapping_map_wc().
+io_mapping_map_local_wc() or io_mapping_map_wc().
 
 With this mapping object, individual pages can be mapped either temporarily
 or long term, depending on the requirements. Of course, temporary maps are
-more efficient. They come in two flavours::
+more efficient.
 
 	void *io_mapping_map_local_wc(struct io_mapping *mapping,
 				      unsigned long offset)
 
-	void *io_mapping_map_atomic_wc(struct io_mapping *mapping,
-				       unsigned long offset)
-
 'offset' is the offset within the defined mapping region.  Accessing
 addresses beyond the region specified in the creation function yields
 undefined results. Using an offset which is not page aligned yields an
@@ -50,9 +46,6 @@ io_mapping_map_local_wc() has a side eff
 migration to make the mapping code work. No caller can rely on this side
 effect.
 
-io_mapping_map_atomic_wc() has the side effect of disabling preemption and
-pagefaults. Don't use in new code. Use io_mapping_map_local_wc() instead.
-
 Nested mappings need to be undone in reverse order because the mapping
 code uses a stack for keeping track of them::
 
@@ -65,11 +58,10 @@ Nested mappings need to be undone in rev
 The mappings are released with::
 
 	void io_mapping_unmap_local(void *vaddr)
-	void io_mapping_unmap_atomic(void *vaddr)
 
-'vaddr' must be the value returned by the last io_mapping_map_local_wc() or
-io_mapping_map_atomic_wc() call. This unmaps the specified mapping and
-undoes the side effects of the mapping functions.
+'vaddr' must be the value returned by the last io_mapping_map_local_wc()
+call. This unmaps the specified mapping and undoes eventual side effects of
+the mapping function.
 
 If you need to sleep while holding a mapping, you can use the regular
 variant, although this may be significantly slower::
@@ -77,8 +69,8 @@ If you need to sleep while holding a map
 	void *io_mapping_map_wc(struct io_mapping *mapping,
 				unsigned long offset)
 
-This works like io_mapping_map_atomic/local_wc() except it has no side
-effects and the pointer is globaly visible.
+This works like io_mapping_map_local_wc() except it has no side effects and
+the pointer is globaly visible.
 
 The mappings are released with::
 
include/linux/io-mapping.h +2 -40

54 lines not on this page · raw message

#69 lore raw

[Intel-gfx] ✗ Fi.CI.BUILD: failure for mm/highmem: Preemptible variant of kmap_atomic & friends

In reply to Thomas Gleixner
== Series Details ==

== Series Details ==

Series: mm/highmem: Preemptible variant of kmap_atomic & friends
URL : https://patchwork.freedesktop.org/series/83421/
State : failure

== Summary ==

Applying: mm/highmem: Un-EXPORT __kmap_atomic_idx()
Applying: highmem: Remove unused functions
Applying: fs: Remove asm/kmap_types.h includes
Applying: sh/highmem: Remove all traces of unused cruft
Applying: asm-generic: Provide kmap_size.h
Applying: highmem: Provide generic variant of kmap_atomic*
Applying: highmem: Make DEBUG_HIGHMEM functional
Applying: x86/mm/highmem: Use generic kmap atomic implementation
Applying: arc/mm/highmem: Use generic kmap atomic implementation
Applying: ARM: highmem: Switch to generic kmap atomic
Applying: csky/mm/highmem: Switch to generic kmap atomic
Applying: microblaze/mm/highmem: Switch to generic kmap atomic
Applying: mips/mm/highmem: Switch to generic kmap atomic
Applying: nds32/mm/highmem: Switch to generic kmap atomic
Applying: powerpc/mm/highmem: Switch to generic kmap atomic
Applying: sparc/mm/highmem: Switch to generic kmap atomic
Applying: xtensa/mm/highmem: Switch to generic kmap atomic
Applying: highmem: Get rid of kmap_types.h
Applying: mm/highmem: Remove the old kmap_atomic cruft
Applying: io-mapping: Cleanup atomic iomap
Applying: Documentation/io-mapping: Remove outdated blurb
Applying: highmem: High implementation details and document API
Applying: sched: Make migrate_disable/enable() independent of RT
error: sha1 information is lacking or useless (include/linux/kernel.h).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch Patch failed at 0023 sched: Make migrate_disable/enable() independent of RT When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort".

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

#70 lore raw

[Intel-gfx] ✗ Fi.CI.BUILD: failure for mm/highmem: Preemptible variant of kmap_atomic & friends (rev2)

In reply to Thomas Gleixner
== Series Details ==

== Series Details ==

Series: mm/highmem: Preemptible variant of kmap_atomic & friends (rev2)
URL : https://patchwork.freedesktop.org/series/83421/
State : failure

== Summary ==

Applying: mm/highmem: Un-EXPORT __kmap_atomic_idx()
Applying: highmem: Remove unused functions
Applying: fs: Remove asm/kmap_types.h includes
Applying: sh/highmem: Remove all traces of unused cruft
Applying: asm-generic: Provide kmap_size.h
Applying: highmem: Provide generic variant of kmap_atomic*
Applying: highmem: Make DEBUG_HIGHMEM functional
Applying: x86/mm/highmem: Use generic kmap atomic implementation
Applying: arc/mm/highmem: Use generic kmap atomic implementation
Applying: ARM: highmem: Switch to generic kmap atomic
Applying: csky/mm/highmem: Switch to generic kmap atomic
Applying: microblaze/mm/highmem: Switch to generic kmap atomic
Applying: mips/mm/highmem: Switch to generic kmap atomic
Applying: nds32/mm/highmem: Switch to generic kmap atomic
Applying: powerpc/mm/highmem: Switch to generic kmap atomic
Applying: sparc/mm/highmem: Switch to generic kmap atomic
Applying: xtensa/mm/highmem: Switch to generic kmap atomic
Applying: highmem: Get rid of kmap_types.h
Applying: mm/highmem: Remove the old kmap_atomic cruft
Applying: io-mapping: Cleanup atomic iomap
Applying: Documentation/io-mapping: Remove outdated blurb
Applying: highmem: High implementation details and document API
Applying: sched: Make migrate_disable/enable() independent of RT
error: sha1 information is lacking or useless (include/linux/kernel.h).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch Patch failed at 0023 sched: Make migrate_disable/enable() independent of RT When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort".

_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx