* [linux-next:master 2342/3265] net/bluetooth/smp.c:2185 smp_cmd_pairing_random() error: uninitialized symbol 'passkey'.
From: Dan Carpenter @ 2020-02-20 10:46 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 9694 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
head: 1d7f85df0f9c0456520ae86dc597bca87980d253
commit: cee5f20fece32cd1722230cb05333f39db860698 [2342/3265] Bluetooth: secure bluetooth stack from bluedump attack
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch warnings:
net/bluetooth/smp.c:2185 smp_cmd_pairing_random() error: uninitialized symbol 'passkey'.
# https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=cee5f20fece32cd1722230cb05333f39db860698
git remote add linux-next https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
git remote update linux-next
git checkout cee5f20fece32cd1722230cb05333f39db860698
vim +/passkey +2185 net/bluetooth/smp.c
da85e5e5afeb72 Vinicius Costa Gomes 2011-06-09 2113 static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
88ba43b662b6b9 Anderson Briglia 2011-06-09 2114 {
5d88cc73dded31 Johan Hedberg 2014-08-08 2115 struct l2cap_chan *chan = conn->smp;
5d88cc73dded31 Johan Hedberg 2014-08-08 2116 struct smp_chan *smp = chan->data;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2117 struct hci_conn *hcon = conn->hcon;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2118 u8 *pkax, *pkbx, *na, *nb;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2119 u32 passkey;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2120 int err;
7d24ddcc1140d2 Anderson Briglia 2011-06-09 2121
8aab47574a7f5b Vinicius Costa Gomes 2011-09-05 2122 BT_DBG("conn %p", conn);
7d24ddcc1140d2 Anderson Briglia 2011-06-09 2123
c46b98bea5691c Johan Hedberg 2014-02-18 2124 if (skb->len < sizeof(smp->rrnd))
38e4a915663f3f Johan Hedberg 2014-05-08 2125 return SMP_INVALID_PARAMS;
c46b98bea5691c Johan Hedberg 2014-02-18 2126
943a732ab6440f Johan Hedberg 2014-03-18 2127 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
8aab47574a7f5b Vinicius Costa Gomes 2011-09-05 2128 skb_pull(skb, sizeof(smp->rrnd));
3158c50c33c1ac Vinicius Costa Gomes 2011-06-14 2129
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2130 if (!test_bit(SMP_FLAG_SC, &smp->flags))
861580a970f1ab Johan Hedberg 2014-05-20 2131 return smp_random(smp);
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2132
580039e838a7ef Johan Hedberg 2014-12-03 2133 if (hcon->out) {
580039e838a7ef Johan Hedberg 2014-12-03 2134 pkax = smp->local_pk;
580039e838a7ef Johan Hedberg 2014-12-03 2135 pkbx = smp->remote_pk;
580039e838a7ef Johan Hedberg 2014-12-03 2136 na = smp->prnd;
580039e838a7ef Johan Hedberg 2014-12-03 2137 nb = smp->rrnd;
580039e838a7ef Johan Hedberg 2014-12-03 2138 } else {
580039e838a7ef Johan Hedberg 2014-12-03 2139 pkax = smp->remote_pk;
580039e838a7ef Johan Hedberg 2014-12-03 2140 pkbx = smp->local_pk;
580039e838a7ef Johan Hedberg 2014-12-03 2141 na = smp->rrnd;
580039e838a7ef Johan Hedberg 2014-12-03 2142 nb = smp->prnd;
580039e838a7ef Johan Hedberg 2014-12-03 2143 }
580039e838a7ef Johan Hedberg 2014-12-03 2144
a29b073351ffdd Johan Hedberg 2014-10-28 2145 if (smp->method == REQ_OOB) {
a29b073351ffdd Johan Hedberg 2014-10-28 2146 if (!hcon->out)
a29b073351ffdd Johan Hedberg 2014-10-28 2147 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
a29b073351ffdd Johan Hedberg 2014-10-28 2148 sizeof(smp->prnd), smp->prnd);
a29b073351ffdd Johan Hedberg 2014-10-28 2149 SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
a29b073351ffdd Johan Hedberg 2014-10-28 2150 goto mackey_and_ltk;
a29b073351ffdd Johan Hedberg 2014-10-28 2151 }
a29b073351ffdd Johan Hedberg 2014-10-28 2152
38606f1418cc9c Johan Hedberg 2014-06-25 2153 /* Passkey entry has special treatment */
38606f1418cc9c Johan Hedberg 2014-06-25 2154 if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
38606f1418cc9c Johan Hedberg 2014-06-25 2155 return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM);
38606f1418cc9c Johan Hedberg 2014-06-25 2156
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2157 if (hcon->out) {
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2158 u8 cfm[16];
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2159
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2160 err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2161 smp->rrnd, 0, cfm);
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2162 if (err)
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2163 return SMP_UNSPECIFIED;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2164
329d82309824ff Jason A. Donenfeld 2017-06-10 2165 if (crypto_memneq(smp->pcnf, cfm, 16))
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2166 return SMP_CONFIRM_FAILED;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2167 } else {
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2168 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2169 smp->prnd);
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2170 SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
cee5f20fece32c Howard Chung 2020-02-14 2171
cee5f20fece32c Howard Chung 2020-02-14 2172 /* Only Just-Works pairing requires extra checks */
cee5f20fece32c Howard Chung 2020-02-14 2173 if (smp->method != JUST_WORKS)
cee5f20fece32c Howard Chung 2020-02-14 2174 goto mackey_and_ltk;
cee5f20fece32c Howard Chung 2020-02-14 2175
cee5f20fece32c Howard Chung 2020-02-14 2176 /* If there already exists long term key in local host, leave
cee5f20fece32c Howard Chung 2020-02-14 2177 * the decision to user space since the remote device could
cee5f20fece32c Howard Chung 2020-02-14 2178 * be legitimate or malicious.
cee5f20fece32c Howard Chung 2020-02-14 2179 */
cee5f20fece32c Howard Chung 2020-02-14 2180 if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
cee5f20fece32c Howard Chung 2020-02-14 2181 hcon->role)) {
cee5f20fece32c Howard Chung 2020-02-14 2182 err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
cee5f20fece32c Howard Chung 2020-02-14 2183 hcon->type,
cee5f20fece32c Howard Chung 2020-02-14 2184 hcon->dst_type,
cee5f20fece32c Howard Chung 2020-02-14 @2185 passkey, 1);
^^^^^^^
Uninitialized until later in the function.
cee5f20fece32c Howard Chung 2020-02-14 2186 if (err)
cee5f20fece32c Howard Chung 2020-02-14 2187 return SMP_UNSPECIFIED;
cee5f20fece32c Howard Chung 2020-02-14 2188 set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
cee5f20fece32c Howard Chung 2020-02-14 2189 }
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2190 }
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2191
a29b073351ffdd Johan Hedberg 2014-10-28 2192 mackey_and_ltk:
760b018b6cf08e Johan Hedberg 2014-06-06 2193 /* Generate MacKey and LTK */
760b018b6cf08e Johan Hedberg 2014-06-06 2194 err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk);
760b018b6cf08e Johan Hedberg 2014-06-06 2195 if (err)
760b018b6cf08e Johan Hedberg 2014-06-06 2196 return SMP_UNSPECIFIED;
760b018b6cf08e Johan Hedberg 2014-06-06 2197
a29b073351ffdd Johan Hedberg 2014-10-28 2198 if (smp->method == JUST_WORKS || smp->method == REQ_OOB) {
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2199 if (hcon->out) {
38606f1418cc9c Johan Hedberg 2014-06-25 2200 sc_dhkey_check(smp);
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2201 SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2202 }
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2203 return 0;
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2204 }
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2205
38606f1418cc9c Johan Hedberg 2014-06-25 2206 err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38606f1418cc9c Johan Hedberg 2014-06-25 2207 if (err)
38606f1418cc9c Johan Hedberg 2014-06-25 2208 return SMP_UNSPECIFIED;
38606f1418cc9c Johan Hedberg 2014-06-25 2209
38606f1418cc9c Johan Hedberg 2014-06-25 2210 err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
38606f1418cc9c Johan Hedberg 2014-06-25 2211 hcon->dst_type, passkey, 0);
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2212 if (err)
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2213 return SMP_UNSPECIFIED;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2214
38606f1418cc9c Johan Hedberg 2014-06-25 2215 set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
38606f1418cc9c Johan Hedberg 2014-06-25 2216
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2217 return 0;
88ba43b662b6b9 Anderson Briglia 2011-06-09 2218 }
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply
* [linux-next:master 2342/3265] net/bluetooth/smp.c:2185 smp_cmd_pairing_random() error: uninitialized symbol 'passkey'.
From: Dan Carpenter @ 2020-02-20 10:46 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 9694 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
head: 1d7f85df0f9c0456520ae86dc597bca87980d253
commit: cee5f20fece32cd1722230cb05333f39db860698 [2342/3265] Bluetooth: secure bluetooth stack from bluedump attack
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch warnings:
net/bluetooth/smp.c:2185 smp_cmd_pairing_random() error: uninitialized symbol 'passkey'.
# https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=cee5f20fece32cd1722230cb05333f39db860698
git remote add linux-next https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
git remote update linux-next
git checkout cee5f20fece32cd1722230cb05333f39db860698
vim +/passkey +2185 net/bluetooth/smp.c
da85e5e5afeb72 Vinicius Costa Gomes 2011-06-09 2113 static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
88ba43b662b6b9 Anderson Briglia 2011-06-09 2114 {
5d88cc73dded31 Johan Hedberg 2014-08-08 2115 struct l2cap_chan *chan = conn->smp;
5d88cc73dded31 Johan Hedberg 2014-08-08 2116 struct smp_chan *smp = chan->data;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2117 struct hci_conn *hcon = conn->hcon;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2118 u8 *pkax, *pkbx, *na, *nb;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2119 u32 passkey;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2120 int err;
7d24ddcc1140d2 Anderson Briglia 2011-06-09 2121
8aab47574a7f5b Vinicius Costa Gomes 2011-09-05 2122 BT_DBG("conn %p", conn);
7d24ddcc1140d2 Anderson Briglia 2011-06-09 2123
c46b98bea5691c Johan Hedberg 2014-02-18 2124 if (skb->len < sizeof(smp->rrnd))
38e4a915663f3f Johan Hedberg 2014-05-08 2125 return SMP_INVALID_PARAMS;
c46b98bea5691c Johan Hedberg 2014-02-18 2126
943a732ab6440f Johan Hedberg 2014-03-18 2127 memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
8aab47574a7f5b Vinicius Costa Gomes 2011-09-05 2128 skb_pull(skb, sizeof(smp->rrnd));
3158c50c33c1ac Vinicius Costa Gomes 2011-06-14 2129
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2130 if (!test_bit(SMP_FLAG_SC, &smp->flags))
861580a970f1ab Johan Hedberg 2014-05-20 2131 return smp_random(smp);
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2132
580039e838a7ef Johan Hedberg 2014-12-03 2133 if (hcon->out) {
580039e838a7ef Johan Hedberg 2014-12-03 2134 pkax = smp->local_pk;
580039e838a7ef Johan Hedberg 2014-12-03 2135 pkbx = smp->remote_pk;
580039e838a7ef Johan Hedberg 2014-12-03 2136 na = smp->prnd;
580039e838a7ef Johan Hedberg 2014-12-03 2137 nb = smp->rrnd;
580039e838a7ef Johan Hedberg 2014-12-03 2138 } else {
580039e838a7ef Johan Hedberg 2014-12-03 2139 pkax = smp->remote_pk;
580039e838a7ef Johan Hedberg 2014-12-03 2140 pkbx = smp->local_pk;
580039e838a7ef Johan Hedberg 2014-12-03 2141 na = smp->rrnd;
580039e838a7ef Johan Hedberg 2014-12-03 2142 nb = smp->prnd;
580039e838a7ef Johan Hedberg 2014-12-03 2143 }
580039e838a7ef Johan Hedberg 2014-12-03 2144
a29b073351ffdd Johan Hedberg 2014-10-28 2145 if (smp->method == REQ_OOB) {
a29b073351ffdd Johan Hedberg 2014-10-28 2146 if (!hcon->out)
a29b073351ffdd Johan Hedberg 2014-10-28 2147 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM,
a29b073351ffdd Johan Hedberg 2014-10-28 2148 sizeof(smp->prnd), smp->prnd);
a29b073351ffdd Johan Hedberg 2014-10-28 2149 SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
a29b073351ffdd Johan Hedberg 2014-10-28 2150 goto mackey_and_ltk;
a29b073351ffdd Johan Hedberg 2014-10-28 2151 }
a29b073351ffdd Johan Hedberg 2014-10-28 2152
38606f1418cc9c Johan Hedberg 2014-06-25 2153 /* Passkey entry has special treatment */
38606f1418cc9c Johan Hedberg 2014-06-25 2154 if (smp->method == REQ_PASSKEY || smp->method == DSP_PASSKEY)
38606f1418cc9c Johan Hedberg 2014-06-25 2155 return sc_passkey_round(smp, SMP_CMD_PAIRING_RANDOM);
38606f1418cc9c Johan Hedberg 2014-06-25 2156
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2157 if (hcon->out) {
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2158 u8 cfm[16];
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2159
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2160 err = smp_f4(smp->tfm_cmac, smp->remote_pk, smp->local_pk,
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2161 smp->rrnd, 0, cfm);
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2162 if (err)
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2163 return SMP_UNSPECIFIED;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2164
329d82309824ff Jason A. Donenfeld 2017-06-10 2165 if (crypto_memneq(smp->pcnf, cfm, 16))
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2166 return SMP_CONFIRM_FAILED;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2167 } else {
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2168 smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2169 smp->prnd);
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2170 SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
cee5f20fece32c Howard Chung 2020-02-14 2171
cee5f20fece32c Howard Chung 2020-02-14 2172 /* Only Just-Works pairing requires extra checks */
cee5f20fece32c Howard Chung 2020-02-14 2173 if (smp->method != JUST_WORKS)
cee5f20fece32c Howard Chung 2020-02-14 2174 goto mackey_and_ltk;
cee5f20fece32c Howard Chung 2020-02-14 2175
cee5f20fece32c Howard Chung 2020-02-14 2176 /* If there already exists long term key in local host, leave
cee5f20fece32c Howard Chung 2020-02-14 2177 * the decision to user space since the remote device could
cee5f20fece32c Howard Chung 2020-02-14 2178 * be legitimate or malicious.
cee5f20fece32c Howard Chung 2020-02-14 2179 */
cee5f20fece32c Howard Chung 2020-02-14 2180 if (hci_find_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
cee5f20fece32c Howard Chung 2020-02-14 2181 hcon->role)) {
cee5f20fece32c Howard Chung 2020-02-14 2182 err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
cee5f20fece32c Howard Chung 2020-02-14 2183 hcon->type,
cee5f20fece32c Howard Chung 2020-02-14 2184 hcon->dst_type,
cee5f20fece32c Howard Chung 2020-02-14 @2185 passkey, 1);
^^^^^^^
Uninitialized until later in the function.
cee5f20fece32c Howard Chung 2020-02-14 2186 if (err)
cee5f20fece32c Howard Chung 2020-02-14 2187 return SMP_UNSPECIFIED;
cee5f20fece32c Howard Chung 2020-02-14 2188 set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
cee5f20fece32c Howard Chung 2020-02-14 2189 }
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2190 }
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2191
a29b073351ffdd Johan Hedberg 2014-10-28 2192 mackey_and_ltk:
760b018b6cf08e Johan Hedberg 2014-06-06 2193 /* Generate MacKey and LTK */
760b018b6cf08e Johan Hedberg 2014-06-06 2194 err = sc_mackey_and_ltk(smp, smp->mackey, smp->tk);
760b018b6cf08e Johan Hedberg 2014-06-06 2195 if (err)
760b018b6cf08e Johan Hedberg 2014-06-06 2196 return SMP_UNSPECIFIED;
760b018b6cf08e Johan Hedberg 2014-06-06 2197
a29b073351ffdd Johan Hedberg 2014-10-28 2198 if (smp->method == JUST_WORKS || smp->method == REQ_OOB) {
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2199 if (hcon->out) {
38606f1418cc9c Johan Hedberg 2014-06-25 2200 sc_dhkey_check(smp);
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2201 SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2202 }
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2203 return 0;
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2204 }
dddd3059e3bdd0 Johan Hedberg 2014-06-01 2205
38606f1418cc9c Johan Hedberg 2014-06-25 2206 err = smp_g2(smp->tfm_cmac, pkax, pkbx, na, nb, &passkey);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38606f1418cc9c Johan Hedberg 2014-06-25 2207 if (err)
38606f1418cc9c Johan Hedberg 2014-06-25 2208 return SMP_UNSPECIFIED;
38606f1418cc9c Johan Hedberg 2014-06-25 2209
38606f1418cc9c Johan Hedberg 2014-06-25 2210 err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
38606f1418cc9c Johan Hedberg 2014-06-25 2211 hcon->dst_type, passkey, 0);
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2212 if (err)
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2213 return SMP_UNSPECIFIED;
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2214
38606f1418cc9c Johan Hedberg 2014-06-25 2215 set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
38606f1418cc9c Johan Hedberg 2014-06-25 2216
191dc7fe2d3a8d Johan Hedberg 2014-06-06 2217 return 0;
88ba43b662b6b9 Anderson Briglia 2011-06-09 2218 }
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply
* Re: [PATCHv5 01/34] drm/core: Add afbc helper functions
From: Boris Brezillon @ 2020-02-20 10:47 UTC (permalink / raw)
To: Andrzej Pietrasiewicz
Cc: kernel, Mihail Atanassov, David Airlie, Liviu Dudau, Sandy Huang,
dri-devel, James Wang, Ayan Halder, Sean Paul
In-Reply-To: <20191217145020.14645-2-andrzej.p@collabora.com>
On Tue, 17 Dec 2019 15:49:47 +0100
Andrzej Pietrasiewicz <andrzej.p@collabora.com> wrote:
> +/**
> + * drm_afbc_get_superblock_wh - extract afbc block width/height from modifier
> + * @modifier: the modifier to be looked at
> + * @w: address of a place to store the block width
> + * @h: address of a place to store the block height
> + *
> + * Returns: true if the modifier describes a supported block size
> + */
> +bool drm_afbc_get_superblock_wh(u64 modifier, u32 *w, u32 *h)
You should probably take the multiplane case into account now.
Maybe introduce the following struct and pass a pointer to such
a struct instead of the w/h pointers:
struct afbc_block_size {
struct {
u32 w;
u32 h;
} plane[2];
};
Note that you could also directly return a
const struct afbc_block_size * and consider the NULL case as
'invalid format'.
> +{
> + switch (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
> + *w = 16;
> + *h = 16;
> + break;
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
> + *w = 32;
> + *h = 8;
> + break;
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
> + /* fall through */
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
> + /* fall through */
I guess display controllers might support a subset of what's actually
defined in the spec, so maybe it makes sense to pass a 'const u8
*supported_block_sizes' and then do something like:
block_size_id = modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK;
for (i = 0; i < num_supported_block_sizes; i++) {
if (supported_block_sizes[i] == block_size_id)
break;
}
if (i == num_supported_block_sizes)
return false;
The above switch-case can also be replaced by an array of structs
encoding the block size:
static const struct afbc_block_size block_sizes[] = {
[AFBC_FORMAT_MOD_BLOCK_SIZE_16x16] = { { 16, 16 } },
[AFBC_FORMAT_MOD_BLOCK_SIZE_32x8] = { { 32, 8 } },
[AFBC_FORMAT_MOD_BLOCK_SIZE_64x4] = { { 64, 4 } },
[AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4] = { { 32, 8 }, { 64, 4} },
};
*block_size = block_sizes[block_size_id];
return true;
> + default:
> + DRM_DEBUG_KMS("Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
> + modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
> + return false;
> + }
> + return true;
> +}
To sum-up, this would give something like (not even compile-tested):
struct afbc_block_size {
struct {
u32 width;
u32 height;
} plane[2];
};
static const struct afbc_block_size superblock_sizes[] = {
[AFBC_FORMAT_MOD_BLOCK_SIZE_16x16] = { { 16, 16 } },
[AFBC_FORMAT_MOD_BLOCK_SIZE_32x8] = { { 32, 8 } },
[AFBC_FORMAT_MOD_BLOCK_SIZE_64x4] = { { 64, 4 } },
[AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4] = { { 32, 8 }, { 64, 4} },
};
const struct afbc_block_size *
drm_afbc_get_superblock_info(u64 modifier,
const u8 *supported_sb_sizes,
unsigned int num_supported_sb_sizes)
{
u8 block_size_id = modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK;
if (!block_size_id ||
block_size_id >= ARRAY_SIZE(superblock_sizes)) {
DRM_DEBUG_KMS("Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
return NULL;
}
for (i = 0; i < num_supported_sb_sizes; i++) {
if (supported_sb_sizes[i] == block_size_id)
break;
}
if (i == num_supported_sb_sizes) {
DRM_DEBUG_KMS("Unsupported AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
return NULL;
}
return &superblock_sizes[block_size_id];
}
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH 08/10] riscv: Add Kendryte K210 device tree
From: Wladimir J. van der Laan @ 2020-02-20 10:48 UTC (permalink / raw)
To: Sean Anderson
Cc: Carlos Eduardo de Paula, Anup Patel, Damien Le Moal,
Palmer Dabbelt, Paul Walmsley, linux-riscv@lists.infradead.org
In-Reply-To: <cabd9527-3df3-4e5a-4669-5c14ed44e94d@gmail.com>
> > BTW speaking of which, does anyone know what's up with the K210's DMA
> > controller? It looks like it can only transfer 32-bit values from and to
> > peripherals? At least the kendryte-standalone-sdk goes to great lengths to
> > first allocate a 32-bit buffer then manually copy it to say, bytes or 16-bit
> > words. Seems quite a silly workaround with a lot of overhead.
>
> Do you have a link to that section?
It's not really one section but all over the place in all clients of the DMA.
See for example the SPI here:
https://github.com/kendryte/kendryte-standalone-sdk/blob/develop/lib/drivers/spi.c#L372
Or serial (this one tripped me up):
https://github.com/kendryte/kendryte-standalone-sdk/blob/develop/lib/drivers/uart.c#L265
https://github.com/kendryte/kendryte-standalone-sdk/blob/develop/lib/drivers/uart.c#L163
One can fairly reliably find them by looking for 'malloc' in the drivers.
A few months back I did some experiments with different values for transfer
sizes and such and wasn't able to get the DMA controller to do this, myself.
The "FIX_CACHE" define is new, BTW. They don't DMA directly from/to cached
memory anymore but use an intermediate copy in uncached special I/O memory in
the 4xxxxxxx range. I haven't had problems with e.g. manually DMAing to the screen
through SPI myself but there might be a coherency edge case (their commit messages
are not exactly enlightening).
Kind regards,
Wladimir
^ permalink raw reply
* [meta-python][PATCH] python3-grpcio: fix do_compile error for native
From: Chen Qi @ 2020-02-20 10:48 UTC (permalink / raw)
To: openembedded-devel
When building python3-grpcio-native, we will meet do_compile error
because of no 'cc'.
In fact, 'cc' is not in our hosttools. So fix to use gcc and make
the patch also apply to native.
Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
---
.../0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch | 6 +++---
.../recipes-devtools/python/python3-grpcio_1.27.1.bb | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/meta-python/recipes-devtools/python/python3-grpcio/0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch b/meta-python/recipes-devtools/python/python3-grpcio/0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch
index 131daace0..f39a82a33 100644
--- a/meta-python/recipes-devtools/python/python3-grpcio/0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch
+++ b/meta-python/recipes-devtools/python/python3-grpcio/0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch
@@ -1,4 +1,4 @@
-From b02be74a2eff8abc612ef84f30e0fbce6a7f65f5 Mon Sep 17 00:00:00 2001
+1From b02be74a2eff8abc612ef84f30e0fbce6a7f65f5 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Fri, 4 Aug 2017 09:04:07 -0700
Subject: [PATCH] setup.py: Do not mix C and C++ compiler options
@@ -24,7 +24,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
def check_linker_need_libatomic():
"""Test if linker on system needs libatomic."""
-+ compiler, cc_args = os.environ.get('CC').split(' ', 1) or 'cc'
++ compiler, cc_args = os.environ.get('CC').split(' ', 1) or 'gcc'
code_test = (b'#include <atomic>\n' +
b'int main() { return std::atomic<int64_t>{}; }')
- cc_test = subprocess.Popen(['cc', '-x', 'c++', '-std=c++11', '-'],
@@ -57,7 +57,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
"""
# TODO(lidiz) Remove the generated a.out for success tests.
- cc_test = subprocess.Popen(['cc', '-x', 'c', '-std=c++11', '-'],
-+ compiler, cc_args = os.environ.get('CC').split(' ', 1) or 'cc'
++ compiler, cc_args = os.environ.get('CC').split(' ', 1) or 'gcc'
+ cc_test = subprocess.Popen([compiler, cc_args, '-x', 'c', '-std=c++11', '-'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
diff --git a/meta-python/recipes-devtools/python/python3-grpcio_1.27.1.bb b/meta-python/recipes-devtools/python/python3-grpcio_1.27.1.bb
index bc2b70cf8..42260cb27 100644
--- a/meta-python/recipes-devtools/python/python3-grpcio_1.27.1.bb
+++ b/meta-python/recipes-devtools/python/python3-grpcio_1.27.1.bb
@@ -6,8 +6,8 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"
DEPENDS += "${PYTHON_PN}-protobuf"
-SRC_URI_append_class-target = " file://0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch \
- file://ppc-boringssl-support.patch \
+SRC_URI += "file://0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch"
+SRC_URI_append_class-target = " file://ppc-boringssl-support.patch \
file://riscv64_support.patch \
"
SRC_URI[md5sum] = "ccaf4e7eb4f031d926fb80035d193b98"
--
2.17.1
^ permalink raw reply related
* Re: [Bridge] [RFC net-next v3 00/10] net: bridge: mrp: Add support for Media Redundancy Protocol (MRP)
From: Nikolay Aleksandrov @ 2020-02-20 10:48 UTC (permalink / raw)
To: Allan W. Nielsen, Horatiu Vultur
Cc: ivecera, andrew, jiri, netdev, roopa, bridge, linux-kernel,
UNGLinuxDriver, anirudh.venkataramanan, jeffrey.t.kirsher,
olteanv, davem
In-Reply-To: <20200218121811.xo3o6zzrhl5p3j2s@lx-anielsen.microsemi.net>
On 18/02/2020 14:18, Allan W. Nielsen wrote:
>
> Hi All,
>
> Its been a while since posting this serie. We got some good and very
> specific comments, but there has not been much discussion on the overall
> architecture.
>
> Here is the list of items we have noted to be fixed in the next version:
> - The headless chicken (it keeps sending test frames if user-space
> daemon dies)
> - Avoid loops when bringing up the network - meaning we need to let MRP
> do its work before the br0 device is set to up, and we need to
> preserve that state.
> - Unnessecary ifdef on the include.
> - Extend the existing mac-table flush instead of adding
> BR_MRP_GENL_FLUSH
> - Further optimize the changes in br_handle_frame
>
> In v1 & v2 we had the entire protocol implemented in kernel-space.
> Everybody told us this is a bad idea, and in v3 we have moved as much as
> possible to user-space, and only kept the HW offload facilites in
> kernel-space. The protocol is then implemented in user-space.
>
> This is nice because it simplifies the code in the kernel and moves it
> to user-space where such complexity is easier to handle. The downside of
> this is that it makes the netlink interface more specific to our HW.
>
> The way v3 is implemented, the netlink API returns an error if a given
> operation cannot be HW offloaded. If the netlink calls return Ok,
> user-space will trust that HW do the offloading as requested, if the
> netlink calls return an error, it will implement all the functionallity
> in user-space.
>
> This works at-least in 2 scenarios: The HW we have with full MRP offload
> capabilities, and a pure SW bridge.
>
> But we should try make sure this also works in a backwards compatible
> way with future MRP aware HW, and with existing (and future) SwitchDev
> offloaded HW. At the very least we want to make this run on Ocelot, HW
> offload the MRC role, but do the MRM in SW (as the HW is not capable of
> this).
>
> If we use the kernel to abstract the MRP forwarding (not the entire
> protocol like we did in v1/v2, not just the HW like we did in v3) then
> we will have more flxibility to support other HW with a different set of
> offload facilities, we can most likely achieve better performance, and
> it would be a cleaner design.
>
> This will mean, that if user-space ask for MRP frame to be generated,
> the kernel should make sure it will happen. The kernel can try to
> offload this via the switchdev API, or it can do it in kernel-space.
>
> Again, it will mean putting back some code into kernel space, but I
> think it is worth it.
>
> What do you think, what is the right design.
>
> /Allan
>
>
In light of all the discussions and details that were explained, and as you've
noted above, I think more code should be put in kernel space at the very least
the performance/latency critical parts would benefit from being executed in the
kernel (kind of control/data-plane separation). It seems from the switchdev calls there's
a minimal state working set which define the behaviour and can be used to make
decisions (similar to STP) in the kernel, but the complex logic how to set them can be
executed in user-space meaning that maybe these hw-offload calls can have a simple SW
fallback logic based on their current values. I think it is worth considering if this can
be achieved before going to full in-kernel implementation of the state machine.
Since you intend to hw-offload it then putting in some SW fallback logic would be good
when the HW can't offload everything, what you suggest above also sounds good to me and
I think you'll have to extend mdb and the multicast code to do it, but IIRC you already
have code to do that based on previous discussions.
As was already suggested you can put the MRP options in the bridge's options and
process them from the bridge netlink code, that should simplify your code. You could
also make the port's "mrp_aware" bool into an internal port flag (use net_bridge_port's
flags field) so it can be quickly tested and in a hot cache line.
> On 24.01.2020 17:18, Horatiu Vultur wrote:
>> Media Redundancy Protocol is a data network protocol standardized by
>> International Electrotechnical Commission as IEC 62439-2. It allows rings of
>> Ethernet switches to overcome any single failure with recovery time faster than
>> STP. It is primarily used in Industrial Ethernet applications.
>>
>> Based on the previous RFC[1][2], the MRP state machine and all the
>> timers were moved to userspace. A generic netlink interface is added to
>> allow configuring the HW, and logic added to to implement the MRP
>> specific forwarding rules.
>>
>> The userspace application that is using the new netlink can be found here[3].
>>
>> The current implementation both in kernel and userspace supports only 2 roles:
>>
>> MRM - this one is responsible to send MRP_Test and MRP_Topo frames on both
>> ring ports. It needs to process MRP_Test to know if the ring is open or
>> closed. This operation is desired to be offloaded to the HW because it
>> requires to generate and process up to 4000 frames per second. Whenever it
>> detects that the ring open it sends MRP_Topo frames to notify all MRC about
>> changes in the topology. MRM needs also to process MRP_LinkChange frames,
>> these frames are generated by the MRC. When the ring is open the the state
>> of both ports is to forward frames and when the ring is closed then the
>> secondary port is blocked.
>>
>> MRC - this one is responsible to forward MRP frames between the ring ports.
>> In case one of the ring ports gets a link down or up, then MRC will generate
>> a MRP_LinkChange frames. This node should also process MRP_Topo frames and to
>> clear its FDB when it receives this frame.
>>
>> Userspace
>> Deamon +----------+ Client
>> +
>> |
>> +--------------|-----------------------------------------+
>> Kernel |
>> + Netlink
>>
>> | + Interrupt
>> | |
>> +--------------|------------------------------|----------+
>> HW | Switchdev |
>> + |
>>
>> The user interacts using the client (called 'mrp'), the client talks to the
>> deamon (called 'mrp_server'), which talks with the kernel using netlink. The
>> kernel will try to offload the requests to the HW via switchdev API. For this a
>> new generic netlink interface was added to the bridge.
>>
>> If the kernel cannot offload MRP to HW (maybe it does not have a switchdev
>> driver, or it is just not supported), then all the netlink calls will return
>> -EOPNOTSUPP. In this case the user-space deamon fallback to SW only
>> implementation.
>>
>> There are required changes to the SW bridge to be able to run the MRP. First the
>> bridge needs to initialize the netlink interface. And second it needs to know if
>> a MRP frame was received on a MRP ring port. In case it was received the SW
>> bridge should not forward the frame it needs to redirected to upper layes. In
>> case it was not received on a ring port then it just forwards it as usual.
>>
>> To be able to offload this to the HW, it was required to extend the switchdev
>> API.
>>
>> If this will be accepted then in the future the netlink interface can be
>> expended with multiple attributes which are required by different roles of the
>> MRP. Like Media Redundancy Automanager(MRA), Media Interconnect Manager(MIM) and
>> Media Interconnect Client(MIC).
>>
>> [1] https://www.spinics.net/lists/netdev/msg623647.html
>> [2] https://www.spinics.net/lists/netdev/msg624378.html
>> [3] https://github.com/microchip-ung/mrp/tree/patch-v3
>>
>> Horatiu Vultur (10):
>> net: bridge: mrp: Expose mrp attributes.
>> net: bridge: mrp: Expose function br_mrp_port_open
>> net: bridge: mrp: Add MRP interface used by netlink
>> net: bridge: mrp: Add generic netlink interface to configure MRP
>> net: bridge: mrp: Update MRP interface to add switchdev support
>> net: bridge: mrp: switchdev: Extend switchdev API to offload MRP
>> net: bridge: mrp: switchdev: Implement MRP API for switchdev
>> net: bridge: mrp: Connect MRP api with the switchev API
>> net: bridge: mrp: Integrate MRP into the bridge
>> net: bridge: mrp: Update Kconfig and Makefile
>>
>> include/linux/mrp_bridge.h | 25 ++
>> include/net/switchdev.h | 51 +++
>> include/uapi/linux/if_ether.h | 1 +
>> include/uapi/linux/mrp_bridge.h | 118 ++++++
>> net/bridge/Kconfig | 12 +
>> net/bridge/Makefile | 2 +
>> net/bridge/br.c | 11 +
>> net/bridge/br_device.c | 3 +
>> net/bridge/br_if.c | 6 +
>> net/bridge/br_input.c | 14 +
>> net/bridge/br_mrp.c | 193 ++++++++++
>> net/bridge/br_mrp_netlink.c | 655 ++++++++++++++++++++++++++++++++
>> net/bridge/br_mrp_switchdev.c | 147 +++++++
>> net/bridge/br_private.h | 14 +
>> net/bridge/br_private_mrp.h | 58 +++
>> 15 files changed, 1310 insertions(+)
>> create mode 100644 include/linux/mrp_bridge.h
>> create mode 100644 include/uapi/linux/mrp_bridge.h
>> create mode 100644 net/bridge/br_mrp.c
>> create mode 100644 net/bridge/br_mrp_netlink.c
>> create mode 100644 net/bridge/br_mrp_switchdev.c
>> create mode 100644 net/bridge/br_private_mrp.h
>>
>> --
>> 2.17.1
>>
> /Allan
^ permalink raw reply
* Re: [RFC net-next v3 00/10] net: bridge: mrp: Add support for Media Redundancy Protocol (MRP)
From: Nikolay Aleksandrov @ 2020-02-20 10:48 UTC (permalink / raw)
To: Allan W. Nielsen, Horatiu Vultur
Cc: linux-kernel, netdev, bridge, jiri, ivecera, davem, roopa,
anirudh.venkataramanan, olteanv, andrew, jeffrey.t.kirsher,
UNGLinuxDriver
In-Reply-To: <20200218121811.xo3o6zzrhl5p3j2s@lx-anielsen.microsemi.net>
On 18/02/2020 14:18, Allan W. Nielsen wrote:
>
> Hi All,
>
> Its been a while since posting this serie. We got some good and very
> specific comments, but there has not been much discussion on the overall
> architecture.
>
> Here is the list of items we have noted to be fixed in the next version:
> - The headless chicken (it keeps sending test frames if user-space
> daemon dies)
> - Avoid loops when bringing up the network - meaning we need to let MRP
> do its work before the br0 device is set to up, and we need to
> preserve that state.
> - Unnessecary ifdef on the include.
> - Extend the existing mac-table flush instead of adding
> BR_MRP_GENL_FLUSH
> - Further optimize the changes in br_handle_frame
>
> In v1 & v2 we had the entire protocol implemented in kernel-space.
> Everybody told us this is a bad idea, and in v3 we have moved as much as
> possible to user-space, and only kept the HW offload facilites in
> kernel-space. The protocol is then implemented in user-space.
>
> This is nice because it simplifies the code in the kernel and moves it
> to user-space where such complexity is easier to handle. The downside of
> this is that it makes the netlink interface more specific to our HW.
>
> The way v3 is implemented, the netlink API returns an error if a given
> operation cannot be HW offloaded. If the netlink calls return Ok,
> user-space will trust that HW do the offloading as requested, if the
> netlink calls return an error, it will implement all the functionallity
> in user-space.
>
> This works at-least in 2 scenarios: The HW we have with full MRP offload
> capabilities, and a pure SW bridge.
>
> But we should try make sure this also works in a backwards compatible
> way with future MRP aware HW, and with existing (and future) SwitchDev
> offloaded HW. At the very least we want to make this run on Ocelot, HW
> offload the MRC role, but do the MRM in SW (as the HW is not capable of
> this).
>
> If we use the kernel to abstract the MRP forwarding (not the entire
> protocol like we did in v1/v2, not just the HW like we did in v3) then
> we will have more flxibility to support other HW with a different set of
> offload facilities, we can most likely achieve better performance, and
> it would be a cleaner design.
>
> This will mean, that if user-space ask for MRP frame to be generated,
> the kernel should make sure it will happen. The kernel can try to
> offload this via the switchdev API, or it can do it in kernel-space.
>
> Again, it will mean putting back some code into kernel space, but I
> think it is worth it.
>
> What do you think, what is the right design.
>
> /Allan
>
>
In light of all the discussions and details that were explained, and as you've
noted above, I think more code should be put in kernel space at the very least
the performance/latency critical parts would benefit from being executed in the
kernel (kind of control/data-plane separation). It seems from the switchdev calls there's
a minimal state working set which define the behaviour and can be used to make
decisions (similar to STP) in the kernel, but the complex logic how to set them can be
executed in user-space meaning that maybe these hw-offload calls can have a simple SW
fallback logic based on their current values. I think it is worth considering if this can
be achieved before going to full in-kernel implementation of the state machine.
Since you intend to hw-offload it then putting in some SW fallback logic would be good
when the HW can't offload everything, what you suggest above also sounds good to me and
I think you'll have to extend mdb and the multicast code to do it, but IIRC you already
have code to do that based on previous discussions.
As was already suggested you can put the MRP options in the bridge's options and
process them from the bridge netlink code, that should simplify your code. You could
also make the port's "mrp_aware" bool into an internal port flag (use net_bridge_port's
flags field) so it can be quickly tested and in a hot cache line.
> On 24.01.2020 17:18, Horatiu Vultur wrote:
>> Media Redundancy Protocol is a data network protocol standardized by
>> International Electrotechnical Commission as IEC 62439-2. It allows rings of
>> Ethernet switches to overcome any single failure with recovery time faster than
>> STP. It is primarily used in Industrial Ethernet applications.
>>
>> Based on the previous RFC[1][2], the MRP state machine and all the
>> timers were moved to userspace. A generic netlink interface is added to
>> allow configuring the HW, and logic added to to implement the MRP
>> specific forwarding rules.
>>
>> The userspace application that is using the new netlink can be found here[3].
>>
>> The current implementation both in kernel and userspace supports only 2 roles:
>>
>> MRM - this one is responsible to send MRP_Test and MRP_Topo frames on both
>> ring ports. It needs to process MRP_Test to know if the ring is open or
>> closed. This operation is desired to be offloaded to the HW because it
>> requires to generate and process up to 4000 frames per second. Whenever it
>> detects that the ring open it sends MRP_Topo frames to notify all MRC about
>> changes in the topology. MRM needs also to process MRP_LinkChange frames,
>> these frames are generated by the MRC. When the ring is open the the state
>> of both ports is to forward frames and when the ring is closed then the
>> secondary port is blocked.
>>
>> MRC - this one is responsible to forward MRP frames between the ring ports.
>> In case one of the ring ports gets a link down or up, then MRC will generate
>> a MRP_LinkChange frames. This node should also process MRP_Topo frames and to
>> clear its FDB when it receives this frame.
>>
>> Userspace
>> Deamon +----------+ Client
>> +
>> |
>> +--------------|-----------------------------------------+
>> Kernel |
>> + Netlink
>>
>> | + Interrupt
>> | |
>> +--------------|------------------------------|----------+
>> HW | Switchdev |
>> + |
>>
>> The user interacts using the client (called 'mrp'), the client talks to the
>> deamon (called 'mrp_server'), which talks with the kernel using netlink. The
>> kernel will try to offload the requests to the HW via switchdev API. For this a
>> new generic netlink interface was added to the bridge.
>>
>> If the kernel cannot offload MRP to HW (maybe it does not have a switchdev
>> driver, or it is just not supported), then all the netlink calls will return
>> -EOPNOTSUPP. In this case the user-space deamon fallback to SW only
>> implementation.
>>
>> There are required changes to the SW bridge to be able to run the MRP. First the
>> bridge needs to initialize the netlink interface. And second it needs to know if
>> a MRP frame was received on a MRP ring port. In case it was received the SW
>> bridge should not forward the frame it needs to redirected to upper layes. In
>> case it was not received on a ring port then it just forwards it as usual.
>>
>> To be able to offload this to the HW, it was required to extend the switchdev
>> API.
>>
>> If this will be accepted then in the future the netlink interface can be
>> expended with multiple attributes which are required by different roles of the
>> MRP. Like Media Redundancy Automanager(MRA), Media Interconnect Manager(MIM) and
>> Media Interconnect Client(MIC).
>>
>> [1] https://www.spinics.net/lists/netdev/msg623647.html
>> [2] https://www.spinics.net/lists/netdev/msg624378.html
>> [3] https://github.com/microchip-ung/mrp/tree/patch-v3
>>
>> Horatiu Vultur (10):
>> net: bridge: mrp: Expose mrp attributes.
>> net: bridge: mrp: Expose function br_mrp_port_open
>> net: bridge: mrp: Add MRP interface used by netlink
>> net: bridge: mrp: Add generic netlink interface to configure MRP
>> net: bridge: mrp: Update MRP interface to add switchdev support
>> net: bridge: mrp: switchdev: Extend switchdev API to offload MRP
>> net: bridge: mrp: switchdev: Implement MRP API for switchdev
>> net: bridge: mrp: Connect MRP api with the switchev API
>> net: bridge: mrp: Integrate MRP into the bridge
>> net: bridge: mrp: Update Kconfig and Makefile
>>
>> include/linux/mrp_bridge.h | 25 ++
>> include/net/switchdev.h | 51 +++
>> include/uapi/linux/if_ether.h | 1 +
>> include/uapi/linux/mrp_bridge.h | 118 ++++++
>> net/bridge/Kconfig | 12 +
>> net/bridge/Makefile | 2 +
>> net/bridge/br.c | 11 +
>> net/bridge/br_device.c | 3 +
>> net/bridge/br_if.c | 6 +
>> net/bridge/br_input.c | 14 +
>> net/bridge/br_mrp.c | 193 ++++++++++
>> net/bridge/br_mrp_netlink.c | 655 ++++++++++++++++++++++++++++++++
>> net/bridge/br_mrp_switchdev.c | 147 +++++++
>> net/bridge/br_private.h | 14 +
>> net/bridge/br_private_mrp.h | 58 +++
>> 15 files changed, 1310 insertions(+)
>> create mode 100644 include/linux/mrp_bridge.h
>> create mode 100644 include/uapi/linux/mrp_bridge.h
>> create mode 100644 net/bridge/br_mrp.c
>> create mode 100644 net/bridge/br_mrp_netlink.c
>> create mode 100644 net/bridge/br_mrp_switchdev.c
>> create mode 100644 net/bridge/br_private_mrp.h
>>
>> --
>> 2.17.1
>>
> /Allan
^ permalink raw reply
* Re: [PATCH v3 06/17] s390x: protvirt: Add migration blocker
From: Cornelia Huck @ 2020-02-20 10:48 UTC (permalink / raw)
To: Janosch Frank; +Cc: qemu-s390x, mihajlov, qemu-devel, david
In-Reply-To: <20200214151636.8764-7-frankja@linux.ibm.com>
On Fri, 14 Feb 2020 10:16:25 -0500
Janosch Frank <frankja@linux.ibm.com> wrote:
> Migration is not yet supported.
>
> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
> ---
> hw/s390x/s390-virtio-ccw.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
> index 5fa4372083..d64724af91 100644
> --- a/hw/s390x/s390-virtio-ccw.c
> +++ b/hw/s390x/s390-virtio-ccw.c
> @@ -42,6 +42,9 @@
> #include "hw/s390x/tod.h"
> #include "sysemu/sysemu.h"
> #include "hw/s390x/pv.h"
> +#include "migration/blocker.h"
> +
> +static Error *pv_mig_blocker;
>
> S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
> {
> @@ -373,6 +376,7 @@ static void s390_machine_reset(MachineState *machine)
> CPUState *cs, *t;
> S390CPU *cpu;
> S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
> + static Error *local_err;
>
> /* get the reset parameters, reset them once done */
> s390_ipl_get_reset_request(&cs, &reset_type);
> @@ -422,6 +426,17 @@ static void s390_machine_reset(MachineState *machine)
> }
> run_on_cpu(cs, s390_do_cpu_reset, RUN_ON_CPU_NULL);
>
> + if (!pv_mig_blocker) {
> + error_setg(&pv_mig_blocker,
> + "protected VMs are currently not migrateable.");
> + }
> + migrate_add_blocker(pv_mig_blocker, &local_err);
If I'm not lost in the context, that's during PV_RESET. I'm a bit
confused why you'd add the blocker here?
> + if (local_err) {
> + error_report_err(local_err);
> + error_free(pv_mig_blocker);
> + exit(1);
Why the exit()? Can't you fail the call?
> + }
> +
> if (s390_machine_pv_secure(ms)) {
> CPU_FOREACH(t) {
> s390_pv_vcpu_destroy(t);
> @@ -430,6 +445,7 @@ static void s390_machine_reset(MachineState *machine)
> ms->pv = false;
>
> s390_machine_inject_pv_error(cs);
> + migrate_del_blocker(pv_mig_blocker);
> s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
> return;
> }
^ permalink raw reply
* [meta-python][PATCH] python3-grpcio: fix do_compile error for native
From: Chen Qi @ 2020-02-20 10:49 UTC (permalink / raw)
To: openembedded-devel
When building python3-grpcio-native, we will meet do_compile error
because of no 'cc'.
In fact, 'cc' is not in our hosttools. So fix to use gcc and make
the patch also apply to native.
Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
---
.../0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch | 6 +++---
.../recipes-devtools/python/python3-grpcio_1.27.1.bb | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/meta-python/recipes-devtools/python/python3-grpcio/0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch b/meta-python/recipes-devtools/python/python3-grpcio/0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch
index 131daace0..f39a82a33 100644
--- a/meta-python/recipes-devtools/python/python3-grpcio/0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch
+++ b/meta-python/recipes-devtools/python/python3-grpcio/0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch
@@ -1,4 +1,4 @@
-From b02be74a2eff8abc612ef84f30e0fbce6a7f65f5 Mon Sep 17 00:00:00 2001
+1From b02be74a2eff8abc612ef84f30e0fbce6a7f65f5 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Fri, 4 Aug 2017 09:04:07 -0700
Subject: [PATCH] setup.py: Do not mix C and C++ compiler options
@@ -24,7 +24,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
def check_linker_need_libatomic():
"""Test if linker on system needs libatomic."""
-+ compiler, cc_args = os.environ.get('CC').split(' ', 1) or 'cc'
++ compiler, cc_args = os.environ.get('CC').split(' ', 1) or 'gcc'
code_test = (b'#include <atomic>\n' +
b'int main() { return std::atomic<int64_t>{}; }')
- cc_test = subprocess.Popen(['cc', '-x', 'c++', '-std=c++11', '-'],
@@ -57,7 +57,7 @@ Signed-off-by: Khem Raj <raj.khem@gmail.com>
"""
# TODO(lidiz) Remove the generated a.out for success tests.
- cc_test = subprocess.Popen(['cc', '-x', 'c', '-std=c++11', '-'],
-+ compiler, cc_args = os.environ.get('CC').split(' ', 1) or 'cc'
++ compiler, cc_args = os.environ.get('CC').split(' ', 1) or 'gcc'
+ cc_test = subprocess.Popen([compiler, cc_args, '-x', 'c', '-std=c++11', '-'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
diff --git a/meta-python/recipes-devtools/python/python3-grpcio_1.27.1.bb b/meta-python/recipes-devtools/python/python3-grpcio_1.27.1.bb
index bc2b70cf8..42260cb27 100644
--- a/meta-python/recipes-devtools/python/python3-grpcio_1.27.1.bb
+++ b/meta-python/recipes-devtools/python/python3-grpcio_1.27.1.bb
@@ -6,8 +6,8 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"
DEPENDS += "${PYTHON_PN}-protobuf"
-SRC_URI_append_class-target = " file://0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch \
- file://ppc-boringssl-support.patch \
+SRC_URI += "file://0001-setup.py-Do-not-mix-C-and-C-compiler-options.patch"
+SRC_URI_append_class-target = " file://ppc-boringssl-support.patch \
file://riscv64_support.patch \
"
SRC_URI[md5sum] = "ccaf4e7eb4f031d926fb80035d193b98"
--
2.17.1
^ permalink raw reply related
* [ndctl PATCH 0/8] Add support for reporting papr-scm nvdimm health
From: Vaibhav Jain @ 2020-02-20 10:49 UTC (permalink / raw)
To: linux-nvdimm; +Cc: Vaibhav Jain, Aneesh Kumar K . V, Alastair D'Silva
This patch-set proposes changes to libndctl to add support for reporting
health for nvdimms that support the PAPR standard[1]. The standard defines
heathenism (HCALL) through which a guest kernel can query and fetch health
and performance stats of an nvdimm attached to the hypervisor[2]. Until
now 'ndctl' was unable to report these stats for papr_scm dimms on PPC64
guests due to absence of ACPI/NFIT, a limitation which this patch-set tries
to address.
The patch-set introduces support for the new PAPR-SCM DSM family defined at
[3] via a new dimm-ops named 'papr_scm_dimm_ops'. Infrastructure to probe
and distinguish papr-scm dimms from other dimm families that may support
ACPI/NFIT is implemented by updating the 'struct ndctl_dimm' initialization
routines to bifurcate based on the nvdimm type. We also introduce two new
dimm-ops for handling initialization of dimm specific data for specific DSM
families.
These changes coupled with proposed ndtcl changes located at Ref[4] should
provide a way for the user to retrieve NVDIMM health status using ndtcl for
papr_scm guests. Below is a sample output using proposed kernel + ndctl
changes:
# ndctl list -DH
[
{
"dev":"nmem0",
"health":{
"health_state":"fatal",
"shutdown_state":"dirty"
}
}
]
Structure of the patchset
=========================
We start with a re-factoring patch that splits the 'add_dimm()' function
into two functions one that take care of allocating and initializing
'struct ndctl_dimm' and another that takes care of initializing nfit
specific dimm attributes.
Patch-2 introduces new dimm ops 'dimm_init()' & 'dimm_uninit()' to handle
DSM family specific initialization of 'struct ndctl_dimm'.
Patch-3 introduces probe function of papr_scm nvdimms and assigning
'papr_scm_dimm_ops' to 'dimm->ops' if needed. Subsequent patch-4 adds
support for parsing papr_scm nvdimm flags and updating 'dimm->flags' with
them.
Patches-5,6 implements scaffolding to add support for PAPR_SCM DSM commands
and pull in their definitions from the kernel. This implementation resides
in newly added 'papr_scm.c' file.
Finally Patched-7,8 add support for issuing and handling the result of
'struct ndctl_cmd' to request dimm health stats from papr_scm kernel module
and returning appropriate health status to libndctl for reporting.
References:
[1]: "Power Architecture Platform Reference"
https://en.wikipedia.org/wiki/Power_Architecture_Platform_Reference
[2]: "[DOC,v2] powerpc: Provide initial documentation for PAPR hcalls"
https://patchwork.ozlabs.org/patch/1154292/
[3]: "[PATCH 5/8] powerpc/uapi: Introduce uapi header 'papr_scm_dsm.h' for
papr_scm DSMs"
https://patchwork.ozlabs.org/patch/1241352/
[4]: "powerpc/papr_scm: Add support for reporting nvdimm health"
https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=159701
Vaibhav Jain (8):
libndctl: Refactor out add_dimm() to handle NFIT specific init
libndctl: Introduce a new dimm-ops dimm_init() & dimm_uninit()
libncdtl: Add initial support for NVDIMM_FAMILY_PAPR_SCM dimm family
libndctl: Add support for parsing of_pmem dimm flags and monitor mode
libndctl,papr_scm: Add definitions for PAPR_SCM DSM commands
libndctl,papr_scm: Implement scaffolding to issue and handle DSM cmds
libndctl,papr_scm: Implement support for DSM_PAPR_SCM_HEALTH
libndctl,papr_scm: Add support for reporting bad shutdown
ndctl/lib/Makefile.am | 1 +
ndctl/lib/libndctl.c | 263 +++++++++++++++++++++++++----------
ndctl/lib/papr_scm.c | 292 +++++++++++++++++++++++++++++++++++++++
ndctl/lib/papr_scm_dsm.h | 143 +++++++++++++++++++
ndctl/lib/private.h | 7 +
ndctl/libndctl.h | 1 +
ndctl/ndctl.h | 1 +
7 files changed, 634 insertions(+), 74 deletions(-)
create mode 100644 ndctl/lib/papr_scm.c
create mode 100644 ndctl/lib/papr_scm_dsm.h
--
2.24.1
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
^ permalink raw reply
* Re: [PATCH] thinkpad_acpi: Add sysfs entry for lcdshadow feature
From: Andy Shevchenko @ 2020-02-20 10:42 UTC (permalink / raw)
To: Nitin Joshi, Mat King, Jani Nikula, Daniel Thompson, Jingoo Han,
Rajat Jain
Cc: Nitin Joshi, Greg Kroah-Hartman, Henrique de Moraes Holschuh,
Linux Kernel Mailing List, dri-devel, Platform Driver,
Thinkpad-acpi devel ML, Andy Shevchenko, Darren Hart, mpearson,
Benjamin Berg
In-Reply-To: <20200220074637.7578-1-njoshi1@lenovo.com>
On Thu, Feb 20, 2020 at 9:48 AM Nitin Joshi <nitjoshi@gmail.com> wrote:
>
> This feature is supported on some Thinkpad products like T490s, Thinkpad
> X1 yoga 4th Gen etc . The lcdshadow feature can be enabled and disabled
> when user press "Fn" + "D" key. Currently, no user feedback is given for
> this action. Adding as sysfs entry allows userspace to show an On Screen
> Display whenever the setting changes.
>
> Summary of changes is mentioned below :
>
> - Added TP_HKEY_EV_LCDSHADOW_CHANGED for consistency inside the driver
> - Added unmapped LCDSHADOW to keymap
> - Added lcdshadow_get function to read value using ACPI
> - Added lcdshadow_refresh function to re-read value and send notification
> - Added sysfs group creation to tpaci_lcdshadow_init
> - Added lcdshadow_exit to remove sysfs group again
> - Implemented lcdshadow_enable_show/lcdshadow_enable_store
> - Added handler to tpacpi_driver_event to update refresh lcdshadow
> - Explicitly call tpacpi_driver_event for extended keyset
Adding custom PrivacyGuard support to this driver was my mistake,
There is a discussion [1] how to do this in generic way to cover other
possible users.
I Cc this to people from that discussion.
[1]: https://lore.kernel.org/dri-devel/CAL_quvRknSSVvXN3q_Se0hrziw2oTNS3ENNoeHYhvciCRq9Yww@mail.gmail.com/
--
With Best Regards,
Andy Shevchenko
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* [ndctl PATCH 1/8] libndctl: Refactor out add_dimm() to handle NFIT specific init
From: Vaibhav Jain @ 2020-02-20 10:49 UTC (permalink / raw)
To: linux-nvdimm; +Cc: Vaibhav Jain, Aneesh Kumar K . V, Alastair D'Silva
In-Reply-To: <20200220104928.198625-1-vaibhav@linux.ibm.com>
Presently add_dimm() only probes dimms that support NFIT/ACPI. Hence
this patch refactors this functionality into two functions namely
add_dimm() and add_nfit_dimm(). Function add_dimm() performs
allocation and common 'struct ndctl_dimm' initialization and depending
on whether the dimm-bus supports NIFT, calls add_nfit_dimm(). Once
the probe is completed based on the value of 'ndctl_dimm.cmd_family'
appropriate dimm-ops are assigned to the dimm.
In case dimm-bus is of unknown type or doesn't support NFIT the
initialization still continues, with no dimm-ops assigned to the
'struct ndctl_dimm' there-by limiting the functionality available.
This patch shouldn't introduce any behavioral change.
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
---
ndctl/lib/libndctl.c | 193 +++++++++++++++++++++++++------------------
1 file changed, 112 insertions(+), 81 deletions(-)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index d6a28002e7d6..38ddfea6dbc0 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -1401,82 +1401,15 @@ static int ndctl_bind(struct ndctl_ctx *ctx, struct kmod_module *module,
static int ndctl_unbind(struct ndctl_ctx *ctx, const char *devpath);
static struct kmod_module *to_module(struct ndctl_ctx *ctx, const char *alias);
-static void *add_dimm(void *parent, int id, const char *dimm_base)
+static int add_nfit_dimm(struct ndctl_dimm *dimm, const char *dimm_base)
{
- int formats, i;
- struct ndctl_dimm *dimm;
+ int i, rc = -1;
char buf[SYSFS_ATTR_SIZE];
- struct ndctl_bus *bus = parent;
- struct ndctl_ctx *ctx = bus->ctx;
+ struct ndctl_ctx *ctx = dimm->bus->ctx;
char *path = calloc(1, strlen(dimm_base) + 100);
if (!path)
- return NULL;
-
- sprintf(path, "%s/nfit/formats", dimm_base);
- if (sysfs_read_attr(ctx, path, buf) < 0)
- formats = 1;
- else
- formats = clamp(strtoul(buf, NULL, 0), 1UL, 2UL);
-
- dimm = calloc(1, sizeof(*dimm) + sizeof(int) * formats);
- if (!dimm)
- goto err_dimm;
- dimm->bus = bus;
- dimm->id = id;
-
- sprintf(path, "%s/dev", dimm_base);
- if (sysfs_read_attr(ctx, path, buf) < 0)
- goto err_read;
- if (sscanf(buf, "%d:%d", &dimm->major, &dimm->minor) != 2)
- goto err_read;
-
- sprintf(path, "%s/commands", dimm_base);
- if (sysfs_read_attr(ctx, path, buf) < 0)
- goto err_read;
- dimm->cmd_mask = parse_commands(buf, 1);
-
- dimm->dimm_buf = calloc(1, strlen(dimm_base) + 50);
- if (!dimm->dimm_buf)
- goto err_read;
- dimm->buf_len = strlen(dimm_base) + 50;
-
- dimm->dimm_path = strdup(dimm_base);
- if (!dimm->dimm_path)
- goto err_read;
-
- sprintf(path, "%s/modalias", dimm_base);
- if (sysfs_read_attr(ctx, path, buf) < 0)
- goto err_read;
- dimm->module = to_module(ctx, buf);
-
- dimm->handle = -1;
- dimm->phys_id = -1;
- dimm->serial = -1;
- dimm->vendor_id = -1;
- dimm->device_id = -1;
- dimm->revision_id = -1;
- dimm->health_eventfd = -1;
- dimm->dirty_shutdown = -ENOENT;
- dimm->subsystem_vendor_id = -1;
- dimm->subsystem_device_id = -1;
- dimm->subsystem_revision_id = -1;
- dimm->manufacturing_date = -1;
- dimm->manufacturing_location = -1;
- dimm->cmd_family = -1;
- dimm->nfit_dsm_mask = ULONG_MAX;
- for (i = 0; i < formats; i++)
- dimm->format[i] = -1;
-
- sprintf(path, "%s/flags", dimm_base);
- if (sysfs_read_attr(ctx, path, buf) < 0) {
- dimm->locked = -1;
- dimm->aliased = -1;
- } else
- parse_dimm_flags(dimm, buf);
-
- if (!ndctl_bus_has_nfit(bus))
- goto out;
+ return -1;
/*
* 'unique_id' may not be available on older kernels, so don't
@@ -1542,24 +1475,15 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
sprintf(path, "%s/nfit/family", dimm_base);
if (sysfs_read_attr(ctx, path, buf) == 0)
dimm->cmd_family = strtoul(buf, NULL, 0);
- if (dimm->cmd_family == NVDIMM_FAMILY_INTEL)
- dimm->ops = intel_dimm_ops;
- if (dimm->cmd_family == NVDIMM_FAMILY_HPE1)
- dimm->ops = hpe1_dimm_ops;
- if (dimm->cmd_family == NVDIMM_FAMILY_MSFT)
- dimm->ops = msft_dimm_ops;
- if (dimm->cmd_family == NVDIMM_FAMILY_HYPERV)
- dimm->ops = hyperv_dimm_ops;
sprintf(path, "%s/nfit/dsm_mask", dimm_base);
if (sysfs_read_attr(ctx, path, buf) == 0)
dimm->nfit_dsm_mask = strtoul(buf, NULL, 0);
- dimm->formats = formats;
sprintf(path, "%s/nfit/format", dimm_base);
if (sysfs_read_attr(ctx, path, buf) == 0)
dimm->format[0] = strtoul(buf, NULL, 0);
- for (i = 1; i < formats; i++) {
+ for (i = 1; i < dimm->formats; i++) {
sprintf(path, "%s/nfit/format%d", dimm_base, i);
if (sysfs_read_attr(ctx, path, buf) == 0)
dimm->format[i] = strtoul(buf, NULL, 0);
@@ -1570,7 +1494,114 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
parse_nfit_mem_flags(dimm, buf);
dimm->health_eventfd = open(path, O_RDONLY|O_CLOEXEC);
+ rc = 0;
+ err_read:
+
+ free(path);
+ return rc;
+}
+
+static void *add_dimm(void *parent, int id, const char *dimm_base)
+{
+ int formats, i, rc = -ENODEV;
+ struct ndctl_dimm *dimm = NULL;
+ char buf[SYSFS_ATTR_SIZE];
+ struct ndctl_bus *bus = parent;
+ struct ndctl_ctx *ctx = bus->ctx;
+ char *path = calloc(1, strlen(dimm_base) + 100);
+
+ if (!path)
+ return NULL;
+
+ sprintf(path, "%s/nfit/formats", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) < 0)
+ formats = 1;
+ else
+ formats = clamp(strtoul(buf, NULL, 0), 1UL, 2UL);
+
+ dimm = calloc(1, sizeof(*dimm) + sizeof(int) * formats);
+ if (!dimm)
+ goto err_dimm;
+ dimm->bus = bus;
+ dimm->id = id;
+
+ sprintf(path, "%s/dev", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) < 0)
+ goto err_read;
+ if (sscanf(buf, "%d:%d", &dimm->major, &dimm->minor) != 2)
+ goto err_read;
+
+ sprintf(path, "%s/commands", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) < 0)
+ goto err_read;
+ dimm->cmd_mask = parse_commands(buf, 1);
+
+ dimm->dimm_buf = calloc(1, strlen(dimm_base) + 50);
+ if (!dimm->dimm_buf)
+ goto err_read;
+ dimm->buf_len = strlen(dimm_base) + 50;
+
+ dimm->dimm_path = strdup(dimm_base);
+ if (!dimm->dimm_path)
+ goto err_read;
+
+ sprintf(path, "%s/modalias", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) < 0)
+ goto err_read;
+ dimm->module = to_module(ctx, buf);
+
+ dimm->handle = -1;
+ dimm->phys_id = -1;
+ dimm->serial = -1;
+ dimm->vendor_id = -1;
+ dimm->device_id = -1;
+ dimm->revision_id = -1;
+ dimm->health_eventfd = -1;
+ dimm->dirty_shutdown = -ENOENT;
+ dimm->subsystem_vendor_id = -1;
+ dimm->subsystem_device_id = -1;
+ dimm->subsystem_revision_id = -1;
+ dimm->manufacturing_date = -1;
+ dimm->manufacturing_location = -1;
+ dimm->cmd_family = -1;
+ dimm->nfit_dsm_mask = ULONG_MAX;
+ for (i = 0; i < formats; i++)
+ dimm->format[i] = -1;
+
+ sprintf(path, "%s/flags", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) < 0) {
+ dimm->locked = -1;
+ dimm->aliased = -1;
+ } else
+ parse_dimm_flags(dimm, buf);
+
+ /* Check if the given dimm supports nfit */
+ if (ndctl_bus_has_nfit(bus)) {
+ dimm->formats = formats;
+ rc = add_nfit_dimm(dimm, dimm_base);
+ }
+
+ if (rc == -ENODEV) {
+ /* Unprobed dimm with no family */
+ rc = 0;
+ goto out;
+ }
+
+ /* Assign dimm-ops based on command family */
+ if (dimm->cmd_family == NVDIMM_FAMILY_INTEL)
+ dimm->ops = intel_dimm_ops;
+ if (dimm->cmd_family == NVDIMM_FAMILY_HPE1)
+ dimm->ops = hpe1_dimm_ops;
+ if (dimm->cmd_family == NVDIMM_FAMILY_MSFT)
+ dimm->ops = msft_dimm_ops;
+ if (dimm->cmd_family == NVDIMM_FAMILY_HYPERV)
+ dimm->ops = hyperv_dimm_ops;
out:
+ if (rc) {
+ err(ctx, "Unable to probe dimm:%d. Err:%d\n", id, rc);
+ goto err_read;
+ }
+
list_add(&bus->dimms, &dimm->list);
free(path);
--
2.24.1
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
^ permalink raw reply related
* Re: [PATCH v2] hw/i386: disable smbus migration for xenfv
From: Paolo Bonzini @ 2020-02-20 10:50 UTC (permalink / raw)
To: Olaf Hering
Cc: Stefano Stabellini, Eduardo Habkost, Michael S. Tsirkin,
Paul Durrant, open list:All patches CC here, Anthony Perard,
Richard Henderson
In-Reply-To: <20200219151459.5a6b9690.olaf@aepfle.de>
On 19/02/20 15:14, Olaf Hering wrote:
>> Is any of the things done by pc_i440fx_5_0_machine_options and
>> pc_i440fx_machine_options a desired, or even breaking, change for the
>> current result of pc_xen_hvm_init?
> I tried to follow a few of the initialized members:
>
> default_nic_model, perhaps the involved code paths are not called, so the NULL pointer does not matter.
>
> pvh_enabled, does this mean the PVH domU type? If yes, this would be lost when xenfv is locked at v3.1.
No, pvh_enabled means recognizing uncompressed kernels and setting up
the pvh.bin ROM to boot them. On Xen, this is done by the domain loader.
Paolo
^ permalink raw reply
* [ndctl PATCH 2/8] libndctl: Introduce a new dimm-ops dimm_init() & dimm_uninit()
From: Vaibhav Jain @ 2020-02-20 10:49 UTC (permalink / raw)
To: linux-nvdimm; +Cc: Vaibhav Jain, Aneesh Kumar K . V, Alastair D'Silva
In-Reply-To: <20200220104928.198625-1-vaibhav@linux.ibm.com>
There are scenarios when a dimm-provider need to allocate some
per-dimm data that can be quickly retrieved. This data can be used to
cache data that spans multiple 'struct ndctl_cmd' submissions.
Unfortunately currently in libnvdimm there is no easiy way to implement
this. Even if this data is some how store in an overloaded field of
'struct ndctl_dimm', managing its lifetime is a challenge.
To solve this problem this patch proposes a new member 'struct
ndctl_dimm.dimm_user_data' to store per-dimm data thats specific to a
dimm-provider. Also two new dimm-ops namely dimm_init() &
dimm_uninit() are introduced that can be used to manage the lifetime
of this per-dimm data.
Semantics
=========
int (*dimm_init)(struct ndctl_dimm *):
This callback will be called just after dimm-probe inside add_dimm()
is completed. Dimm-providers should use this callback to allocate
per-dimm data and assign it to 'struct ndctl_dimm.dimm_user_data'
member. In case this function returns an error, dimm initialization is
halted and errors out.
void (*dimm_uninit)(struct ndctl_dimm *):
This callback will be called during free_dimm() and is only called if
previous call to 'dimm_ops->dimm_init()' had reported no
error. Dimm-providers should use this callback to unallocate and
cleanup 'dimm_user_data'.
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
---
ndctl/lib/libndctl.c | 13 ++++++++++++-
ndctl/lib/private.h | 5 +++++
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 38ddfea6dbc0..a5f5fdac9f48 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -596,6 +596,10 @@ static void free_dimm(struct ndctl_dimm *dimm)
{
if (!dimm)
return;
+ /* If needed call the dimm uninitialization function */
+ if (dimm->ops && dimm->ops->dimm_uninit)
+ dimm->ops->dimm_uninit(dimm);
+
free(dimm->unique_id);
free(dimm->dimm_buf);
free(dimm->dimm_path);
@@ -1596,8 +1600,15 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
dimm->ops = msft_dimm_ops;
if (dimm->cmd_family == NVDIMM_FAMILY_HYPERV)
dimm->ops = hyperv_dimm_ops;
- out:
+
+ /* Call the dimm initialization function if needed */
+ if (!rc && dimm->ops && dimm->ops->dimm_init)
+ rc = dimm->ops->dimm_init(dimm);
+
+out:
if (rc) {
+ /* Ensure dimm_uninit() is not called during free_dimm() */
+ dimm->ops = NULL;
err(ctx, "Unable to probe dimm:%d. Err:%d\n", id, rc);
goto err_read;
}
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 1f6a01c55377..fb7fa47f1f37 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -98,6 +98,7 @@ struct ndctl_dimm {
} flags;
int locked;
int aliased;
+ void *dimm_user_data;
struct list_node list;
int formats;
int format[0];
@@ -340,6 +341,10 @@ struct ndctl_dimm_ops {
struct ndctl_cmd *(*new_ack_shutdown_count)(struct ndctl_dimm *);
int (*fw_update_supported)(struct ndctl_dimm *);
int (*xlat_firmware_status)(struct ndctl_cmd *);
+ /* Called just after dimm is initialized and probed */
+ int (*dimm_init)(struct ndctl_dimm *);
+ /* Called just before struct ndctl_dimm is de-allocated */
+ void (*dimm_uninit)(struct ndctl_dimm *);
};
struct ndctl_dimm_ops * const intel_dimm_ops;
--
2.24.1
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
^ permalink raw reply related
* [ndctl PATCH 5/8] libndctl,papr_scm: Add definitions for PAPR_SCM DSM commands
From: Vaibhav Jain @ 2020-02-20 10:49 UTC (permalink / raw)
To: linux-nvdimm; +Cc: Vaibhav Jain, Aneesh Kumar K . V, Alastair D'Silva
In-Reply-To: <20200220104928.198625-1-vaibhav@linux.ibm.com>
Pull the kernel definition of PAPR_SCM DSM command which is located in
the kernel tree at Ref[1]. Also add an implementation of
'papr_scm_dimm_ops' in a new file named 'papr_scm.c'. For now only an
implementation of 'dimm_ops.cmd_is_supported' is provided.
References:
[1]: arch/powerpc/include/uapi/asm/papr_scm_dsm.h
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
---
ndctl/lib/Makefile.am | 1 +
ndctl/lib/papr_scm.c | 34 ++++++++++
ndctl/lib/papr_scm_dsm.h | 143 +++++++++++++++++++++++++++++++++++++++
3 files changed, 178 insertions(+)
create mode 100644 ndctl/lib/papr_scm.c
create mode 100644 ndctl/lib/papr_scm_dsm.h
diff --git a/ndctl/lib/Makefile.am b/ndctl/lib/Makefile.am
index e4eb0060bca4..3943541e435d 100644
--- a/ndctl/lib/Makefile.am
+++ b/ndctl/lib/Makefile.am
@@ -21,6 +21,7 @@ libndctl_la_SOURCES =\
hpe1.c \
msft.c \
hyperv.c \
+ papr_scm.c \
ars.c \
firmware.c \
libndctl.c
diff --git a/ndctl/lib/papr_scm.c b/ndctl/lib/papr_scm.c
new file mode 100644
index 000000000000..878698a5a8b4
--- /dev/null
+++ b/ndctl/lib/papr_scm.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ * more details.
+ */
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <endian.h>
+#include <util/log.h>
+#include <ndctl.h>
+#include <ndctl/libndctl.h>
+#include <lib/private.h>
+#include <papr_scm_dsm.h>
+
+static bool papr_cmd_is_supported(struct ndctl_dimm *dimm, int cmd)
+{
+ /* Handle this separately to support monitor mode */
+ if (cmd == ND_CMD_SMART)
+ return true;
+
+ return !!(dimm->cmd_mask & (1ULL << cmd));
+}
+
+struct ndctl_dimm_ops * const papr_scm_dimm_ops = &(struct ndctl_dimm_ops) {
+ .cmd_is_supported = papr_cmd_is_supported,
+};
diff --git a/ndctl/lib/papr_scm_dsm.h b/ndctl/lib/papr_scm_dsm.h
new file mode 100644
index 000000000000..aacced453579
--- /dev/null
+++ b/ndctl/lib/papr_scm_dsm.h
@@ -0,0 +1,143 @@
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
+/*
+ * PAPR SCM Device specific methods for libndctl and ndctl
+ *
+ * (C) Copyright IBM 2020
+ *
+ * Author: Vaibhav Jain <vaibhav at linux.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _UAPI_ASM_POWERPC_PAPR_SCM_DSM_H_
+#define _UAPI_ASM_POWERPC_PAPR_SCM_DSM_H_
+
+#include <linux/types.h>
+
+#ifdef __KERNEL__
+#include <linux/ndctl.h>
+#else
+#include <ndctl.h>
+#endif
+
+/*
+ * Sub commands for ND_CMD_CALL. To prevent overlap from ND_CMD_*, values for
+ * these enums start at 0x10000. These values are then returned from
+ * cmd_to_func() making it easy to implement the switch-case block in
+ * papr_scm_ndctl()
+ */
+enum dsm_papr_scm {
+ DSM_PAPR_SCM_MIN = 0x10000,
+ DSM_PAPR_SCM_HEALTH,
+ DSM_PAPR_SCM_STATS,
+ DSM_PAPR_SCM_MAX,
+};
+
+enum dsm_papr_scm_dimm_health {
+ DSM_PAPR_SCM_DIMM_HEALTHY,
+ DSM_PAPR_SCM_DIMM_UNHEALTHY,
+ DSM_PAPR_SCM_DIMM_CRITICAL,
+ DSM_PAPR_SCM_DIMM_FATAL,
+};
+
+/* Papr-scm-header + payload expected with ND_CMD_CALL ioctl from libnvdimm */
+struct nd_papr_scm_cmd_pkg {
+ struct nd_cmd_pkg hdr; /* Package header containing sub-cmd */
+ int32_t cmd_status; /* Out: Sub-cmd status returned back */
+ uint16_t payload_offset; /* In: offset from start of struct */
+ uint16_t payload_version; /* In/Out: version of the payload */
+ uint8_t payload[]; /* In/Out: Sub-cmd data buffer */
+};
+
+/* Helpers to evaluate the size of PAPR_SCM envelope */
+/* Calculate the papr_scm-header size */
+#define ND_PAPR_SCM_ENVELOPE_CONTENT_HDR_SIZE \
+ (sizeof(struct nd_papr_scm_cmd_pkg) - sizeof(struct nd_cmd_pkg))
+/*
+ * Given a type calculate the envelope size
+ * (nd-header + papr_scm-header + payload)
+ */
+#define ND_PAPR_SCM_ENVELOPE_SIZE(_type_) \
+ (sizeof(_type_) + sizeof(struct nd_papr_scm_cmd_pkg))
+
+/* Given a type envelope-content size (papr_scm-header + payload) */
+#define ND_PAPR_SCM_ENVELOPE_CONTENT_SIZE(_type_) \
+ (sizeof(_type_) + ND_PAPR_SCM_ENVELOPE_CONTENT_HDR_SIZE)
+
+/*
+ * Struct exchanged between kernel & ndctl in for PAPR_DSM_PAPR_SMART_HEALTH
+ * Various bitflags indicate the health status of the dimm.
+ */
+struct nd_papr_scm_dimm_health_stat_v1 {
+ /* Dimm not armed. So contents wont persist */
+ bool dimm_unarmed;
+ /* Previous shutdown did not persist contents */
+ bool dimm_bad_shutdown;
+ /* Contents from previous shutdown werent restored */
+ bool dimm_bad_restore;
+ /* Contents of the dimm have been scrubbed */
+ bool dimm_scrubbed;
+ /* Contents of the dimm cant be modified until CEC reboot */
+ bool dimm_locked;
+ /* Contents of dimm are encrypted */
+ bool dimm_encrypted;
+
+ enum dsm_papr_scm_dimm_health dimm_health;
+};
+
+/*
+ * Typedef the current struct for dimm_health so that any application
+ * or kernel recompiled after introducing a new version autometically
+ * supports the new version.
+ */
+#define nd_papr_scm_dimm_health_stat nd_papr_scm_dimm_health_stat_v1
+
+/* Current version number for the dimm health struct */
+#define ND_PAPR_SCM_DIMM_HEALTH_VERSION 1
+
+/* Struct holding a single performance metric */
+struct nd_papr_scm_perf_stat {
+ u64 statistic_id;
+ u64 statistic_value;
+};
+
+/* Struct exchanged between kernel and ndctl reporting drc perf stats */
+struct nd_papr_scm_perf_stats_v1 {
+ /* Number of stats following */
+ u32 num_statistics;
+
+ /* zero or more performance matrics */
+ struct nd_papr_scm_perf_stat scm_statistics[];
+};
+
+/*
+ * Typedef the current struct for dimm_stats so that any application
+ * or kernel recompiled after introducing a new version autometically
+ * supports the new version.
+ */
+#define nd_papr_scm_perf_stats nd_papr_scm_perf_stats_v1
+#define ND_PAPR_SCM_DIMM_PERF_STATS_VERSION 1
+
+/* Convert a libnvdimm nd_cmd_pkg to papr_scm specific pkg */
+static struct nd_papr_scm_cmd_pkg *nd_to_papr_cmd_pkg(struct nd_cmd_pkg *cmd)
+{
+ return (struct nd_papr_scm_cmd_pkg *) cmd;
+}
+
+/* Return the payload pointer for a given pcmd */
+static void *papr_scm_pcmd_to_payload(struct nd_papr_scm_cmd_pkg *pcmd)
+{
+ if (pcmd->hdr.nd_size_in == 0 && pcmd->hdr.nd_size_out == 0)
+ return NULL;
+ else
+ return (void *)((u8 *) pcmd + pcmd->payload_offset);
+}
+#endif /* _UAPI_ASM_POWERPC_PAPR_SCM_DSM_H_ */
--
2.24.1
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
^ permalink raw reply related
* Re: [Intel-gfx] [PATCH v5] drm/i915/gt: make a gt sysfs group and move power management files
From: Jani Nikula @ 2020-02-20 10:52 UTC (permalink / raw)
To: Andi Shyti, Intel GFX
In-Reply-To: <20200219193020.17673-1-andi.shyti@intel.com>
On Wed, 19 Feb 2020, Andi Shyti <andi.shyti@intel.com> wrote:
> The GT has its own properties and in sysfs they should be grouped
> in the 'gt/' directory.
>
> Create the 'gt/' directory in sysfs and move the power management
> related files.
>
> The new interfaces are:
>
> gt/gt_act_freq_mhz
> gt/gt_boost_freq_mhz
> gt/gt_cur_freq_mhz
> gt/gt_info
> gt/gt_max_freq_mhz
> gt/gt_min_freq_mhz
> gt/gt_RP0_freq_mhz
> gt/gt_RP1_freq_mhz
> gt/gt_RPn_freq_mhz
> gt/rc6_enable
> gt/rc6_residency_ms
>
> The once in the root directory will be marked as deprecated, if
> accessed a warning message is printed.
>
> Signed-off-by: Andi Shyti <andi.shyti@intel.com>
> ---
> v4 -> v5:
> - removed spurious ghost 'vvv' file that was never meant to be
> there... sorry for spamming.
> v3 -> v4:
> - fixed Tvrtko's comments:
> - some renaming
> - some clumsy unbalanced kobject_put/get
> - the warning print is more descriptive and printed with
> limited rate
> - TODO: drm_print doesn't have a drm_warn_unlimited, to
> be added
> v2 -> v3:
> - fix some cleanups that I forgot in the previous patch
> - fix reference pointers to the gt structure
> - and many other small changes here and there.
> v1 -> v2:
> - keep the existing files as they are
> - use "intel_gt_*" as prefix instead of "sysfs_*"
>
> drivers/gpu/drm/i915/Makefile | 4 +-
> drivers/gpu/drm/i915/gt/intel_gt.c | 3 +
> drivers/gpu/drm/i915/gt/intel_gt_types.h | 1 +
> drivers/gpu/drm/i915/gt/sysfs_gt.c | 79 +++++
> drivers/gpu/drm/i915/gt/sysfs_gt.h | 22 ++
> drivers/gpu/drm/i915/gt/sysfs_gt_pm.c | 432 +++++++++++++++++++++++
> drivers/gpu/drm/i915/gt/sysfs_gt_pm.h | 17 +
> drivers/gpu/drm/i915/i915_sysfs.c | 375 +-------------------
> drivers/gpu/drm/i915/i915_sysfs.h | 3 +
> 9 files changed, 561 insertions(+), 375 deletions(-)
> create mode 100644 drivers/gpu/drm/i915/gt/sysfs_gt.c
> create mode 100644 drivers/gpu/drm/i915/gt/sysfs_gt.h
> create mode 100644 drivers/gpu/drm/i915/gt/sysfs_gt_pm.c
> create mode 100644 drivers/gpu/drm/i915/gt/sysfs_gt_pm.h
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index b314d44ded5e..ff9e17c97dc2 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -107,7 +107,9 @@ gt-y += \
> gt/intel_rps.o \
> gt/intel_sseu.o \
> gt/intel_timeline.o \
> - gt/intel_workarounds.o
> + gt/intel_workarounds.o \
> + gt/sysfs_gt.o \
> + gt/sysfs_gt_pm.o
> # autogenerated null render state
> gt-y += \
> gt/gen6_renderstate.o \
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
> index f1f1b306e0af..e794d05d69a1 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.c
> @@ -15,6 +15,7 @@
> #include "intel_rps.h"
> #include "intel_uncore.h"
> #include "intel_pm.h"
> +#include "sysfs_gt.h"
>
> void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915)
> {
> @@ -321,6 +322,7 @@ void intel_gt_driver_register(struct intel_gt *gt)
> intel_rps_driver_register(>->rps);
>
> debugfs_gt_register(gt);
> + intel_gt_sysfs_register(gt);
> }
>
> static int intel_gt_init_scratch(struct intel_gt *gt, unsigned int size)
> @@ -641,6 +643,7 @@ void intel_gt_driver_remove(struct intel_gt *gt)
>
> void intel_gt_driver_unregister(struct intel_gt *gt)
> {
> + intel_gt_sysfs_unregister(gt);
> intel_rps_driver_unregister(>->rps);
> }
>
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> index 96890dd12b5f..7f0b4f8d9e28 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
> @@ -32,6 +32,7 @@ struct intel_gt {
> struct drm_i915_private *i915;
> struct intel_uncore *uncore;
> struct i915_ggtt *ggtt;
> + struct kobject sysfs_root;
>
> struct intel_uc uc;
>
> diff --git a/drivers/gpu/drm/i915/gt/sysfs_gt.c b/drivers/gpu/drm/i915/gt/sysfs_gt.c
> new file mode 100644
> index 000000000000..9335a92d5248
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/sysfs_gt.c
> @@ -0,0 +1,79 @@
> +// SPDX-License-Identifier: MIT
> +
Superfluous newline.
> +/*
> + * Copyright © 2019 Intel Corporation
> + */
It's 2020 now. ;)
> +
> +#include <linux/sysfs.h>
> +#include <drm/drm_device.h>
> +#include <linux/kobject.h>
> +#include <linux/printk.h>
> +
> +#include "../i915_drv.h"
No need for "../", it's in include path.
> +#include "intel_gt.h"
> +#include "intel_gt_types.h"
> +#include "intel_rc6.h"
> +
> +#include "sysfs_gt.h"
> +#include "sysfs_gt_pm.h"
> +
> +static inline struct kobject *gt_get_parent_obj(struct intel_gt *gt)
In .c files just drop the inline keyword and let the compiler do what's
best.
> +{
> + return >->i915->drm.primary->kdev->kobj;
> +}
> +
> +static ssize_t gt_info_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buff)
> +{
> + return snprintf(buff, PAGE_SIZE, "0\n");
> +}
> +
> +static DEVICE_ATTR_RO(gt_info);
> +
> +static struct kobj_type sysfs_gt_ktype = {
> + .sysfs_ops = &kobj_sysfs_ops,
> +};
> +
> +void intel_gt_sysfs_register(struct intel_gt *gt)
> +{
> + struct kobject *parent = kobject_get(gt_get_parent_obj(gt));
> + int ret;
> +
> + ret = kobject_init_and_add(>->sysfs_root,
> + &sysfs_gt_ktype,
> + parent, "gt");
> + if (ret) {
> + drm_err(>->i915->drm, "failed to initialize sysfs file\n");
> + kobject_put(>->sysfs_root);
> + goto parent_files;
> + }
> +
> + ret = sysfs_create_file(>->sysfs_root, &dev_attr_gt_info.attr);
> + if (ret)
> + drm_err(>->i915->drm, "failed to create sysfs gt info files\n");
> +
> + intel_gt_sysfs_pm_init(gt, >->sysfs_root);
> +
> +parent_files:
> + /*
> + * we need to make things right with the
> + * ABI compatibility. The files were originally
> + * generated under the parent directory.
> + */
> + intel_gt_sysfs_pm_init(gt, parent);
> +}
> +
> +void intel_gt_sysfs_unregister(struct intel_gt *gt)
> +{
> + struct kobject *parent = gt_get_parent_obj(gt);
> +
> + /*
> + * the name gt tells us wether sysfs_root
> + * object was initialized properly
> + */
> + if (!strcmp(gt->sysfs_root.name, "gt"))
> + kobject_put(>->sysfs_root);
> +
> + kobject_put(parent);
> +}
> diff --git a/drivers/gpu/drm/i915/gt/sysfs_gt.h b/drivers/gpu/drm/i915/gt/sysfs_gt.h
> new file mode 100644
> index 000000000000..2e479aa902e5
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/sysfs_gt.h
> @@ -0,0 +1,22 @@
> +/* SPDX-License-Identifier: MIT */
> +
Superfluous newline.
> +/*
> + * Copyright © 2019 Intel Corporation
> + */
2020.
> +
> +#ifndef SYSFS_GT_H
> +#define SYSFS_GT_H
Please add some underscores, e.g. __SYSFS_GT_H__.
> +
> +#include "intel_gt_types.h"
> +
> +struct intel_gt;
> +
> +static inline struct intel_gt *kobj_to_gt(struct kobject *kobj)
> +{
> + return container_of(kobj, struct intel_gt, sysfs_root);
> +}
> +
> +void intel_gt_sysfs_register(struct intel_gt *gt);
> +void intel_gt_sysfs_unregister(struct intel_gt *gt);
> +
> +#endif /* SYSFS_GT_H */
> diff --git a/drivers/gpu/drm/i915/gt/sysfs_gt_pm.c b/drivers/gpu/drm/i915/gt/sysfs_gt_pm.c
> new file mode 100644
> index 000000000000..c548eb851a70
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/sysfs_gt_pm.c
> @@ -0,0 +1,432 @@
> +// SPDX-License-Identifier: MIT
> +
> +/*
> + * Copyright © 2019 Intel Corporation
> + */
You know the drill. ;)
> +
> +#include <drm/drm_device.h>
> +#include <linux/sysfs.h>
> +#include <linux/printk.h>
> +
> +#include "../i915_drv.h"
> +#include "../i915_sysfs.h"
"../" is unnecessary.
> +#include "intel_gt.h"
> +#include "intel_rc6.h"
> +#include "intel_rps.h"
> +#include "sysfs_gt.h"
> +#include "sysfs_gt_pm.h"
> +
> +struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev)
> +{
> + struct kobject *kobj = &dev->kobj;
> + /*
> + * We are interested at knowing from where the interface
> + * has been called, whether it's called from gt/ or from
> + * the parent directory.
> + * From the interface position it depends also the value of
> + * the private data.
> + * If the interface is called from gt/ then private data is
> + * of the "struct intel_gt *" type, otherwise it's * a
> + * "struct drm_i915_private *" type.
> + */
> + if (strcmp(dev->kobj.name, "gt")) {
> + struct drm_i915_private *i915 = kdev_minor_to_i915(dev);
> +
> + pr_warn_ratelimited(DEPRECATED
> + "(%s, %d) trying to access deprecated interface, "
> + "use the corresponding interface in gt/\n",
> + current->comm, task_pid_nr(current));
> + return &i915->gt;
> + }
> +
> + return kobj_to_gt(kobj);
> +}
> +
> +#ifdef CONFIG_PM
> +static u32 get_residency(struct intel_gt *gt, i915_reg_t reg)
> +{
> + intel_wakeref_t wakeref;
> + u64 res = 0;
> +
> + with_intel_runtime_pm(gt->uncore->rpm, wakeref)
> + res = intel_rc6_residency_us(>->rc6, reg);
> +
> + return DIV_ROUND_CLOSEST_ULL(res, 1000);
> +}
> +
> +static ssize_t rc6_enable_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + u8 mask = 0;
> +
> + if (HAS_RC6(gt->i915))
> + mask |= BIT(0);
> + if (HAS_RC6p(gt->i915))
> + mask |= BIT(1);
> + if (HAS_RC6pp(gt->i915))
> + mask |= BIT(2);
> +
> + return snprintf(buff, PAGE_SIZE, "%x\n", mask);
> +}
> +
> +static ssize_t rc6_residency_ms_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + u32 rc6_residency = get_residency(gt, GEN6_GT_GFX_RC6);
> +
> + return snprintf(buff, PAGE_SIZE, "%u\n", rc6_residency);
> +}
> +
> +static ssize_t rc6p_residency_ms_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + u32 rc6p_residency = get_residency(gt, GEN6_GT_GFX_RC6p);
> +
> + return snprintf(buff, PAGE_SIZE, "%u\n", rc6p_residency);
> +}
> +
> +static ssize_t rc6pp_residency_ms_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + u32 rc6pp_residency = get_residency(gt, GEN6_GT_GFX_RC6pp);
> +
> + return snprintf(buff, PAGE_SIZE, "%u\n", rc6pp_residency);
> +}
> +
> +static ssize_t media_rc6_residency_ms_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + u32 rc6_residency = get_residency(gt, VLV_GT_MEDIA_RC6);
> +
> + return snprintf(buff, PAGE_SIZE, "%u\n", rc6_residency);
> +}
> +
> +static DEVICE_ATTR_RO(rc6_enable);
> +static DEVICE_ATTR_RO(rc6_residency_ms);
> +static DEVICE_ATTR_RO(rc6p_residency_ms);
> +static DEVICE_ATTR_RO(rc6pp_residency_ms);
> +static DEVICE_ATTR_RO(media_rc6_residency_ms);
> +
> +static const struct attribute *rc6_attrs[] = {
> + &dev_attr_rc6_enable.attr,
> + &dev_attr_rc6_residency_ms.attr,
> + NULL
> +};
> +
> +static const struct attribute *rc6p_attrs[] = {
> + &dev_attr_rc6p_residency_ms.attr,
> + &dev_attr_rc6pp_residency_ms.attr,
> + NULL
> +};
> +
> +static const struct attribute *media_rc6_attrs[] = {
> + &dev_attr_media_rc6_residency_ms.attr,
> + NULL
> +};
> +
> +static void intel_sysfs_rc6_init(struct intel_gt *gt, struct kobject *kobj)
> +{
> + int ret = 0;
> +
> + if (HAS_RC6(gt->i915)) {
> + ret = sysfs_create_files(kobj, rc6_attrs);
> + if (ret)
> + drm_err(>->i915->drm,
> + "failed to create RC6 sysfs files\n");
> + }
> +
> + if (HAS_RC6p(gt->i915)) {
> + ret = sysfs_create_files(kobj, rc6p_attrs);
> + if (ret)
> + drm_err(>->i915->drm,
> + "failed to create RC6p sysfs files\n");
> + }
> +
> + if (IS_VALLEYVIEW(gt->i915) || IS_CHERRYVIEW(gt->i915)) {
> + ret = sysfs_create_files(kobj, media_rc6_attrs);
> + if (ret)
> + drm_err(>->i915->drm,
> + "failed to create media RC6 sysfs files\n");
> + }
> +}
> +#else
> +static void intel_sysfs_rc6_init(struct intel_gt *gt, struct kobject *kobj)
> +{
> + return 0;
> +}
> +#endif /* CONFIG_PM */
> +
> +static ssize_t gt_act_freq_mhz_show(struct device *dev,
> + struct device_attribute *attr, char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> +
> + return snprintf(buff, PAGE_SIZE, "%d\n",
> + intel_rps_read_actual_frequency(>->rps));
> +}
> +
> +static ssize_t gt_cur_freq_mhz_show(struct device *dev,
> + struct device_attribute *attr, char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + struct intel_rps *rps = >->rps;
> +
> + return snprintf(buff, PAGE_SIZE, "%d\n",
> + intel_gpu_freq(rps, rps->cur_freq));
> +}
> +
> +static ssize_t gt_boost_freq_mhz_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + struct intel_rps *rps = >->rps;
> +
> + return snprintf(buff, PAGE_SIZE, "%d\n",
> + intel_gpu_freq(rps, rps->boost_freq));
> +}
> +
> +static ssize_t gt_boost_freq_mhz_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buff, size_t count)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + struct intel_rps *rps = >->rps;
> + bool boost = false;
> + ssize_t ret;
> + u32 val;
> +
> + ret = kstrtou32(buff, 0, &val);
> + if (ret)
> + return ret;
> +
> + /* Validate against (static) hardware limits */
> + val = intel_freq_opcode(rps, val);
> + if (val < rps->min_freq || val > rps->max_freq)
> + return -EINVAL;
> +
> + mutex_lock(&rps->lock);
> + if (val != rps->boost_freq) {
> + rps->boost_freq = val;
> + boost = atomic_read(&rps->num_waiters);
> + }
> + mutex_unlock(&rps->lock);
> + if (boost)
> + schedule_work(&rps->work);
> +
> + return count;
> +}
> +
> +static ssize_t vlv_rpe_freq_mhz_show(struct device *dev,
> + struct device_attribute *attr, char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + struct intel_rps *rps = >->rps;
> +
> + return snprintf(buff, PAGE_SIZE, "%d\n",
> + intel_gpu_freq(rps, rps->efficient_freq));
> +}
> +
> +static ssize_t gt_max_freq_mhz_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + struct intel_rps *rps = >->rps;
> +
> + return snprintf(buff, PAGE_SIZE, "%d\n",
> + intel_gpu_freq(rps, rps->max_freq_softlimit));
> +}
> +
> +static ssize_t gt_max_freq_mhz_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buff, size_t count)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + struct intel_rps *rps = >->rps;
> + ssize_t ret;
> + u32 val;
> +
> + ret = kstrtou32(buff, 0, &val);
> + if (ret)
> + return ret;
> +
> + mutex_lock(&rps->lock);
> +
> + val = intel_freq_opcode(rps, val);
> + if (val < rps->min_freq ||
> + val > rps->max_freq ||
> + val < rps->min_freq_softlimit) {
> + ret = -EINVAL;
> + goto unlock;
> + }
> +
> + if (val > rps->rp0_freq)
> + DRM_DEBUG("User requested overclocking to %d\n",
> + intel_gpu_freq(rps, val));
> +
> + rps->max_freq_softlimit = val;
> +
> + val = clamp_t(int, rps->cur_freq,
> + rps->min_freq_softlimit,
> + rps->max_freq_softlimit);
> +
> + /*
> + * We still need *_set_rps to process the new max_delay and
> + * update the interrupt limits and PMINTRMSK even though
> + * frequency request may be unchanged.
> + */
> + intel_rps_set(rps, val);
> +
> +unlock:
> + mutex_unlock(&rps->lock);
> +
> + return ret ?: count;
> +}
> +
> +static ssize_t gt_min_freq_mhz_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + struct intel_rps *rps = >->rps;
> +
> + return snprintf(buff, PAGE_SIZE, "%d\n",
> + intel_gpu_freq(rps, rps->min_freq_softlimit));
> +}
> +
> +static ssize_t gt_min_freq_mhz_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buff, size_t count)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + struct intel_rps *rps = >->rps;
> + ssize_t ret;
> + u32 val;
> +
> + ret = kstrtou32(buff, 0, &val);
> + if (ret)
> + return ret;
> +
> + mutex_lock(&rps->lock);
> +
> + val = intel_freq_opcode(rps, val);
> + if (val < rps->min_freq ||
> + val > rps->max_freq ||
> + val > rps->max_freq_softlimit) {
> + ret = -EINVAL;
> + goto unlock;
> + }
> +
> + rps->min_freq_softlimit = val;
> +
> + val = clamp_t(int, rps->cur_freq,
> + rps->min_freq_softlimit,
> + rps->max_freq_softlimit);
> +
> + /*
> + * We still need *_set_rps to process the new min_delay and
> + * update the interrupt limits and PMINTRMSK even though
> + * frequency request may be unchanged.
> + */
> + intel_rps_set(rps, val);
> +
> +unlock:
> + mutex_unlock(&rps->lock);
> +
> + return ret ?: count;
> +}
> +
> +static DEVICE_ATTR_RO(gt_act_freq_mhz);
> +static DEVICE_ATTR_RO(gt_cur_freq_mhz);
> +static DEVICE_ATTR_RW(gt_boost_freq_mhz);
> +static DEVICE_ATTR_RW(gt_max_freq_mhz);
> +static DEVICE_ATTR_RW(gt_min_freq_mhz);
> +
> +static DEVICE_ATTR_RO(vlv_rpe_freq_mhz);
> +
> +static ssize_t gt_rp_mhz_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buff);
> +
> +static DEVICE_ATTR(gt_RP0_freq_mhz, 0444, gt_rp_mhz_show, NULL);
> +static DEVICE_ATTR(gt_RP1_freq_mhz, 0444, gt_rp_mhz_show, NULL);
> +static DEVICE_ATTR(gt_RPn_freq_mhz, 0444, gt_rp_mhz_show, NULL);
> +
> +/* For now we have a static number of RP states */
> +static ssize_t gt_rp_mhz_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buff)
> +{
> + struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev);
> + struct intel_rps *rps = >->rps;
> + u32 val;
> +
> + if (attr == &dev_attr_gt_RP0_freq_mhz)
> + val = intel_gpu_freq(rps, rps->rp0_freq);
> + else if (attr == &dev_attr_gt_RP1_freq_mhz)
> + val = intel_gpu_freq(rps, rps->rp1_freq);
> + else if (attr == &dev_attr_gt_RPn_freq_mhz)
> + val = intel_gpu_freq(rps, rps->min_freq);
> + else
> + BUG();
> +
> + return snprintf(buff, PAGE_SIZE, "%d\n", val);
> +}
> +
> +static const struct attribute * const gen6_attrs[] = {
> + &dev_attr_gt_act_freq_mhz.attr,
> + &dev_attr_gt_cur_freq_mhz.attr,
> + &dev_attr_gt_boost_freq_mhz.attr,
> + &dev_attr_gt_max_freq_mhz.attr,
> + &dev_attr_gt_min_freq_mhz.attr,
> + &dev_attr_gt_RP0_freq_mhz.attr,
> + &dev_attr_gt_RP1_freq_mhz.attr,
> + &dev_attr_gt_RPn_freq_mhz.attr,
> + NULL,
> +};
> +
> +static const struct attribute * const vlv_attrs[] = {
> + &dev_attr_gt_act_freq_mhz.attr,
> + &dev_attr_gt_cur_freq_mhz.attr,
> + &dev_attr_gt_boost_freq_mhz.attr,
> + &dev_attr_gt_max_freq_mhz.attr,
> + &dev_attr_gt_min_freq_mhz.attr,
> + &dev_attr_gt_RP0_freq_mhz.attr,
> + &dev_attr_gt_RP1_freq_mhz.attr,
> + &dev_attr_gt_RPn_freq_mhz.attr,
> + &dev_attr_vlv_rpe_freq_mhz.attr,
> + NULL,
> +};
> +
> +static int intel_sysfs_rps_init(struct intel_gt *gt, struct kobject *kobj)
> +{
> + if (IS_VALLEYVIEW(gt->i915) || IS_CHERRYVIEW(gt->i915))
> + return sysfs_create_files(kobj, vlv_attrs);
> +
> + if (INTEL_GEN(gt->i915) >= 6)
> + return sysfs_create_files(kobj, gen6_attrs);
> +
> + return 0;
> +}
> +
> +void intel_gt_sysfs_pm_init(struct intel_gt *gt, struct kobject *kobj)
> +{
> + int ret;
> +
> + intel_sysfs_rc6_init(gt, kobj);
> +
> + ret = intel_sysfs_rps_init(gt, kobj);
> + if (ret)
> + drm_err(>->i915->drm, "failed to create RPS sysfs files");
> +}
> diff --git a/drivers/gpu/drm/i915/gt/sysfs_gt_pm.h b/drivers/gpu/drm/i915/gt/sysfs_gt_pm.h
> new file mode 100644
> index 000000000000..758d0c3cb998
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/sysfs_gt_pm.h
> @@ -0,0 +1,17 @@
> +/* SPDX-License-Identifier: MIT */
> +
> +/*
> + * Copyright © 2019 Intel Corporation
> + */
> +
> +#ifndef SYSFS_RC6_H
> +#define SYSFS_RC6_H
All the things mentioned before; newline, year, underscores.
Additionally make the include protection match the file name.
> +
> +#include <linux/kobject.h>
> +
> +#include "intel_gt_types.h"
> +
> +void intel_gt_sysfs_pm_init(struct intel_gt *gt, struct kobject *kobj);
> +void intel_gt_sysfs_pm_remove(struct intel_gt *gt, struct kobject *kobj);
> +
> +#endif /* SYSFS_RC6_H */
> diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
> index c14d762bd652..1298977fc08b 100644
> --- a/drivers/gpu/drm/i915/i915_sysfs.c
> +++ b/drivers/gpu/drm/i915/i915_sysfs.c
> @@ -38,113 +38,12 @@
> #include "intel_pm.h"
> #include "intel_sideband.h"
>
> -static inline struct drm_i915_private *kdev_minor_to_i915(struct device *kdev)
> +struct drm_i915_private *kdev_minor_to_i915(struct device *kdev)
> {
> struct drm_minor *minor = dev_get_drvdata(kdev);
> return to_i915(minor->dev);
> }
>
> -#ifdef CONFIG_PM
> -static u32 calc_residency(struct drm_i915_private *dev_priv,
> - i915_reg_t reg)
> -{
> - intel_wakeref_t wakeref;
> - u64 res = 0;
> -
> - with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref)
> - res = intel_rc6_residency_us(&dev_priv->gt.rc6, reg);
> -
> - return DIV_ROUND_CLOSEST_ULL(res, 1000);
> -}
> -
> -static ssize_t
> -show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - unsigned int mask;
> -
> - mask = 0;
> - if (HAS_RC6(dev_priv))
> - mask |= BIT(0);
> - if (HAS_RC6p(dev_priv))
> - mask |= BIT(1);
> - if (HAS_RC6pp(dev_priv))
> - mask |= BIT(2);
> -
> - return snprintf(buf, PAGE_SIZE, "%x\n", mask);
> -}
> -
> -static ssize_t
> -show_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - u32 rc6_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6);
> - return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency);
> -}
> -
> -static ssize_t
> -show_rc6p_ms(struct device *kdev, struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - u32 rc6p_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6p);
> - return snprintf(buf, PAGE_SIZE, "%u\n", rc6p_residency);
> -}
> -
> -static ssize_t
> -show_rc6pp_ms(struct device *kdev, struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - u32 rc6pp_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6pp);
> - return snprintf(buf, PAGE_SIZE, "%u\n", rc6pp_residency);
> -}
> -
> -static ssize_t
> -show_media_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - u32 rc6_residency = calc_residency(dev_priv, VLV_GT_MEDIA_RC6);
> - return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency);
> -}
> -
> -static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL);
> -static DEVICE_ATTR(rc6_residency_ms, S_IRUGO, show_rc6_ms, NULL);
> -static DEVICE_ATTR(rc6p_residency_ms, S_IRUGO, show_rc6p_ms, NULL);
> -static DEVICE_ATTR(rc6pp_residency_ms, S_IRUGO, show_rc6pp_ms, NULL);
> -static DEVICE_ATTR(media_rc6_residency_ms, S_IRUGO, show_media_rc6_ms, NULL);
> -
> -static struct attribute *rc6_attrs[] = {
> - &dev_attr_rc6_enable.attr,
> - &dev_attr_rc6_residency_ms.attr,
> - NULL
> -};
> -
> -static const struct attribute_group rc6_attr_group = {
> - .name = power_group_name,
> - .attrs = rc6_attrs
> -};
> -
> -static struct attribute *rc6p_attrs[] = {
> - &dev_attr_rc6p_residency_ms.attr,
> - &dev_attr_rc6pp_residency_ms.attr,
> - NULL
> -};
> -
> -static const struct attribute_group rc6p_attr_group = {
> - .name = power_group_name,
> - .attrs = rc6p_attrs
> -};
> -
> -static struct attribute *media_rc6_attrs[] = {
> - &dev_attr_media_rc6_residency_ms.attr,
> - NULL
> -};
> -
> -static const struct attribute_group media_rc6_attr_group = {
> - .name = power_group_name,
> - .attrs = media_rc6_attrs
> -};
> -#endif
> -
> static int l3_access_valid(struct drm_i915_private *i915, loff_t offset)
> {
> if (!HAS_L3_DPF(i915))
> @@ -256,239 +155,6 @@ static const struct bin_attribute dpf_attrs_1 = {
> .private = (void *)1
> };
>
> -static ssize_t gt_act_freq_mhz_show(struct device *kdev,
> - struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
> - struct intel_rps *rps = &i915->gt.rps;
> -
> - return snprintf(buf, PAGE_SIZE, "%d\n",
> - intel_rps_read_actual_frequency(rps));
> -}
> -
> -static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
> - struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
> - struct intel_rps *rps = &i915->gt.rps;
> -
> - return snprintf(buf, PAGE_SIZE, "%d\n",
> - intel_gpu_freq(rps, rps->cur_freq));
> -}
> -
> -static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
> - struct intel_rps *rps = &i915->gt.rps;
> -
> - return snprintf(buf, PAGE_SIZE, "%d\n",
> - intel_gpu_freq(rps, rps->boost_freq));
> -}
> -
> -static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
> - struct device_attribute *attr,
> - const char *buf, size_t count)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - struct intel_rps *rps = &dev_priv->gt.rps;
> - bool boost = false;
> - ssize_t ret;
> - u32 val;
> -
> - ret = kstrtou32(buf, 0, &val);
> - if (ret)
> - return ret;
> -
> - /* Validate against (static) hardware limits */
> - val = intel_freq_opcode(rps, val);
> - if (val < rps->min_freq || val > rps->max_freq)
> - return -EINVAL;
> -
> - mutex_lock(&rps->lock);
> - if (val != rps->boost_freq) {
> - rps->boost_freq = val;
> - boost = atomic_read(&rps->num_waiters);
> - }
> - mutex_unlock(&rps->lock);
> - if (boost)
> - schedule_work(&rps->work);
> -
> - return count;
> -}
> -
> -static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
> - struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - struct intel_rps *rps = &dev_priv->gt.rps;
> -
> - return snprintf(buf, PAGE_SIZE, "%d\n",
> - intel_gpu_freq(rps, rps->efficient_freq));
> -}
> -
> -static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - struct intel_rps *rps = &dev_priv->gt.rps;
> -
> - return snprintf(buf, PAGE_SIZE, "%d\n",
> - intel_gpu_freq(rps, rps->max_freq_softlimit));
> -}
> -
> -static ssize_t gt_max_freq_mhz_store(struct device *kdev,
> - struct device_attribute *attr,
> - const char *buf, size_t count)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - struct intel_rps *rps = &dev_priv->gt.rps;
> - ssize_t ret;
> - u32 val;
> -
> - ret = kstrtou32(buf, 0, &val);
> - if (ret)
> - return ret;
> -
> - mutex_lock(&rps->lock);
> -
> - val = intel_freq_opcode(rps, val);
> - if (val < rps->min_freq ||
> - val > rps->max_freq ||
> - val < rps->min_freq_softlimit) {
> - ret = -EINVAL;
> - goto unlock;
> - }
> -
> - if (val > rps->rp0_freq)
> - DRM_DEBUG("User requested overclocking to %d\n",
> - intel_gpu_freq(rps, val));
> -
> - rps->max_freq_softlimit = val;
> -
> - val = clamp_t(int, rps->cur_freq,
> - rps->min_freq_softlimit,
> - rps->max_freq_softlimit);
> -
> - /*
> - * We still need *_set_rps to process the new max_delay and
> - * update the interrupt limits and PMINTRMSK even though
> - * frequency request may be unchanged.
> - */
> - intel_rps_set(rps, val);
> -
> -unlock:
> - mutex_unlock(&rps->lock);
> -
> - return ret ?: count;
> -}
> -
> -static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - struct intel_rps *rps = &dev_priv->gt.rps;
> -
> - return snprintf(buf, PAGE_SIZE, "%d\n",
> - intel_gpu_freq(rps, rps->min_freq_softlimit));
> -}
> -
> -static ssize_t gt_min_freq_mhz_store(struct device *kdev,
> - struct device_attribute *attr,
> - const char *buf, size_t count)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - struct intel_rps *rps = &dev_priv->gt.rps;
> - ssize_t ret;
> - u32 val;
> -
> - ret = kstrtou32(buf, 0, &val);
> - if (ret)
> - return ret;
> -
> - mutex_lock(&rps->lock);
> -
> - val = intel_freq_opcode(rps, val);
> - if (val < rps->min_freq ||
> - val > rps->max_freq ||
> - val > rps->max_freq_softlimit) {
> - ret = -EINVAL;
> - goto unlock;
> - }
> -
> - rps->min_freq_softlimit = val;
> -
> - val = clamp_t(int, rps->cur_freq,
> - rps->min_freq_softlimit,
> - rps->max_freq_softlimit);
> -
> - /*
> - * We still need *_set_rps to process the new min_delay and
> - * update the interrupt limits and PMINTRMSK even though
> - * frequency request may be unchanged.
> - */
> - intel_rps_set(rps, val);
> -
> -unlock:
> - mutex_unlock(&rps->lock);
> -
> - return ret ?: count;
> -}
> -
> -static DEVICE_ATTR_RO(gt_act_freq_mhz);
> -static DEVICE_ATTR_RO(gt_cur_freq_mhz);
> -static DEVICE_ATTR_RW(gt_boost_freq_mhz);
> -static DEVICE_ATTR_RW(gt_max_freq_mhz);
> -static DEVICE_ATTR_RW(gt_min_freq_mhz);
> -
> -static DEVICE_ATTR_RO(vlv_rpe_freq_mhz);
> -
> -static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf);
> -static DEVICE_ATTR(gt_RP0_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
> -static DEVICE_ATTR(gt_RP1_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
> -static DEVICE_ATTR(gt_RPn_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
> -
> -/* For now we have a static number of RP states */
> -static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
> -{
> - struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
> - struct intel_rps *rps = &dev_priv->gt.rps;
> - u32 val;
> -
> - if (attr == &dev_attr_gt_RP0_freq_mhz)
> - val = intel_gpu_freq(rps, rps->rp0_freq);
> - else if (attr == &dev_attr_gt_RP1_freq_mhz)
> - val = intel_gpu_freq(rps, rps->rp1_freq);
> - else if (attr == &dev_attr_gt_RPn_freq_mhz)
> - val = intel_gpu_freq(rps, rps->min_freq);
> - else
> - BUG();
> -
> - return snprintf(buf, PAGE_SIZE, "%d\n", val);
> -}
> -
> -static const struct attribute * const gen6_attrs[] = {
> - &dev_attr_gt_act_freq_mhz.attr,
> - &dev_attr_gt_cur_freq_mhz.attr,
> - &dev_attr_gt_boost_freq_mhz.attr,
> - &dev_attr_gt_max_freq_mhz.attr,
> - &dev_attr_gt_min_freq_mhz.attr,
> - &dev_attr_gt_RP0_freq_mhz.attr,
> - &dev_attr_gt_RP1_freq_mhz.attr,
> - &dev_attr_gt_RPn_freq_mhz.attr,
> - NULL,
> -};
> -
> -static const struct attribute * const vlv_attrs[] = {
> - &dev_attr_gt_act_freq_mhz.attr,
> - &dev_attr_gt_cur_freq_mhz.attr,
> - &dev_attr_gt_boost_freq_mhz.attr,
> - &dev_attr_gt_max_freq_mhz.attr,
> - &dev_attr_gt_min_freq_mhz.attr,
> - &dev_attr_gt_RP0_freq_mhz.attr,
> - &dev_attr_gt_RP1_freq_mhz.attr,
> - &dev_attr_gt_RPn_freq_mhz.attr,
> - &dev_attr_vlv_rpe_freq_mhz.attr,
> - NULL,
> -};
> -
> #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
>
> static ssize_t error_state_read(struct file *filp, struct kobject *kobj,
> @@ -559,29 +225,6 @@ void i915_setup_sysfs(struct drm_i915_private *dev_priv)
> struct device *kdev = dev_priv->drm.primary->kdev;
> int ret;
>
> -#ifdef CONFIG_PM
> - if (HAS_RC6(dev_priv)) {
> - ret = sysfs_merge_group(&kdev->kobj,
> - &rc6_attr_group);
> - if (ret)
> - drm_err(&dev_priv->drm,
> - "RC6 residency sysfs setup failed\n");
> - }
> - if (HAS_RC6p(dev_priv)) {
> - ret = sysfs_merge_group(&kdev->kobj,
> - &rc6p_attr_group);
> - if (ret)
> - drm_err(&dev_priv->drm,
> - "RC6p residency sysfs setup failed\n");
> - }
> - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
> - ret = sysfs_merge_group(&kdev->kobj,
> - &media_rc6_attr_group);
> - if (ret)
> - drm_err(&dev_priv->drm,
> - "Media RC6 residency sysfs setup failed\n");
> - }
> -#endif
> if (HAS_L3_DPF(dev_priv)) {
> ret = device_create_bin_file(kdev, &dpf_attrs);
> if (ret)
> @@ -597,14 +240,6 @@ void i915_setup_sysfs(struct drm_i915_private *dev_priv)
> }
> }
>
> - ret = 0;
> - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> - ret = sysfs_create_files(&kdev->kobj, vlv_attrs);
> - else if (INTEL_GEN(dev_priv) >= 6)
> - ret = sysfs_create_files(&kdev->kobj, gen6_attrs);
> - if (ret)
> - drm_err(&dev_priv->drm, "RPS sysfs setup failed\n");
> -
> i915_setup_error_capture(kdev);
> }
>
> @@ -614,14 +249,6 @@ void i915_teardown_sysfs(struct drm_i915_private *dev_priv)
>
> i915_teardown_error_capture(kdev);
>
> - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> - sysfs_remove_files(&kdev->kobj, vlv_attrs);
> - else
> - sysfs_remove_files(&kdev->kobj, gen6_attrs);
> device_remove_bin_file(kdev, &dpf_attrs_1);
> device_remove_bin_file(kdev, &dpf_attrs);
> -#ifdef CONFIG_PM
> - sysfs_unmerge_group(&kdev->kobj, &rc6_attr_group);
> - sysfs_unmerge_group(&kdev->kobj, &rc6p_attr_group);
> -#endif
> }
> diff --git a/drivers/gpu/drm/i915/i915_sysfs.h b/drivers/gpu/drm/i915/i915_sysfs.h
> index 41afd4366416..ad6114de81c9 100644
> --- a/drivers/gpu/drm/i915/i915_sysfs.h
> +++ b/drivers/gpu/drm/i915/i915_sysfs.h
> @@ -6,8 +6,11 @@
> #ifndef __I915_SYSFS_H__
> #define __I915_SYSFS_H__
>
> +#include <linux/device.h>
You'll only need a forward declaration.
> +
> struct drm_i915_private;
>
> +struct drm_i915_private *kdev_minor_to_i915(struct device *kdev);
> void i915_setup_sysfs(struct drm_i915_private *i915);
> void i915_teardown_sysfs(struct drm_i915_private *i915);
--
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply
* usb: host: xhci: update event ring dequeue pointer on purpose
From: Fabio Estevam @ 2020-02-20 10:52 UTC (permalink / raw)
To: stable; +Cc: peter.chen, mathias.nyman, gregkh, Fabio Estevam
From: Peter Chen <peter.chen@nxp.com>
[ Upstream commit dc0ffbea5729a3abafa577ebfce87f18b79e294b ]
On some situations, the software handles TRB events slower
than adding TRBs, then xhci_handle_event can't return zero
long time, the xHC will consider the event ring is full,
and trigger "Event Ring Full" error, but in fact, the software
has already finished lots of events, just no chance to
update ERDP (event ring dequeue pointer).
In this commit, we force update ERDP if half of TRBS_PER_SEGMENT
events have handled to avoid "Event Ring Full" error.
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/1573836603-10871-2-git-send-email-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Fabio Estevam <festevam@gmail.com>
---
Hi,
One of our customer running 4.14 reported that this upstream patch
fixes USB issues, so I am sending it to the stable trees.
drivers/usb/host/xhci-ring.c | 60 +++++++++++++++++++++++++++++++-------------
1 file changed, 43 insertions(+), 17 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index e7aab31fd9a5..55084adf1faf 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2740,6 +2740,42 @@ static int xhci_handle_event(struct xhci_hcd *xhci)
return 1;
}
+/*
+ * Update Event Ring Dequeue Pointer:
+ * - When all events have finished
+ * - To avoid "Event Ring Full Error" condition
+ */
+static void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
+ union xhci_trb *event_ring_deq)
+{
+ u64 temp_64;
+ dma_addr_t deq;
+
+ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+ /* If necessary, update the HW's version of the event ring deq ptr. */
+ if (event_ring_deq != xhci->event_ring->dequeue) {
+ deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg,
+ xhci->event_ring->dequeue);
+ if (deq == 0)
+ xhci_warn(xhci, "WARN something wrong with SW event ring dequeue ptr\n");
+ /*
+ * Per 4.9.4, Software writes to the ERDP register shall
+ * always advance the Event Ring Dequeue Pointer value.
+ */
+ if ((temp_64 & (u64) ~ERST_PTR_MASK) ==
+ ((u64) deq & (u64) ~ERST_PTR_MASK))
+ return;
+
+ /* Update HC event ring dequeue pointer */
+ temp_64 &= ERST_PTR_MASK;
+ temp_64 |= ((u64) deq & (u64) ~ERST_PTR_MASK);
+ }
+
+ /* Clear the event handler busy flag (RW1C) */
+ temp_64 |= ERST_EHB;
+ xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue);
+}
+
/*
* xHCI spec says we can get an interrupt, and if the HC has an error condition,
* we might get bad data out of the event ring. Section 4.10.2.7 has a list of
@@ -2751,9 +2787,9 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
union xhci_trb *event_ring_deq;
irqreturn_t ret = IRQ_NONE;
unsigned long flags;
- dma_addr_t deq;
u64 temp_64;
u32 status;
+ int event_loop = 0;
spin_lock_irqsave(&xhci->lock, flags);
/* Check if the xHC generated the interrupt, or the irq is shared */
@@ -2807,24 +2843,14 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
/* FIXME this should be a delayed service routine
* that clears the EHB.
*/
- while (xhci_handle_event(xhci) > 0) {}
-
- temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
- /* If necessary, update the HW's version of the event ring deq ptr. */
- if (event_ring_deq != xhci->event_ring->dequeue) {
- deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg,
- xhci->event_ring->dequeue);
- if (deq == 0)
- xhci_warn(xhci, "WARN something wrong with SW event "
- "ring dequeue ptr.\n");
- /* Update HC event ring dequeue pointer */
- temp_64 &= ERST_PTR_MASK;
- temp_64 |= ((u64) deq & (u64) ~ERST_PTR_MASK);
+ while (xhci_handle_event(xhci) > 0) {
+ if (event_loop++ < TRBS_PER_SEGMENT / 2)
+ continue;
+ xhci_update_erst_dequeue(xhci, event_ring_deq);
+ event_loop = 0;
}
- /* Clear the event handler busy flag (RW1C); event ring is empty. */
- temp_64 |= ERST_EHB;
- xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue);
+ xhci_update_erst_dequeue(xhci, event_ring_deq);
ret = IRQ_HANDLED;
out:
--
cgit 1.2-0.3.lf.el7
^ permalink raw reply related
* [ndctl PATCH 6/8] libndctl,papr_scm: Implement scaffolding to issue and handle DSM cmds
From: Vaibhav Jain @ 2020-02-20 10:49 UTC (permalink / raw)
To: linux-nvdimm; +Cc: Vaibhav Jain, Aneesh Kumar K . V, Alastair D'Silva
In-Reply-To: <20200220104928.198625-1-vaibhav@linux.ibm.com>
This patch implement necessary infrastructure inside 'papr_scm.c' to
issue and handle DSM commands. Changed implemented are:
* Implement dimm initialization/un-initialization functions
papr_dimm_init()/unint() to allocate a per-dimm 'struct dimm_priv'
instance.
* New helper function allocate_cmd() to allocate command packages for
a specific DSM command and payload size.
* New function update_dimm_state() to parse a given command payload
and update per dimm 'struct dimm_priv'.
* Provide an implementation of 'dimm_ops->smart_get_flags' to send the
submitted instance of 'struct ndctl_cmd' to update_dimm_state().
* Logging helpers for papr_scm that use the underlying libndctl
provided logging.
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
---
ndctl/lib/papr_scm.c | 174 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 174 insertions(+)
diff --git a/ndctl/lib/papr_scm.c b/ndctl/lib/papr_scm.c
index 878698a5a8b4..0a3857e2a4c4 100644
--- a/ndctl/lib/papr_scm.c
+++ b/ndctl/lib/papr_scm.c
@@ -20,6 +20,29 @@
#include <lib/private.h>
#include <papr_scm_dsm.h>
+/* Utility logging maros for simplify logging */
+#define PAPR_DBG(_dimm_, _format_str_, ...) dbg(_dimm_->bus->ctx, \
+ "papr_scm:"#_format_str_, \
+ ##__VA_ARGS__)
+#define PAPR_INFO(_dimm_, _format_str_, ...) info(_dimm_->bus->ctx, \
+ "papr_scm:"#_format_str_, \
+ ##__VA_ARGS__)
+#define PAPR_ERR(_dimm_, _format_str_, ...) err(_dimm_->bus->ctx, \
+ "papr_scm:"#_format_str_, \
+ ##__VA_ARGS__)
+#define PAPR_NOTICE(_dimm_, _format_str_, ...) notice(_dimm_->bus->ctx, \
+ "papr_scm:"#_format_str_, \
+ ##__VA_ARGS__)
+
+/* Command flags to indicate if a given command is parsed of not */
+#define CMD_PKG_SUBMITTED 1
+#define CMD_PKG_PARSED 2
+
+/* Per dimm data. Holds per-dimm data parsed from the cmd_pkgs */
+struct dimm_priv {
+ /* Empty for now */
+};
+
static bool papr_cmd_is_supported(struct ndctl_dimm *dimm, int cmd)
{
/* Handle this separately to support monitor mode */
@@ -29,6 +52,157 @@ static bool papr_cmd_is_supported(struct ndctl_dimm *dimm, int cmd)
return !!(dimm->cmd_mask & (1ULL << cmd));
}
+static __u64 pcmd_to_dsm(const struct nd_papr_scm_cmd_pkg *pcmd)
+{
+ return pcmd->hdr.nd_command;
+}
+
+/* Verify if the given command is supported and valid */
+static bool cmd_is_valid(struct ndctl_dimm *dimm, struct ndctl_cmd *cmd)
+{
+ const struct nd_papr_scm_cmd_pkg *pcmd = nd_to_papr_cmd_pkg(cmd->pkg);
+
+ if (dimm == NULL)
+ return false;
+
+ if (cmd == NULL) {
+ PAPR_ERR(dimm, "Invalid command\n");
+ return false;
+ }
+
+ /* Verify the command family */
+ if (pcmd->hdr.nd_family != NVDIMM_FAMILY_PAPR_SCM) {
+ PAPR_ERR(dimm, "Invalid command family:0x%016llx\n",
+ pcmd->hdr.nd_family);
+ return false;
+ }
+
+ /* Verify the DSM */
+ if (pcmd_to_dsm(pcmd) <= DSM_PAPR_SCM_MIN ||
+ pcmd_to_dsm(pcmd) >= DSM_PAPR_SCM_MAX) {
+ PAPR_ERR(dimm, "Invalid command :0x%016llx\n",
+ pcmd->hdr.nd_command);
+ return false;
+ }
+
+ return true;
+}
+
+/* Parse a command payload and update dimm flags/private data */
+static int update_dimm_stats(struct ndctl_dimm *dimm, struct ndctl_cmd *cmd)
+{
+ const struct nd_papr_scm_cmd_pkg *pcmd;
+
+ if (!cmd_is_valid(dimm, cmd))
+ return -EINVAL;
+
+ /*
+ * Silently prevent parsing of an already parsed ndctl_cmd else
+ * mark the command as parsed.
+ */
+ if (cmd->status >= CMD_PKG_PARSED) {
+ return 0;
+ } else if (cmd->status < 0) {
+ PAPR_ERR(dimm, "Command error %d\n", cmd->status);
+ return -ENXIO;
+ }
+
+ /* Mark the command as parsed */
+ cmd->status = CMD_PKG_PARSED;
+
+ /* Get the command dsm and handle it */
+ pcmd = nd_to_papr_cmd_pkg(cmd->pkg);
+ switch (pcmd_to_dsm(pcmd)) {
+ default:
+ PAPR_ERR(dimm, "Unhandled dsm-command 0x%016llx\n",
+ pcmd_to_dsm(pcmd));
+ return -ENOENT;
+ }
+}
+
+/* Allocate a struct ndctl_cmd for given dsm command with payload size */
+static struct ndctl_cmd *allocate_cmd(struct ndctl_dimm *dimm,
+ __u64 dsm_cmd, size_t payload_size,
+ uint16_t payload_version)
+{
+ struct ndctl_cmd *cmd;
+ struct nd_papr_scm_cmd_pkg *pcmd;
+ size_t size;
+
+ size = sizeof(struct ndctl_cmd) +
+ sizeof(struct nd_papr_scm_cmd_pkg) + payload_size;
+ cmd = calloc(1, size);
+ if (!cmd)
+ return NULL;
+ pcmd = nd_to_papr_cmd_pkg(cmd->pkg);
+
+ ndctl_cmd_ref(cmd);
+ cmd->dimm = dimm;
+ cmd->type = ND_CMD_CALL;
+ cmd->size = size;
+ cmd->status = CMD_PKG_SUBMITTED;
+ cmd->firmware_status = (u32 *) &pcmd->cmd_status;
+
+ /* Populate the nd_cmd_pkg contained in nd_papr_scm_cmd_pkg */
+ pcmd->hdr.nd_family = NVDIMM_FAMILY_PAPR_SCM;
+ pcmd->hdr.nd_command = dsm_cmd;
+
+ pcmd->payload_version = payload_version;
+ pcmd->payload_offset = sizeof(struct nd_papr_scm_cmd_pkg);
+
+ /* Keep payload size empty. To be populated by called */
+ pcmd->hdr.nd_fw_size = 0;
+ pcmd->hdr.nd_size_out = 0;
+ pcmd->hdr.nd_size_in = 0;
+
+ return cmd;
+}
+
+static unsigned int papr_smart_get_flags(struct ndctl_cmd *cmd)
+{
+ /* In case of error return empty flags * */
+ if (update_dimm_stats(cmd->dimm, cmd))
+ return 0;
+
+ /* Return empty flags for now as no DSM support */
+ return 0;
+}
+
+static int papr_dimm_init(struct ndctl_dimm *dimm)
+{
+ struct dimm_priv *p;
+
+ if (dimm->dimm_user_data) {
+ PAPR_DBG(dimm, "Dimm already initialized !!\n");
+ return 0;
+ }
+
+ p = calloc(1, sizeof(struct dimm_priv));
+ if (!p) {
+ PAPR_ERR(dimm, "Unable to allocate memory for dimm-private\n");
+ return -1;
+ }
+
+ dimm->dimm_user_data = p;
+ return 0;
+}
+
+static void papr_dimm_uninit(struct ndctl_dimm *dimm)
+{
+ struct dimm_priv *p = dimm->dimm_user_data;
+
+ if (!p) {
+ PAPR_DBG(dimm, "Dimm already un-initialized !!\n");
+ return;
+ }
+
+ dimm->dimm_user_data = NULL;
+ free(p);
+}
+
struct ndctl_dimm_ops * const papr_scm_dimm_ops = &(struct ndctl_dimm_ops) {
.cmd_is_supported = papr_cmd_is_supported,
+ .dimm_init = papr_dimm_init,
+ .dimm_uninit = papr_dimm_uninit,
+ .smart_get_flags = papr_smart_get_flags,
};
--
2.24.1
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
^ permalink raw reply related
* load a freebsd derived kernel on Qemu-system-arm
From: Kamal R. Prasad @ 2020-02-20 10:52 UTC (permalink / raw)
To: qemu-arm
[-- Attachment #1: Type: text/plain, Size: 442 bytes --]
hello,
when I try to load a freebsd kernel onto Qemu running on my Mac, I get
this error:-
# qemu-system-arm -machine versatileab -kernel ./kernel
qemu-system-arm: GLib: g_mapped_file_unref: assertion 'file != NULL' failed
Can someone tell me what I am missing? The code is built for arm but online
linux, freebsd build does not generate a vmlinuz or ignited file. The
target is a cortex -arm quad core board (from Broadcom).
thanks
[-- Attachment #2: Type: text/html, Size: 2168 bytes --]
^ permalink raw reply
* [ndctl PATCH 7/8] libndctl,papr_scm: Implement support for DSM_PAPR_SCM_HEALTH
From: Vaibhav Jain @ 2020-02-20 10:49 UTC (permalink / raw)
To: linux-nvdimm; +Cc: Vaibhav Jain, Aneesh Kumar K . V, Alastair D'Silva
In-Reply-To: <20200220104928.198625-1-vaibhav@linux.ibm.com>
Add support for reporting DIMM health by issuing DSM_PAPR_SCM_HEALTH
DSM. It returns an instance of '
struct nd_papr_scm_dimm_health_stat' as defined in
'papr_scm_dsm.h'. The patch provides support for dimm-ops 'new_smart' &
'smart_get_health' as papr_new_smart_health() &
papr_smart_get_health() respectively. This callbacks should enable
ndctl to report DIMM health.
Also a new member 'struct dimm_priv.health' is introduced which holds
the current health status of the dimm. This member is set inside newly
added function 'update_dimm_health_v1()' which parses the v1 payload
returned by the kernel after servicing DSM_PAPR_SCM_HEALTH. The
function will also update dimm-flags viz 'struct ndctl_dimm.flags.f_*'
based on the flags set in the returned payload.
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
---
ndctl/lib/papr_scm.c | 80 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 77 insertions(+), 3 deletions(-)
diff --git a/ndctl/lib/papr_scm.c b/ndctl/lib/papr_scm.c
index 0a3857e2a4c4..a01649d3a9fe 100644
--- a/ndctl/lib/papr_scm.c
+++ b/ndctl/lib/papr_scm.c
@@ -40,7 +40,9 @@
/* Per dimm data. Holds per-dimm data parsed from the cmd_pkgs */
struct dimm_priv {
- /* Empty for now */
+
+ /* Cache the dimm health status */
+ struct nd_papr_scm_dimm_health_stat health;
};
static bool papr_cmd_is_supported(struct ndctl_dimm *dimm, int cmd)
@@ -88,6 +90,43 @@ static bool cmd_is_valid(struct ndctl_dimm *dimm, struct ndctl_cmd *cmd)
return true;
}
+/*
+ * Parse the nd_papr_scm_dimm_health_stat_v1 payload embedded in ndctl_cmd and
+ * update dimm health/flags
+ */
+static int update_dimm_health_v1(struct ndctl_dimm *dimm, struct ndctl_cmd *cmd)
+{
+ struct nd_papr_scm_cmd_pkg *pcmd = nd_to_papr_cmd_pkg(cmd->pkg);
+ struct dimm_priv *p = dimm->dimm_user_data;
+ const struct nd_papr_scm_dimm_health_stat_v1 *health =
+ papr_scm_pcmd_to_payload(pcmd);
+
+ /* Update the dimm flags */
+ dimm->flags.f_arm = health->dimm_unarmed;
+ dimm->flags.f_flush = health->dimm_bad_shutdown;
+ dimm->flags.f_restore = health->dimm_bad_restore;
+ dimm->flags.f_smart = (health->dimm_health != 0);
+
+ /* Cache the dimm health information */
+ memcpy(&p->health, health, sizeof(*health));
+ return 0;
+}
+
+/* Check payload version returned and pass the packet to appropriate handler */
+static int update_dimm_health(struct ndctl_dimm *dimm, struct ndctl_cmd *cmd)
+{
+ const struct nd_papr_scm_cmd_pkg *pcmd = nd_to_papr_cmd_pkg(cmd->pkg);
+
+ if (pcmd->payload_version == 1)
+ return update_dimm_health_v1(dimm, cmd);
+
+ /* unknown version */
+ PAPR_ERR(dimm, "Unknown payload version for dimm_health."
+ "Ver=%d, Supported=%d\n", pcmd->payload_version,
+ ND_PAPR_SCM_DIMM_HEALTH_VERSION);
+ return -EINVAL;
+}
+
/* Parse a command payload and update dimm flags/private data */
static int update_dimm_stats(struct ndctl_dimm *dimm, struct ndctl_cmd *cmd)
{
@@ -113,6 +152,8 @@ static int update_dimm_stats(struct ndctl_dimm *dimm, struct ndctl_cmd *cmd)
/* Get the command dsm and handle it */
pcmd = nd_to_papr_cmd_pkg(cmd->pkg);
switch (pcmd_to_dsm(pcmd)) {
+ case DSM_PAPR_SCM_HEALTH:
+ return update_dimm_health(dimm, cmd);
default:
PAPR_ERR(dimm, "Unhandled dsm-command 0x%016llx\n",
pcmd_to_dsm(pcmd));
@@ -158,14 +199,45 @@ static struct ndctl_cmd *allocate_cmd(struct ndctl_dimm *dimm,
return cmd;
}
+static struct ndctl_cmd *papr_new_smart_health(struct ndctl_dimm *dimm)
+{
+ struct ndctl_cmd *cmd_ret;
+
+ cmd_ret = allocate_cmd(dimm, DSM_PAPR_SCM_HEALTH,
+ sizeof(struct nd_papr_scm_dimm_health_stat),
+ ND_PAPR_SCM_DIMM_HEALTH_VERSION);
+ if (!cmd_ret) {
+ PAPR_ERR(dimm, "Unable to allocate smart_health command\n");
+ return NULL;
+ }
+
+ cmd_ret->pkg[0].nd_size_out = ND_PAPR_SCM_ENVELOPE_CONTENT_SIZE(
+ struct nd_papr_scm_dimm_health_stat);
+
+ return cmd_ret;
+}
+
+static unsigned int papr_smart_get_health(struct ndctl_cmd *cmd)
+{
+ struct dimm_priv *p = cmd->dimm->dimm_user_data;
+
+ /*
+ * Update the dimm stats and use some math to return one of
+ * defined ND_SMART_*_HEALTH values
+ */
+ if (update_dimm_stats(cmd->dimm, cmd) || !p->health.dimm_health)
+ return 0;
+ else
+ return 1 << (p->health.dimm_health - 1);
+}
+
static unsigned int papr_smart_get_flags(struct ndctl_cmd *cmd)
{
/* In case of error return empty flags * */
if (update_dimm_stats(cmd->dimm, cmd))
return 0;
- /* Return empty flags for now as no DSM support */
- return 0;
+ return ND_SMART_HEALTH_VALID;
}
static int papr_dimm_init(struct ndctl_dimm *dimm)
@@ -205,4 +277,6 @@ struct ndctl_dimm_ops * const papr_scm_dimm_ops = &(struct ndctl_dimm_ops) {
.dimm_init = papr_dimm_init,
.dimm_uninit = papr_dimm_uninit,
.smart_get_flags = papr_smart_get_flags,
+ .new_smart = papr_new_smart_health,
+ .smart_get_health = papr_smart_get_health,
};
--
2.24.1
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
^ permalink raw reply related
* Re: [PATCH nf-next v4 0/9] nftables: Set implementation for arbitrary concatenation of ranges
From: Phil Sutter @ 2020-02-20 10:52 UTC (permalink / raw)
To: Stefano Brivio
Cc: Pablo Neira Ayuso, netfilter-devel, Florian Westphal,
Kadlecsik József, Eric Garver
In-Reply-To: <cover.1579647351.git.sbrivio@redhat.com>
Hi Stefano,
When playing with adding multiple elements, I suddenly noticed a
disturbance in the force (general protection fault). Here's a
reproducer:
| $NFT -f - <<EOF
| table t {
| set s {
| type ipv4_addr . inet_service
| flags interval
| }
| }
| EOF
|
| $NFT add element t s '{ 10.0.0.1 . 22-25, 10.0.0.1 . 10-20 }'
| $NFT flush set t s
| $NFT add element t s '{ 10.0.0.1 . 10-20, 10.0.0.1 . 22-25 }'
It is pretty reliable, though sometimes needs a second call. Looks like some
things going on in parallel which shouldn't. Here's a typical last breath:
[ 71.319848] general protection fault, probably for non-canonical address 0x6f6b6e696c2e756e: 0000 [#1] PREEMPT SMP PTI
[ 71.321540] CPU: 3 PID: 1201 Comm: kworker/3:2 Not tainted 5.6.0-rc1-00377-g2bb07f4e1d861 #192
[ 71.322746] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190711_202441-buildvm-armv7-10.arm.fedoraproject.org-2.fc31 04/01/2014
[ 71.324430] Workqueue: events nf_tables_trans_destroy_work [nf_tables]
[ 71.325387] RIP: 0010:nft_set_elem_destroy+0xa5/0x110 [nf_tables]
[ 71.326164] Code: 89 d4 84 c0 74 0e 8b 77 44 0f b6 f8 48 01 df e8 41 ff ff ff 45 84 e4 74 36 44 0f b6 63 08 45 84 e4 74 2c 49 01 dc 49 8b 04 24 <48> 8b 40 38 48 85 c0 74 4f 48 89 e7 4c 8b
[ 71.328423] RSP: 0018:ffffc9000226fd90 EFLAGS: 00010282
[ 71.329225] RAX: 6f6b6e696c2e756e RBX: ffff88813ab79f60 RCX: ffff88813931b5a0
[ 71.330365] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff88813ab79f9a
[ 71.331473] RBP: ffff88813ab79f60 R08: 0000000000000008 R09: 0000000000000000
[ 71.332627] R10: 000000000000021c R11: 0000000000000000 R12: ffff88813ab79fc2
[ 71.333615] R13: ffff88813b3adf50 R14: dead000000000100 R15: ffff88813931b8a0
[ 71.334596] FS: 0000000000000000(0000) GS:ffff88813bd80000(0000) knlGS:0000000000000000
[ 71.335780] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 71.336577] CR2: 000055ac683710f0 CR3: 000000013a222003 CR4: 0000000000360ee0
[ 71.337533] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 71.338557] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 71.339718] Call Trace:
[ 71.340093] nft_pipapo_destroy+0x7a/0x170 [nf_tables_set]
[ 71.340973] nft_set_destroy+0x20/0x50 [nf_tables]
[ 71.341879] nf_tables_trans_destroy_work+0x246/0x260 [nf_tables]
[ 71.342916] process_one_work+0x1d5/0x3c0
[ 71.343601] worker_thread+0x4a/0x3c0
[ 71.344229] kthread+0xfb/0x130
[ 71.344780] ? process_one_work+0x3c0/0x3c0
[ 71.345477] ? kthread_park+0x90/0x90
[ 71.346129] ret_from_fork+0x35/0x40
[ 71.346748] Modules linked in: nf_tables_set nf_tables nfnetlink 8021q [last unloaded: nfnetlink]
[ 71.348153] ---[ end trace 2eaa8149ca759bcc ]---
[ 71.349066] RIP: 0010:nft_set_elem_destroy+0xa5/0x110 [nf_tables]
[ 71.350016] Code: 89 d4 84 c0 74 0e 8b 77 44 0f b6 f8 48 01 df e8 41 ff ff ff 45 84 e4 74 36 44 0f b6 63 08 45 84 e4 74 2c 49 01 dc 49 8b 04 24 <48> 8b 40 38 48 85 c0 74 4f 48 89 e7 4c 8b
[ 71.350017] RSP: 0018:ffffc9000226fd90 EFLAGS: 00010282
[ 71.350019] RAX: 6f6b6e696c2e756e RBX: ffff88813ab79f60 RCX: ffff88813931b5a0
[ 71.350019] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff88813ab79f9a
[ 71.350020] RBP: ffff88813ab79f60 R08: 0000000000000008 R09: 0000000000000000
[ 71.350021] R10: 000000000000021c R11: 0000000000000000 R12: ffff88813ab79fc2
[ 71.350022] R13: ffff88813b3adf50 R14: dead000000000100 R15: ffff88813931b8a0
[ 71.350025] FS: 0000000000000000(0000) GS:ffff88813bd80000(0000) knlGS:0000000000000000
[ 71.350026] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 71.350027] CR2: 000055ac683710f0 CR3: 000000013a222003 CR4: 0000000000360ee0
[ 71.350028] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 71.350028] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 71.350030] Kernel panic - not syncing: Fatal exception
[ 71.350412] Kernel Offset: disabled
[ 71.365922] ---[ end Kernel panic - not syncing: Fatal exception ]---
Cheers, Phil
^ permalink raw reply
* Re: Questions about logic_pio
From: John Garry @ 2020-02-20 10:52 UTC (permalink / raw)
To: Wei Xu, Jiaxun Yang, bhelgaas, andyshevchenko; +Cc: Arnd Bergmann, linux-kernel
In-Reply-To: <5E4E55F7.70800@hisilicon.com>
+ Arnd (also remove some defunct e-mail addresses)
On 20/02/2020 09:48, Wei Xu wrote:
> Hi Jiaxun,
>
> On 2020/2/19 21:58, Jiaxun Yang wrote:
>> Hi there,
>>
>> Logic PIO gives us a way to make indirect PIO access, however,
>> the way it handles direct (MMIO) I/O access confused me.
>>
>> I was trying to create a PCI controller Driver and noticed that I/O range parsed
>> from DeviceTree will be added to the Logic PIO range by logic_pio_register_range.
>> And than PCI subsystem will use the ioport obtained from `logic_pio_trans_cpuaddr`
>> to allocate resources for the host bridge. In my case, the range added to the logic pio
>> was set as hw_start 0x4000, size 0x4000.
FYI, For when CONFIG_INDIRECT_PIO is defined, in logical PIO space, we
reserve the last 0x4000 bytes for Indirectio, while the rest is
available for MMIO. When CONFIG_INDIRECT_PIO is not defined, all Logical
PIO space is available for MMIO.
Later, `logic_pio_trans_cpuaddr` called
>> by `pci_address_to_pio` gives a ioport of 0x0, which is totally wrong.
ioport of 0x0 seems fine. Here is my IO port listing for my host (which
defines PCI_IOBASE):
00000000-0000ffff : PCI Bus 0002:f8
00001000-00001fff : PCI Bus 0002:f9
00001000-00001007 : 0002:f9:00.0
00001000-00001007 : serial
00001008-0000100f : 0002:f9:00.1
00001008-0000100f : serial
00001010-00001017 : 0002:f9:00.2
00001018-0000101f : 0002:f9:00.2
00010000-0001ffff : PCI Bus 0004:88
00020000-0002ffff : PCI Bus 0005:78
00030000-0003ffff : PCI Bus 0006:c0
00040000-0004ffff : PCI Bus 0007:90
00050000-0005ffff : PCI Bus 000a:10
00060000-0006ffff : PCI Bus 000c:20
00070000-0007ffff : PCI Bus 000d:30
00ffc0e3-00ffc0e7 : hisi-lpc-ipmi.5.auto
00ffc2f7-00ffffff : serial8250.6.auto
00ffc2f7-00ffc2fe : serial
>>
>> After dig into logic pio logic, I found that logic pio is trying to "allocate" an io_start
>> for MMIO ranges, the allocation starts from 0x0. And later the io_start is used to calculate
>> cpu_address. In my opinion, for direct MMIO access, logic_pio address should always
>> equal to hw address,
I'm not sure what you mean by simply the hw address.
So there is the physical cpu address of the host bridge IO ports, and
these host bridge IO ports are mapped in pci_remap_iospace() to some
part of logical PIO space. The base of the logical PIO space corresponds
to PCI_IOBASE virtual address.
because there is no way to translate address from logic pio address
>> to actual hw address in {in,out}{b,sb,w,sb,l,sl} operations.
Please check
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/logic_pio.c?h=v5.6-rc2#n231
for reference:
#if defined(CONFIG_INDIRECT_PIO) && defined(PCI_IOBASE)
#define BUILD_LOGIC_IO(bw, type) \
type logic_in##bw(unsigned long addr) \{ \ type ret =
(type)~0; \ \ if (addr < MMIO_UPPER_LIMIT) { \ ret =
read##bw(PCI_IOBASE + addr); \ } else if (addr >= MMIO_UPPER_LIMIT &&
addr < IO_SPACE_LIMIT) { \ struct logic_pio_hwaddr *entry =
find_io_range(addr); \ \ if (entry) \ ret =
entry->ops->in(entry->hostdata, \ addr, sizeof(type)); \ else
\ WARN_ON_ONCE(1); \ } \ return ret; \}
For when the IO port address is within the MMIO range (addr <
MMIO_UPPER_LIMIT), we use readl(PCI_IOBASE + addr); please remember that
PCI_IOBASE virtual address is mapped to the physical host bridge IO port
address.
For when CONFIG_INDIRECT_PIO is not defined, we use the asm generic version:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/asm-generic/io.h?h=v5.6-rc2#n461
As an aside, I do notice that the definitions here have changed here in
87fe2d543f81 ("io: change inX() to have their own IO barrier overrides")
since we introduced logic PIO.
>>
>> How this mechanism intends to work?
I hope the above description makes this clearer.
What is the reason that we are trying to
>> allocate a io_start for MMIO rather than take their hw_start ioport directly?
For PCI MMIO, the io_start is the Logical PIO range start address.
>>
>> Thanks.
>
> Corrected John's mail address.
> Maybe he can help.
Thanks to xuwei
>
> Best Regards,
> Wei
>
>>
>> --
>> Jiaxun Yang
>>
>>
>>
>> .
>>
>
> .
>
^ permalink raw reply
* [ndctl PATCH 3/8] libncdtl: Add initial support for NVDIMM_FAMILY_PAPR_SCM dimm family
From: Vaibhav Jain @ 2020-02-20 10:49 UTC (permalink / raw)
To: linux-nvdimm; +Cc: Vaibhav Jain, Aneesh Kumar K . V, Alastair D'Silva
In-Reply-To: <20200220104928.198625-1-vaibhav@linux.ibm.com>
The patch-set adds necessary scaffolding in libndctl for dimms that
support papr_scm specification[1]. Since there can be platforms that
support Open-Firmware[2] but not the papr_scm specification, hence the
changes proposed first add support for probing if the dimm bus
supports Open-Firmware. This is done via querying for sysfs attribute
'of_node' in dimm device sysfs directory. If available newly
introduced member 'struct ndctl_bus.has_of_node' is set.
During the probe of the dimm and execution of add_dimm(), the newly
introduced add_of_pmem_dimm() is called if dimm bus reports supports
Open-Firmware.
Function add_of_pmem_dimm() queries the 'compatible' device tree
attribute and based on its value assign NVDIMM_FAMILY_PAPR_SCM to the
dimm command family. In future based on the contents of 'compatible'
attribute more of_pmem dimm families can be queried.
Presently the dimm-ops implementation for NVDIMM_FAMILY_PAPR_SCM is
available in global variable 'papr_scm_dimm_ops' which is a NULL
pointer. Subsequent patches will provide a working dimm-ops
implementation pointed to by 'papr_scm_dimm_ops'.
References:
[1] : https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id=58b278f568f0509497e2df7310bfd719156a60d1
[2] : https://en.wikipedia.org/wiki/Open_Firmware
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
---
ndctl/lib/libndctl.c | 42 ++++++++++++++++++++++++++++++++++++++++++
ndctl/lib/private.h | 2 ++
ndctl/libndctl.h | 1 +
ndctl/ndctl.h | 1 +
4 files changed, 46 insertions(+)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index a5f5fdac9f48..650406d27512 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -858,6 +858,12 @@ static void *add_bus(void *parent, int id, const char *ctl_base)
bus->revision = strtoul(buf, NULL, 0);
}
+ sprintf(path, "%s/device/of_node/compatible", ctl_base);
+ if (sysfs_read_attr(ctx, path, buf) < 0)
+ bus->has_of_node = 0;
+ else
+ bus->has_of_node = 1;
+
sprintf(path, "%s/device/nfit/dsm_mask", ctl_base);
if (sysfs_read_attr(ctx, path, buf) < 0)
bus->nfit_dsm_mask = 0;
@@ -966,6 +972,10 @@ NDCTL_EXPORT int ndctl_bus_has_nfit(struct ndctl_bus *bus)
return bus->has_nfit;
}
+NDCTL_EXPORT int ndctl_bus_has_of_node(struct ndctl_bus *bus)
+{
+ return bus->has_of_node;
+}
/**
* ndctl_bus_get_major - nd bus character device major number
* @bus: ndctl_bus instance returned from ndctl_bus_get_{first|next}
@@ -1405,6 +1415,34 @@ static int ndctl_bind(struct ndctl_ctx *ctx, struct kmod_module *module,
static int ndctl_unbind(struct ndctl_ctx *ctx, const char *devpath);
static struct kmod_module *to_module(struct ndctl_ctx *ctx, const char *alias);
+static int add_of_pmem_dimm(struct ndctl_dimm *dimm, const char *dimm_base)
+{
+ int rc = -ENODEV;
+ char buf[SYSFS_ATTR_SIZE];
+ struct ndctl_ctx *ctx = dimm->bus->ctx;
+ char *path = calloc(1, strlen(dimm_base) + 100);
+
+ dbg(ctx, "Probing of_pmem dimm %d at %s\n", dimm->id, dimm_base);
+
+ if (!path)
+ return -ENOMEM;
+
+ sprintf(path, "%s/../of_node/compatible", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) < 0)
+ goto out;
+
+
+ dbg(ctx, "Compatible of_pmem dimm %d at %s\n", dimm->id, buf);
+ if (strcmp(buf, "ibm,pmemory") == 0) {
+ dimm->cmd_family = NVDIMM_FAMILY_PAPR_SCM;
+ rc = 0;
+ goto out;
+ }
+out:
+ free(path);
+ return rc;
+}
+
static int add_nfit_dimm(struct ndctl_dimm *dimm, const char *dimm_base)
{
int i, rc = -1;
@@ -1583,6 +1621,8 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
if (ndctl_bus_has_nfit(bus)) {
dimm->formats = formats;
rc = add_nfit_dimm(dimm, dimm_base);
+ } else if (ndctl_bus_has_of_node(bus)) {
+ rc = add_of_pmem_dimm(dimm, dimm_base);
}
if (rc == -ENODEV) {
@@ -1600,6 +1640,8 @@ static void *add_dimm(void *parent, int id, const char *dimm_base)
dimm->ops = msft_dimm_ops;
if (dimm->cmd_family == NVDIMM_FAMILY_HYPERV)
dimm->ops = hyperv_dimm_ops;
+ if (dimm->cmd_family == NVDIMM_FAMILY_PAPR_SCM)
+ dimm->ops = papr_scm_dimm_ops;
/* Call the dimm initialization function if needed */
if (!rc && dimm->ops && dimm->ops->dimm_init)
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index fb7fa47f1f37..16754eda7634 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -167,6 +167,7 @@ struct ndctl_bus {
int dimms_init;
int regions_init;
int has_nfit;
+ int has_of_node;
char *bus_path;
char *bus_buf;
size_t buf_len;
@@ -351,6 +352,7 @@ struct ndctl_dimm_ops * const intel_dimm_ops;
struct ndctl_dimm_ops * const hpe1_dimm_ops;
struct ndctl_dimm_ops * const msft_dimm_ops;
struct ndctl_dimm_ops * const hyperv_dimm_ops;
+struct ndctl_dimm_ops * const papr_scm_dimm_ops;
static inline struct ndctl_bus *cmd_to_bus(struct ndctl_cmd *cmd)
{
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index 9a53049e7f61..32202654885a 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -119,6 +119,7 @@ struct ndctl_bus *ndctl_bus_get_next(struct ndctl_bus *bus);
bus = ndctl_bus_get_next(bus))
struct ndctl_ctx *ndctl_bus_get_ctx(struct ndctl_bus *bus);
int ndctl_bus_has_nfit(struct ndctl_bus *bus);
+int ndctl_bus_has_of_node(struct ndctl_bus *bus);
unsigned int ndctl_bus_get_major(struct ndctl_bus *bus);
unsigned int ndctl_bus_get_minor(struct ndctl_bus *bus);
const char *ndctl_bus_get_devname(struct ndctl_bus *bus);
diff --git a/ndctl/ndctl.h b/ndctl/ndctl.h
index 008f81cdeb9f..426708e1fd9b 100644
--- a/ndctl/ndctl.h
+++ b/ndctl/ndctl.h
@@ -263,6 +263,7 @@ struct nd_cmd_pkg {
#define NVDIMM_FAMILY_HPE2 2
#define NVDIMM_FAMILY_MSFT 3
#define NVDIMM_FAMILY_HYPERV 4
+#define NVDIMM_FAMILY_PAPR_SCM 5
#define ND_IOCTL_CALL _IOWR(ND_IOCTL, ND_CMD_CALL,\
struct nd_cmd_pkg)
--
2.24.1
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
^ permalink raw reply related
* [ndctl PATCH 4/8] libndctl: Add support for parsing of_pmem dimm flags and monitor mode
From: Vaibhav Jain @ 2020-02-20 10:49 UTC (permalink / raw)
To: linux-nvdimm; +Cc: Vaibhav Jain, Aneesh Kumar K . V, Alastair D'Silva
In-Reply-To: <20200220104928.198625-1-vaibhav@linux.ibm.com>
Add support for parsing the dimm flags for of_pmem supporting
dimms. The flag file is exported in sysfs as 'papr_flags' and its
contents are space separated flags indicating the current state of the
dimm. A newly introduced function parse_of_pmem_flags() reads the contents
of this flag file and sets appropriate flag bits in 'struct
ndctl_dimm.flags'. This function is called at the end of of_pmem probe
function add_of_pmem_dimm().
Also we advertise support for monitor mode by allocating a file
descriptor to the 'papr_flags' file and assigning it to 'struct
ndctl_dimm.health_event_fd'.
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
---
ndctl/lib/libndctl.c | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 650406d27512..7cc50afac404 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -801,6 +801,28 @@ static void parse_nfit_mem_flags(struct ndctl_dimm *dimm, char *flags)
ndctl_dimm_get_devname(dimm), flags);
}
+static void parse_of_pmem_flags(struct ndctl_dimm *dimm, char *flags)
+{
+ char *start, *end;
+
+ start = flags;
+ while ((end = strchr(start, ' '))) {
+ *end = '\0';
+ if (strcmp(start, "not_armed") == 0)
+ dimm->flags.f_arm = 1;
+ else if (strcmp(start, "save_fail") == 0)
+ dimm->flags.f_save = 1;
+ else if (strcmp(start, "flush_fail") == 0)
+ dimm->flags.f_flush = 1;
+ else if (strcmp(start, "smart_notify") == 0)
+ dimm->flags.f_notify = 1;
+ start = end + 1;
+ }
+ if (end != start)
+ dbg(ndctl_dimm_get_ctx(dimm), "%s: %s\n",
+ ndctl_dimm_get_devname(dimm), flags);
+}
+
static void parse_dimm_flags(struct ndctl_dimm *dimm, char *flags)
{
char *start, *end;
@@ -1436,8 +1458,17 @@ static int add_of_pmem_dimm(struct ndctl_dimm *dimm, const char *dimm_base)
if (strcmp(buf, "ibm,pmemory") == 0) {
dimm->cmd_family = NVDIMM_FAMILY_PAPR_SCM;
rc = 0;
- goto out;
+ goto out_monitor;
}
+
+out_monitor:
+ /* read the flags and also allocate the monitor mode event_fd */
+ sprintf(path, "%s/papr_flags", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) == 0)
+ parse_of_pmem_flags(dimm, buf);
+
+ /* Allocate monitor mode fd */
+ dimm->health_eventfd = open(path, O_RDONLY|O_CLOEXEC);
out:
free(path);
return rc;
--
2.24.1
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
^ permalink raw reply related
* Re: [PATCH v2 31/42] KVM: s390: protvirt: Report CPU state to Ultravisor
From: David Hildenbrand @ 2020-02-20 10:52 UTC (permalink / raw)
To: Christian Borntraeger, Janosch Frank
Cc: KVM, Cornelia Huck, Thomas Huth, Ulrich Weigand, Claudio Imbrenda,
linux-s390, Michael Mueller, Vasily Gorbik, Janosch Frank
In-Reply-To: <95f7cd6a-c8d4-a119-d87e-7b25929e0b5c@de.ibm.com>
On 19.02.20 20:46, Christian Borntraeger wrote:
> I could add a comment to all other users of kvm_s390_vcpu_start/stop like
>
>
> /*
> * no need to check the return value of vcpu_stop as it can only have
> * an error for protvirt, but protvirt means user cpu state
> */
> if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm))
> kvm_s390_vcpu_stop(vcpu);
>
>
> to make clear why we do not check the return everywhere
>
Makes sense!
--
Thanks,
David / dhildenb
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.