Pull networking fixes from Paolo Abeni: "Quite unusually, this does not contains any fix coming from subtrees (nf, ebpf, wifi, etc). Current release - regressions: - bcmasp: fix possible OOB write in bcmasp_netfilt_get_all_active() Previous releases - regressions: - ipv4: fix one memleak in __inet_del_ifa() - tcp: fix bind() regressions for v4-mapped-v6 addresses. - tls: do not free tls_rec on async operation in bpf_exec_tx_verdict() - dsa: fixes for SJA1105 FDB regressions - veth: update XDP feature set when bringing up device - igb: fix hangup when enabling SR-IOV Previous releases - always broken: - kcm: fix memory leak in error path of kcm_sendmsg() - smc: fix data corruption in smcr_port_add - microchip: fix possible memory leak for vcap_dup_rule()" * tag 'net-6.6-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (37 commits) kcm: Fix error handling for SOCK_DGRAM in kcm_sendmsg(). net: renesas: rswitch: Add spin lock protection for irq {un}mask net: renesas: rswitch: Fix unmasking irq condition igb: clean up in all error paths when enabling SR-IOV ixgbe: fix timestamp configuration code selftest: tcp: Add v4-mapped-v6 cases in bind_wildcard.c. selftest: tcp: Move expected_errno into each test case in bind_wildcard.c. selftest: tcp: Fix address length in bind_wildcard.c. tcp: Fix bind() regression for v4-mapped-v6 non-wildcard address. tcp: Fix bind() regression for v4-mapped-v6 wildcard address. tcp: Factorise sk_family-independent comparison in inet_bind2_bucket_match(_addr_any). ipv6: fix ip6_sock_set_addr_preferences() typo veth: Update XDP feature set when bringing up device net: macb: fix sleep inside spinlock net/tls: do not free tls_rec on async operation in bpf_exec_tx_verdict() net: ethernet: mtk_eth_soc: fix pse_port configuration for MT7988 net: ethernet: mtk_eth_soc: fix uninitialized variable kcm: Fix memory leak in error path of kcm_sendmsg() r8152: check budget for r8152_poll() net: dsa: sja1105: block FDB accesses that are concurrent with a switch reset ...
Unified · Split
| @@ -266,6 +266,8 @@ struct sja1105_private { · 265 unmodified lines | ||
| 266 | 266 | * the switch doesn't confuse them with one another. |
| 267 | 267 | */ |
| 268 | 268 | struct mutex mgmt_lock; |
| 269 | + /* Serializes accesses to the FDB */ | |
| 270 | + struct mutex fdb_lock; | |
| 269 | 271 | /* PTP two-step TX timestamp ID, and its serialization lock */ |
| 270 | 272 | spinlock_t ts_id_lock; |
| 271 | 273 | u8 ts_id; |
| @@ -1175,18 +1175,15 @@ const struct sja1105_dynamic_table_ops sja1110_dyn_ops[BLK_IDX_MAX_DYN] = { · 1174 unmodified lines | ||
| 1175 | 1175 | |
| 1176 | 1176 | static int |
| 1177 | 1177 | sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, |
| 1178 | − struct sja1105_dyn_cmd *cmd, | |
| 1179 | − const struct sja1105_dynamic_table_ops *ops) | |
| 1178 | + const struct sja1105_dynamic_table_ops *ops, | |
| 1179 | + void *entry, bool check_valident, | |
| 1180 | + bool check_errors) | |
| 1180 | 1181 | { |
| 1181 | 1182 | u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {}; |
| 1183 | + struct sja1105_dyn_cmd cmd = {}; | |
| 1182 | 1184 | int rc; |
| 1183 | 1185 | |
| 1184 | − /* We don't _need_ to read the full entry, just the command area which | |
| 1185 | − * is a fixed SJA1105_SIZE_DYN_CMD. But our cmd_packing() API expects a | |
| 1186 | − * buffer that contains the full entry too. Additionally, our API | |
| 1187 | − * doesn't really know how many bytes into the buffer does the command | |
| 1188 | − * area really begin. So just read back the whole entry. | |
| 1189 | − */ | |
| 1186 | + /* Read back the whole entry + command structure. */ | |
| 1190 | 1187 | rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf, |
| 1191 | 1188 | ops->packed_size); |
| 1192 | 1189 | if (rc) |
| @@ -1195,11 +1192,25 @@ sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, · 2 unmodified lines | ||
| 1195 | 1192 | /* Unpack the command structure, and return it to the caller in case it |
| 1196 | 1193 | * needs to perform further checks on it (VALIDENT). |
| 1197 | 1194 | */ |
| 1198 | − memset(cmd, 0, sizeof(*cmd)); | |
| 1199 | − ops->cmd_packing(packed_buf, cmd, UNPACK); | |
| 1195 | + ops->cmd_packing(packed_buf, &cmd, UNPACK); | |
| 1200 | 1196 | |
| 1201 | 1197 | /* Hardware hasn't cleared VALID => still working on it */ |
| 1202 | − return cmd->valid ? -EAGAIN : 0; | |
| 1198 | + if (cmd.valid) | |
| 1199 | + return -EAGAIN; | |
| 1200 | + | |
| 1201 | + if (check_valident && !cmd.valident && !(ops->access & OP_VALID_ANYWAY)) | |
| 1202 | + return -ENOENT; | |
| 1203 | + | |
| 1204 | + if (check_errors && cmd.errors) | |
| 1205 | + return -EINVAL; | |
| 1206 | + | |
| 1207 | + /* Don't dereference possibly NULL pointer - maybe caller | |
| 1208 | + * only wanted to see whether the entry existed or not. | |
| 1209 | + */ | |
| 1210 | + if (entry) | |
| 1211 | + ops->entry_packing(packed_buf, entry, UNPACK); | |
| 1212 | + | |
| 1213 | + return 0; | |
| 1203 | 1214 | } |
| 1204 | 1215 | |
| 1205 | 1216 | /* Poll the dynamic config entry's control area until the hardware has |
| @@ -1208,16 +1219,19 @@ sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, · 2 unmodified lines | ||
| 1208 | 1219 | */ |
| 1209 | 1220 | static int |
| 1210 | 1221 | sja1105_dynamic_config_wait_complete(struct sja1105_private *priv, |
| 1211 | − struct sja1105_dyn_cmd *cmd, | |
| 1212 | − const struct sja1105_dynamic_table_ops *ops) | |
| 1222 | + const struct sja1105_dynamic_table_ops *ops, | |
| 1223 | + void *entry, bool check_valident, | |
| 1224 | + bool check_errors) | |
| 1213 | 1225 | { |
| 1214 | − int rc; | |
| 1215 | − | |
| 1216 | − return read_poll_timeout(sja1105_dynamic_config_poll_valid, | |
| 1217 | − rc, rc != -EAGAIN, | |
| 1218 | − SJA1105_DYNAMIC_CONFIG_SLEEP_US, | |
| 1219 | − SJA1105_DYNAMIC_CONFIG_TIMEOUT_US, | |
| 1220 | − false, priv, cmd, ops); | |
| 1226 | + int err, rc; | |
| 1227 | + | |
| 1228 | + err = read_poll_timeout(sja1105_dynamic_config_poll_valid, | |
| 1229 | + rc, rc != -EAGAIN, | |
| 1230 | + SJA1105_DYNAMIC_CONFIG_SLEEP_US, | |
| 1231 | + SJA1105_DYNAMIC_CONFIG_TIMEOUT_US, | |
| 1232 | + false, priv, ops, entry, check_valident, | |
| 1233 | + check_errors); | |
| 1234 | + return err < 0 ? err : rc; | |
| 1221 | 1235 | } |
| 1222 | 1236 | |
| 1223 | 1237 | /* Provides read access to the settings through the dynamic interface |
| @@ -1286,25 +1300,14 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv, · 62 unmodified lines | ||
| 1286 | 1300 | mutex_lock(&priv->dynamic_config_lock); |
| 1287 | 1301 | rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, |
| 1288 | 1302 | ops->packed_size); |
| 1289 | − if (rc < 0) { | |
| 1290 | − mutex_unlock(&priv->dynamic_config_lock); | |
| 1291 | − return rc; | |
| 1292 | − } | |
| 1293 | − | |
| 1294 | − rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops); | |
| 1295 | − mutex_unlock(&priv->dynamic_config_lock); | |
| 1296 | 1303 | if (rc < 0) |
| 1297 | − return rc; | |
| 1304 | + goto out; | |
| 1298 | 1305 | |
| 1299 | − if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY)) | |
| 1300 | − return -ENOENT; | |
| 1306 | + rc = sja1105_dynamic_config_wait_complete(priv, ops, entry, true, false); | |
| 1307 | +out: | |
| 1308 | + mutex_unlock(&priv->dynamic_config_lock); | |
| 1301 | 1309 | |
| 1302 | − /* Don't dereference possibly NULL pointer - maybe caller | |
| 1303 | − * only wanted to see whether the entry existed or not. | |
| 1304 | − */ | |
| 1305 | − if (entry) | |
| 1306 | − ops->entry_packing(packed_buf, entry, UNPACK); | |
| 1307 | − return 0; | |
| 1310 | + return rc; | |
| 1308 | 1311 | } |
| 1309 | 1312 | |
| 1310 | 1313 | int sja1105_dynamic_config_write(struct sja1105_private *priv, |
| @@ -1356,22 +1359,14 @@ int sja1105_dynamic_config_write(struct sja1105_private *priv, · 45 unmodified lines | ||
| 1356 | 1359 | mutex_lock(&priv->dynamic_config_lock); |
| 1357 | 1360 | rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, |
| 1358 | 1361 | ops->packed_size); |
| 1359 | − if (rc < 0) { | |
| 1360 | − mutex_unlock(&priv->dynamic_config_lock); | |
| 1361 | − return rc; | |
| 1362 | − } | |
| 1363 | − | |
| 1364 | − rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops); | |
| 1365 | − mutex_unlock(&priv->dynamic_config_lock); | |
| 1366 | 1362 | if (rc < 0) |
| 1367 | − return rc; | |
| 1363 | + goto out; | |
| 1368 | 1364 | |
| 1369 | − cmd = (struct sja1105_dyn_cmd) {0}; | |
| 1370 | − ops->cmd_packing(packed_buf, &cmd, UNPACK); | |
| 1371 | − if (cmd.errors) | |
| 1372 | − return -EINVAL; | |
| 1365 | + rc = sja1105_dynamic_config_wait_complete(priv, ops, NULL, false, true); | |
| 1366 | +out: | |
| 1367 | + mutex_unlock(&priv->dynamic_config_lock); | |
| 1373 | 1368 | |
| 1374 | − return 0; | |
| 1369 | + return rc; | |
| 1375 | 1370 | } |
| 1376 | 1371 | |
| 1377 | 1372 | static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly) |
| @@ -1798,6 +1798,7 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port, · 1797 unmodified lines | ||
| 1798 | 1798 | struct dsa_db db) |
| 1799 | 1799 | { |
| 1800 | 1800 | struct sja1105_private *priv = ds->priv; |
| 1801 | + int rc; | |
| 1801 | 1802 | |
| 1802 | 1803 | if (!vid) { |
| 1803 | 1804 | switch (db.type) { |
| @@ -1812,12 +1813,16 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port, · 8 unmodified lines | ||
| 1812 | 1813 | } |
| 1813 | 1814 | } |
| 1814 | 1815 | |
| 1815 | − return priv->info->fdb_add_cmd(ds, port, addr, vid); | |
| 1816 | + mutex_lock(&priv->fdb_lock); | |
| 1817 | + rc = priv->info->fdb_add_cmd(ds, port, addr, vid); | |
| 1818 | + mutex_unlock(&priv->fdb_lock); | |
| 1819 | + | |
| 1820 | + return rc; | |
| 1816 | 1821 | } |
| 1817 | 1822 | |
| 1818 | −static int sja1105_fdb_del(struct dsa_switch *ds, int port, | |
| 1819 | − const unsigned char *addr, u16 vid, | |
| 1820 | − struct dsa_db db) | |
| 1823 | +static int __sja1105_fdb_del(struct dsa_switch *ds, int port, | |
| 1824 | + const unsigned char *addr, u16 vid, | |
| 1825 | + struct dsa_db db) | |
| 1821 | 1826 | { |
| 1822 | 1827 | struct sja1105_private *priv = ds->priv; |
| 1823 | 1828 | |
| @@ -1837,6 +1842,20 @@ static int sja1105_fdb_del(struct dsa_switch *ds, int port, · 13 unmodified lines | ||
| 1837 | 1842 | return priv->info->fdb_del_cmd(ds, port, addr, vid); |
| 1838 | 1843 | } |
| 1839 | 1844 | |
| 1845 | +static int sja1105_fdb_del(struct dsa_switch *ds, int port, | |
| 1846 | + const unsigned char *addr, u16 vid, | |
| 1847 | + struct dsa_db db) | |
| 1848 | +{ | |
| 1849 | + struct sja1105_private *priv = ds->priv; | |
| 1850 | + int rc; | |
| 1851 | + | |
| 1852 | + mutex_lock(&priv->fdb_lock); | |
| 1853 | + rc = __sja1105_fdb_del(ds, port, addr, vid, db); | |
| 1854 | + mutex_unlock(&priv->fdb_lock); | |
| 1855 | + | |
| 1856 | + return rc; | |
| 1857 | +} | |
| 1858 | + | |
| 1840 | 1859 | static int sja1105_fdb_dump(struct dsa_switch *ds, int port, |
| 1841 | 1860 | dsa_fdb_dump_cb_t *cb, void *data) |
| 1842 | 1861 | { |
| @@ -1868,13 +1887,14 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port, · 25 unmodified lines | ||
| 1868 | 1887 | if (!(l2_lookup.destports & BIT(port))) |
| 1869 | 1888 | continue; |
| 1870 | 1889 | |
| 1871 | − /* We need to hide the FDB entry for unknown multicast */ | |
| 1872 | − if (l2_lookup.macaddr == SJA1105_UNKNOWN_MULTICAST && | |
| 1873 | − l2_lookup.mask_macaddr == SJA1105_UNKNOWN_MULTICAST) | |
| 1874 | − continue; | |
| 1875 | − | |
| 1876 | 1890 | u64_to_ether_addr(l2_lookup.macaddr, macaddr); |
| 1877 | 1891 | |
| 1892 | + /* Hardware FDB is shared for fdb and mdb, "bridge fdb show" | |
| 1893 | + * only wants to see unicast | |
| 1894 | + */ | |
| 1895 | + if (is_multicast_ether_addr(macaddr)) | |
| 1896 | + continue; | |
| 1897 | + | |
| 1878 | 1898 | /* We need to hide the dsa_8021q VLANs from the user. */ |
| 1879 | 1899 | if (vid_is_dsa_8021q(l2_lookup.vlanid)) |
| 1880 | 1900 | l2_lookup.vlanid = 0; |
| @@ -1898,6 +1918,8 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port) · 17 unmodified lines | ||
| 1898 | 1918 | }; |
| 1899 | 1919 | int i; |
| 1900 | 1920 | |
| 1921 | + mutex_lock(&priv->fdb_lock); | |
| 1922 | + | |
| 1901 | 1923 | for (i = 0; i < SJA1105_MAX_L2_LOOKUP_COUNT; i++) { |
| 1902 | 1924 | struct sja1105_l2_lookup_entry l2_lookup = {0}; |
| 1903 | 1925 | u8 macaddr[ETH_ALEN]; |
| @@ -1911,7 +1933,7 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port) · 7 unmodified lines | ||
| 1911 | 1933 | if (rc) { |
| 1912 | 1934 | dev_err(ds->dev, "Failed to read FDB: %pe\n", |
| 1913 | 1935 | ERR_PTR(rc)); |
| 1914 | − return; | |
| 1936 | + break; | |
| 1915 | 1937 | } |
| 1916 | 1938 | |
| 1917 | 1939 | if (!(l2_lookup.destports & BIT(port))) |
| @@ -1923,14 +1945,16 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port) · 5 unmodified lines | ||
| 1923 | 1945 | |
| 1924 | 1946 | u64_to_ether_addr(l2_lookup.macaddr, macaddr); |
| 1925 | 1947 | |
| 1926 | − rc = sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db); | |
| 1948 | + rc = __sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db); | |
| 1927 | 1949 | if (rc) { |
| 1928 | 1950 | dev_err(ds->dev, |
| 1929 | 1951 | "Failed to delete FDB entry %pM vid %lld: %pe\n", |
| 1930 | 1952 | macaddr, l2_lookup.vlanid, ERR_PTR(rc)); |
| 1931 | − return; | |
| 1953 | + break; | |
| 1932 | 1954 | } |
| 1933 | 1955 | } |
| 1956 | + | |
| 1957 | + mutex_unlock(&priv->fdb_lock); | |
| 1934 | 1958 | } |
| 1935 | 1959 | |
| 1936 | 1960 | static int sja1105_mdb_add(struct dsa_switch *ds, int port, |
| @@ -2273,6 +2297,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv, · 336 unmodified lines | ||
| 2273 | 2297 | int rc, i; |
| 2274 | 2298 | s64 now; |
| 2275 | 2299 | |
| 2300 | + mutex_lock(&priv->fdb_lock); | |
| 2276 | 2301 | mutex_lock(&priv->mgmt_lock); |
| 2277 | 2302 | |
| 2278 | 2303 | mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; |
| @@ -2385,6 +2410,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv, · 106 unmodified lines | ||
| 2385 | 2410 | goto out; |
| 2386 | 2411 | out: |
| 2387 | 2412 | mutex_unlock(&priv->mgmt_lock); |
| 2413 | + mutex_unlock(&priv->fdb_lock); | |
| 2388 | 2414 | |
| 2389 | 2415 | return rc; |
| 2390 | 2416 | } |
| @@ -2954,7 +2980,9 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to, · 563 unmodified lines | ||
| 2954 | 2980 | { |
| 2955 | 2981 | struct sja1105_l2_lookup_entry *l2_lookup; |
| 2956 | 2982 | struct sja1105_table *table; |
| 2957 | − int match; | |
| 2983 | + int match, rc; | |
| 2984 | + | |
| 2985 | + mutex_lock(&priv->fdb_lock); | |
| 2958 | 2986 | |
| 2959 | 2987 | table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; |
| 2960 | 2988 | l2_lookup = table->entries; |
| @@ -2967,7 +2995,8 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to, · 6 unmodified lines | ||
| 2967 | 2995 | if (match == table->entry_count) { |
| 2968 | 2996 | NL_SET_ERR_MSG_MOD(extack, |
| 2969 | 2997 | "Could not find FDB entry for unknown multicast"); |
| 2970 | − return -ENOSPC; | |
| 2998 | + rc = -ENOSPC; | |
| 2999 | + goto out; | |
| 2971 | 3000 | } |
| 2972 | 3001 | |
| 2973 | 3002 | if (flags.val & BR_MCAST_FLOOD) |
| @@ -2975,10 +3004,13 @@ static int sja1105_port_mcast_flood(struct sja1105_private *priv, int to, · 1 unmodified line | ||
| 2975 | 3004 | else |
| 2976 | 3005 | l2_lookup[match].destports &= ~BIT(to); |
| 2977 | 3006 | |
| 2978 | − return sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, | |
| 2979 | − l2_lookup[match].index, | |
| 2980 | − &l2_lookup[match], | |
| 2981 | − true); | |
| 3007 | + rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, | |
| 3008 | + l2_lookup[match].index, | |
| 3009 | + &l2_lookup[match], true); | |
| 3010 | +out: | |
| 3011 | + mutex_unlock(&priv->fdb_lock); | |
| 3012 | + | |
| 3013 | + return rc; | |
| 2982 | 3014 | } |
| 2983 | 3015 | |
| 2984 | 3016 | static int sja1105_port_pre_bridge_flags(struct dsa_switch *ds, int port, |
| @@ -3348,6 +3380,7 @@ static int sja1105_probe(struct spi_device *spi) · 363 unmodified lines | ||
| 3348 | 3380 | mutex_init(&priv->ptp_data.lock); |
| 3349 | 3381 | mutex_init(&priv->dynamic_config_lock); |
| 3350 | 3382 | mutex_init(&priv->mgmt_lock); |
| 3383 | + mutex_init(&priv->fdb_lock); | |
| 3351 | 3384 | spin_lock_init(&priv->ts_id_lock); |
| 3352 | 3385 | |
| 3353 | 3386 | rc = sja1105_parse_dt(priv); |
| @@ -1385,7 +1385,7 @@ static int adin1110_fdb_add(struct adin1110_port_priv *port_priv, · 1384 unmodified lines | ||
| 1385 | 1385 | return -ENOMEM; |
| 1386 | 1386 | |
| 1387 | 1387 | other_port = priv->ports[!port_priv->nr]; |
| 1388 | − port_rules = adin1110_port_rules(port_priv, false, true); | |
| 1388 | + port_rules = adin1110_port_rules(other_port, false, true); | |
| 1389 | 1389 | eth_broadcast_addr(mask); |
| 1390 | 1390 | |
| 1391 | 1391 | return adin1110_write_mac_address(other_port, mac_nr, (u8 *)fdb->addr, |
| @@ -528,13 +528,16 @@ void bcmasp_netfilt_suspend(struct bcmasp_intf *intf) · 527 unmodified lines | ||
| 528 | 528 | ASP_RX_FILTER_BLK_CTRL); |
| 529 | 529 | } |
| 530 | 530 | |
| 531 | −void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, | |
| 532 | − u32 *rule_cnt) | |
| 531 | +int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, | |
| 532 | + u32 *rule_cnt) | |
| 533 | 533 | { |
| 534 | 534 | struct bcmasp_priv *priv = intf->parent; |
| 535 | 535 | int j = 0, i; |
| 536 | 536 | |
| 537 | 537 | for (i = 0; i < NUM_NET_FILTERS; i++) { |
| 538 | + if (j == *rule_cnt) | |
| 539 | + return -EMSGSIZE; | |
| 540 | + | |
| 538 | 541 | if (!priv->net_filters[i].claimed || |
| 539 | 542 | priv->net_filters[i].port != intf->port) |
| 540 | 543 | continue; |
| @@ -548,6 +551,8 @@ void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, · 7 unmodified lines | ||
| 548 | 551 | } |
| 549 | 552 | |
| 550 | 553 | *rule_cnt = j; |
| 554 | + | |
| 555 | + return 0; | |
| 551 | 556 | } |
| 552 | 557 | |
| 553 | 558 | int bcmasp_netfilt_get_active(struct bcmasp_intf *intf) |
| @@ -1300,6 +1305,7 @@ static int bcmasp_probe(struct platform_device *pdev) · 746 unmodified lines | ||
| 1300 | 1305 | if (!intf) { |
| 1301 | 1306 | dev_err(dev, "Cannot create eth interface %d\n", i); |
| 1302 | 1307 | bcmasp_remove_intfs(priv); |
| 1308 | + of_node_put(intf_node); | |
| 1303 | 1309 | goto of_put_exit; |
| 1304 | 1310 | } |
| 1305 | 1311 | list_add_tail(&intf->list, &priv->intfs); |
| @@ -577,8 +577,8 @@ void bcmasp_netfilt_release(struct bcmasp_intf *intf, · 576 unmodified lines | ||
| 577 | 577 | |
| 578 | 578 | int bcmasp_netfilt_get_active(struct bcmasp_intf *intf); |
| 579 | 579 | |
| 580 | −void bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, | |
| 581 | − u32 *rule_cnt); | |
| 580 | +int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs, | |
| 581 | + u32 *rule_cnt); | |
| 582 | 582 | |
| 583 | 583 | void bcmasp_netfilt_suspend(struct bcmasp_intf *intf); |
| 584 | 584 | |
| @@ -335,7 +335,7 @@ static int bcmasp_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, · 334 unmodified lines | ||
| 335 | 335 | err = bcmasp_flow_get(intf, cmd); |
| 336 | 336 | break; |
| 337 | 337 | case ETHTOOL_GRXCLSRLALL: |
| 338 | − bcmasp_netfilt_get_all_active(intf, rule_locs, &cmd->rule_cnt); | |
| 338 | + err = bcmasp_netfilt_get_all_active(intf, rule_locs, &cmd->rule_cnt); | |
| 339 | 339 | cmd->data = NUM_NET_FILTERS; |
| 340 | 340 | break; |
| 341 | 341 | default: |
| @@ -756,8 +756,6 @@ static void macb_mac_link_up(struct phylink_config *config, · 755 unmodified lines | ||
| 756 | 756 | if (rx_pause) |
| 757 | 757 | ctrl |= MACB_BIT(PAE); |
| 758 | 758 | |
| 759 | − macb_set_tx_clk(bp, speed); | |
| 760 | − | |
| 761 | 759 | /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down |
| 762 | 760 | * cleared the pipeline and control registers. |
| 763 | 761 | */ |
| @@ -777,6 +775,9 @@ static void macb_mac_link_up(struct phylink_config *config, · 13 unmodified lines | ||
| 777 | 775 | |
| 778 | 776 | spin_unlock_irqrestore(&bp->lock, flags); |
| 779 | 777 | |
| 778 | + if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) | |
| 779 | + macb_set_tx_clk(bp, speed); | |
| 780 | + | |
| 780 | 781 | /* Enable Rx and Tx; Enable PTP unicast */ |
| 781 | 782 | ctrl = macb_readl(bp, NCR); |
| 782 | 783 | if (gem_has_ptp(bp)) |
| @@ -3827,8 +3827,11 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs, bool reinit) · 3826 unmodified lines | ||
| 3827 | 3827 | } |
| 3828 | 3828 | |
| 3829 | 3829 | /* only call pci_enable_sriov() if no VFs are allocated already */ |
| 3830 | − if (!old_vfs) | |
| 3830 | + if (!old_vfs) { | |
| 3831 | 3831 | err = pci_enable_sriov(pdev, adapter->vfs_allocated_count); |
| 3832 | + if (err) | |
| 3833 | + goto err_out; | |
| 3834 | + } | |
| 3832 | 3835 | |
| 3833 | 3836 | goto out; |
| 3834 | 3837 | |
| @@ -979,6 +979,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 978 unmodified lines | ||
| 979 | 979 | u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED; |
| 980 | 980 | u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED; |
| 981 | 981 | u32 tsync_rx_mtrl = PTP_EV_PORT << 16; |
| 982 | + u32 aflags = adapter->flags; | |
| 982 | 983 | bool is_l2 = false; |
| 983 | 984 | u32 regval; |
| 984 | 985 | |
| @@ -996,20 +997,20 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 11 unmodified lines | ||
| 996 | 997 | case HWTSTAMP_FILTER_NONE: |
| 997 | 998 | tsync_rx_ctl = 0; |
| 998 | 999 | tsync_rx_mtrl = 0; |
| 999 | − adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | |
| 1000 | − IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | |
| 1000 | + aflags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | |
| 1001 | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | |
| 1001 | 1002 | break; |
| 1002 | 1003 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: |
| 1003 | 1004 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; |
| 1004 | 1005 | tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG; |
| 1005 | − adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | |
| 1006 | − IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | |
| 1006 | + aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | |
| 1007 | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | |
| 1007 | 1008 | break; |
| 1008 | 1009 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: |
| 1009 | 1010 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; |
| 1010 | 1011 | tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG; |
| 1011 | − adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | |
| 1012 | − IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | |
| 1012 | + aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | |
| 1013 | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | |
| 1013 | 1014 | break; |
| 1014 | 1015 | case HWTSTAMP_FILTER_PTP_V2_EVENT: |
| 1015 | 1016 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: |
| @@ -1023,8 +1024,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 7 unmodified lines | ||
| 1023 | 1024 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; |
| 1024 | 1025 | is_l2 = true; |
| 1025 | 1026 | config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; |
| 1026 | − adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | |
| 1027 | − IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | |
| 1027 | + aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | |
| 1028 | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | |
| 1028 | 1029 | break; |
| 1029 | 1030 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: |
| 1030 | 1031 | case HWTSTAMP_FILTER_NTP_ALL: |
| @@ -1035,7 +1036,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 4 unmodified lines | ||
| 1035 | 1036 | if (hw->mac.type >= ixgbe_mac_X550) { |
| 1036 | 1037 | tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL; |
| 1037 | 1038 | config->rx_filter = HWTSTAMP_FILTER_ALL; |
| 1038 | − adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; | |
| 1039 | + aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; | |
| 1039 | 1040 | break; |
| 1040 | 1041 | } |
| 1041 | 1042 | fallthrough; |
| @@ -1046,8 +1047,6 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 4 unmodified lines | ||
| 1046 | 1047 | * Delay_Req messages and hardware does not support |
| 1047 | 1048 | * timestamping all packets => return error |
| 1048 | 1049 | */ |
| 1049 | − adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | | |
| 1050 | − IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); | |
| 1051 | 1050 | config->rx_filter = HWTSTAMP_FILTER_NONE; |
| 1052 | 1051 | return -ERANGE; |
| 1053 | 1052 | } |
| @@ -1079,8 +1078,8 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 25 unmodified lines | ||
| 1079 | 1078 | IXGBE_TSYNCRXCTL_TYPE_ALL | |
| 1080 | 1079 | IXGBE_TSYNCRXCTL_TSIP_UT_EN; |
| 1081 | 1080 | config->rx_filter = HWTSTAMP_FILTER_ALL; |
| 1082 | − adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; | |
| 1083 | − adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; | |
| 1081 | + aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; | |
| 1082 | + aflags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; | |
| 1084 | 1083 | is_l2 = true; |
| 1085 | 1084 | break; |
| 1086 | 1085 | default: |
| @@ -1113,6 +1112,9 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, · 26 unmodified lines | ||
| 1113 | 1112 | |
| 1114 | 1113 | IXGBE_WRITE_FLUSH(hw); |
| 1115 | 1114 | |
| 1115 | + /* configure adapter flags only when HW is actually configured */ | |
| 1116 | + adapter->flags = aflags; | |
| 1117 | + | |
| 1116 | 1118 | /* clear TX/RX time stamp registers, just to be sure */ |
| 1117 | 1119 | ixgbe_ptp_clear_tx_timestamp(adapter); |
| 1118 | 1120 | IXGBE_READ_REG(hw, IXGBE_RXSTMPH); |
| @@ -5586,6 +5586,11 @@ static int mvpp2_ethtool_get_rxnfc(struct net_device *dev, · 5585 unmodified lines | ||
| 5586 | 5586 | break; |
| 5587 | 5587 | case ETHTOOL_GRXCLSRLALL: |
| 5588 | 5588 | for (i = 0; i < MVPP2_N_RFS_ENTRIES_PER_FLOW; i++) { |
| 5589 | + if (loc == info->rule_cnt) { | |
| 5590 | + ret = -EMSGSIZE; | |
| 5591 | + break; | |
| 5592 | + } | |
| 5593 | + | |
| 5589 | 5594 | if (port->rfs_rules[i]) |
| 5590 | 5595 | rules[loc++] = i; |
| 5591 | 5596 | } |
| @@ -107,12 +107,13 @@ int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura) · 106 unmodified lines | ||
| 107 | 107 | } |
| 108 | 108 | |
| 109 | 109 | #define NPA_MAX_BURST 16 |
| 110 | −void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) | |
| 110 | +int cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) | |
| 111 | 111 | { |
| 112 | 112 | struct otx2_nic *pfvf = dev; |
| 113 | + int cnt = cq->pool_ptrs; | |
| 113 | 114 | u64 ptrs[NPA_MAX_BURST]; |
| 114 | − int num_ptrs = 1; | |
| 115 | 115 | dma_addr_t bufptr; |
| 116 | + int num_ptrs = 1; | |
| 116 | 117 | |
| 117 | 118 | /* Refill pool with new buffers */ |
| 118 | 119 | while (cq->pool_ptrs) { |
| @@ -131,6 +132,7 @@ void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) · 12 unmodified lines | ||
| 131 | 132 | num_ptrs = 1; |
| 132 | 133 | } |
| 133 | 134 | } |
| 135 | + return cnt - cq->pool_ptrs; | |
| 134 | 136 | } |
| 135 | 137 | |
| 136 | 138 | void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx) |
| @@ -24,7 +24,7 @@ static inline int mtu_to_dwrr_weight(struct otx2_nic *pfvf, int mtu) · 23 unmodified lines | ||
| 24 | 24 | return weight; |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | −void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); | |
| 27 | +int cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); | |
| 28 | 28 | void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx); |
| 29 | 29 | int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura); |
| 30 | 30 | int cn10k_lmtst_init(struct otx2_nic *pfvf); |
| @@ -574,20 +574,8 @@ int otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, · 573 unmodified lines | ||
| 574 | 574 | int otx2_alloc_buffer(struct otx2_nic *pfvf, struct otx2_cq_queue *cq, |
| 575 | 575 | dma_addr_t *dma) |
| 576 | 576 | { |
| 577 | − if (unlikely(__otx2_alloc_rbuf(pfvf, cq->rbpool, dma))) { | |
| 578 | − struct refill_work *work; | |
| 579 | − struct delayed_work *dwork; | |
| 580 | − | |
| 581 | − work = &pfvf->refill_wrk[cq->cq_idx]; | |
| 582 | − dwork = &work->pool_refill_work; | |
| 583 | − /* Schedule a task if no other task is running */ | |
| 584 | − if (!cq->refill_task_sched) { | |
| 585 | − cq->refill_task_sched = true; | |
| 586 | − schedule_delayed_work(dwork, | |
| 587 | − msecs_to_jiffies(100)); | |
| 588 | − } | |
| 577 | + if (unlikely(__otx2_alloc_rbuf(pfvf, cq->rbpool, dma))) | |
| 589 | 578 | return -ENOMEM; |
| 590 | − } | |
| 591 | 579 | return 0; |
| 592 | 580 | } |
| 593 | 581 | |
| @@ -1082,39 +1070,20 @@ static int otx2_cq_init(struct otx2_nic *pfvf, u16 qidx) · 488 unmodified lines | ||
| 1082 | 1070 | static void otx2_pool_refill_task(struct work_struct *work) |
| 1083 | 1071 | { |
| 1084 | 1072 | struct otx2_cq_queue *cq; |
| 1085 | − struct otx2_pool *rbpool; | |
| 1086 | 1073 | struct refill_work *wrk; |
| 1087 | − int qidx, free_ptrs = 0; | |
| 1088 | 1074 | struct otx2_nic *pfvf; |
| 1089 | − dma_addr_t bufptr; | |
| 1075 | + int qidx; | |
| 1090 | 1076 | |
| 1091 | 1077 | wrk = container_of(work, struct refill_work, pool_refill_work.work); |
| 1092 | 1078 | pfvf = wrk->pf; |
| 1093 | 1079 | qidx = wrk - pfvf->refill_wrk; |
| 1094 | 1080 | cq = &pfvf->qset.cq[qidx]; |
| 1095 | − rbpool = cq->rbpool; | |
| 1096 | − free_ptrs = cq->pool_ptrs; | |
| 1097 | 1081 | |
| 1098 | − while (cq->pool_ptrs) { | |
| 1099 | − if (otx2_alloc_rbuf(pfvf, rbpool, &bufptr)) { | |
| 1100 | − /* Schedule a WQ if we fails to free atleast half of the | |
| 1101 | − * pointers else enable napi for this RQ. | |
| 1102 | − */ | |
| 1103 | − if (!((free_ptrs - cq->pool_ptrs) > free_ptrs / 2)) { | |
| 1104 | − struct delayed_work *dwork; | |
| 1105 | − | |
| 1106 | − dwork = &wrk->pool_refill_work; | |
| 1107 | − schedule_delayed_work(dwork, | |
| 1108 | − msecs_to_jiffies(100)); | |
| 1109 | − } else { | |
| 1110 | − cq->refill_task_sched = false; | |
| 1111 | − } | |
| 1112 | − return; | |
| 1113 | − } | |
| 1114 | − pfvf->hw_ops->aura_freeptr(pfvf, qidx, bufptr + OTX2_HEAD_ROOM); | |
| 1115 | − cq->pool_ptrs--; | |
| 1116 | − } | |
| 1117 | 1082 | cq->refill_task_sched = false; |
| 1083 | + | |
| 1084 | + local_bh_disable(); | |
| 1085 | + napi_schedule(wrk->napi); | |
| 1086 | + local_bh_enable(); | |
| 1118 | 1087 | } |
| 1119 | 1088 | |
| 1120 | 1089 | int otx2_config_nix_queues(struct otx2_nic *pfvf) |
| @@ -302,6 +302,7 @@ struct flr_work { · 301 unmodified lines | ||
| 302 | 302 | struct refill_work { |
| 303 | 303 | struct delayed_work pool_refill_work; |
| 304 | 304 | struct otx2_nic *pf; |
| 305 | + struct napi_struct *napi; | |
| 305 | 306 | }; |
| 306 | 307 | |
| 307 | 308 | /* PTPv2 originTimestamp structure */ |
| @@ -370,7 +371,7 @@ struct dev_hw_ops { · 62 unmodified lines | ||
| 370 | 371 | int (*sq_aq_init)(void *dev, u16 qidx, u16 sqb_aura); |
| 371 | 372 | void (*sqe_flush)(void *dev, struct otx2_snd_queue *sq, |
| 372 | 373 | int size, int qidx); |
| 373 | − void (*refill_pool_ptrs)(void *dev, struct otx2_cq_queue *cq); | |
| 374 | + int (*refill_pool_ptrs)(void *dev, struct otx2_cq_queue *cq); | |
| 374 | 375 | void (*aura_freeptr)(void *dev, int aura, u64 buf); |
| 375 | 376 | }; |
| 376 | 377 | |
| @@ -1943,6 +1943,10 @@ int otx2_stop(struct net_device *netdev) · 1942 unmodified lines | ||
| 1943 | 1943 | |
| 1944 | 1944 | netif_tx_disable(netdev); |
| 1945 | 1945 | |
| 1946 | + for (wrk = 0; wrk < pf->qset.cq_cnt; wrk++) | |
| 1947 | + cancel_delayed_work_sync(&pf->refill_wrk[wrk].pool_refill_work); | |
| 1948 | + devm_kfree(pf->dev, pf->refill_wrk); | |
| 1949 | + | |
| 1946 | 1950 | otx2_free_hw_resources(pf); |
| 1947 | 1951 | otx2_free_cints(pf, pf->hw.cint_cnt); |
| 1948 | 1952 | otx2_disable_napi(pf); |
| @@ -1950,9 +1954,6 @@ int otx2_stop(struct net_device *netdev) · 1 unmodified line | ||
| 1950 | 1954 | for (qidx = 0; qidx < netdev->num_tx_queues; qidx++) |
| 1951 | 1955 | netdev_tx_reset_queue(netdev_get_tx_queue(netdev, qidx)); |
| 1952 | 1956 | |
| 1953 | − for (wrk = 0; wrk < pf->qset.cq_cnt; wrk++) | |
| 1954 | − cancel_delayed_work_sync(&pf->refill_wrk[wrk].pool_refill_work); | |
| 1955 | − devm_kfree(pf->dev, pf->refill_wrk); | |
| 1956 | 1957 | |
| 1957 | 1958 | kfree(qset->sq); |
| 1958 | 1959 | kfree(qset->cq); |
| @@ -424,9 +424,10 @@ process_cqe: · 423 unmodified lines | ||
| 424 | 424 | return processed_cqe; |
| 425 | 425 | } |
| 426 | 426 | |
| 427 | −void otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) | |
| 427 | +int otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) | |
| 428 | 428 | { |
| 429 | 429 | struct otx2_nic *pfvf = dev; |
| 430 | + int cnt = cq->pool_ptrs; | |
| 430 | 431 | dma_addr_t bufptr; |
| 431 | 432 | |
| 432 | 433 | while (cq->pool_ptrs) { |
| @@ -435,6 +436,8 @@ void otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq) · 2 unmodified lines | ||
| 435 | 436 | otx2_aura_freeptr(pfvf, cq->cq_idx, bufptr + OTX2_HEAD_ROOM); |
| 436 | 437 | cq->pool_ptrs--; |
| 437 | 438 | } |
| 439 | + | |
| 440 | + return cnt - cq->pool_ptrs; | |
| 438 | 441 | } |
| 439 | 442 | |
| 440 | 443 | static int otx2_tx_napi_handler(struct otx2_nic *pfvf, |
| @@ -521,6 +524,7 @@ int otx2_napi_handler(struct napi_struct *napi, int budget) · 80 unmodified lines | ||
| 521 | 524 | struct otx2_cq_queue *cq; |
| 522 | 525 | struct otx2_qset *qset; |
| 523 | 526 | struct otx2_nic *pfvf; |
| 527 | + int filled_cnt = -1; | |
| 524 | 528 | |
| 525 | 529 | cq_poll = container_of(napi, struct otx2_cq_poll, napi); |
| 526 | 530 | pfvf = (struct otx2_nic *)cq_poll->dev; |
| @@ -541,7 +545,7 @@ int otx2_napi_handler(struct napi_struct *napi, int budget) · 14 unmodified lines | ||
| 541 | 545 | } |
| 542 | 546 | |
| 543 | 547 | if (rx_cq && rx_cq->pool_ptrs) |
| 544 | − pfvf->hw_ops->refill_pool_ptrs(pfvf, rx_cq); | |
| 548 | + filled_cnt = pfvf->hw_ops->refill_pool_ptrs(pfvf, rx_cq); | |
| 545 | 549 | /* Clear the IRQ */ |
| 546 | 550 | otx2_write64(pfvf, NIX_LF_CINTX_INT(cq_poll->cint_idx), BIT_ULL(0)); |
| 547 | 551 | |
| @@ -561,9 +565,25 @@ int otx2_napi_handler(struct napi_struct *napi, int budget) · 13 unmodified lines | ||
| 561 | 565 | otx2_config_irq_coalescing(pfvf, i); |
| 562 | 566 | } |
| 563 | 567 | |
| 564 | − /* Re-enable interrupts */ | |
| 565 | − otx2_write64(pfvf, NIX_LF_CINTX_ENA_W1S(cq_poll->cint_idx), | |
| 566 | − BIT_ULL(0)); | |
| 568 | + if (unlikely(!filled_cnt)) { | |
| 569 | + struct refill_work *work; | |
| 570 | + struct delayed_work *dwork; | |
| 571 | + | |
| 572 | + work = &pfvf->refill_wrk[cq->cq_idx]; | |
| 573 | + dwork = &work->pool_refill_work; | |
| 574 | + /* Schedule a task if no other task is running */ | |
| 575 | + if (!cq->refill_task_sched) { | |
| 576 | + work->napi = napi; | |
| 577 | + cq->refill_task_sched = true; | |
| 578 | + schedule_delayed_work(dwork, | |
| 579 | + msecs_to_jiffies(100)); | |
| 580 | + } | |
| 581 | + } else { | |
| 582 | + /* Re-enable interrupts */ | |
| 583 | + otx2_write64(pfvf, | |
| 584 | + NIX_LF_CINTX_ENA_W1S(cq_poll->cint_idx), | |
| 585 | + BIT_ULL(0)); | |
| 586 | + } | |
| 567 | 587 | } |
| 568 | 588 | return workdone; |
| 569 | 589 | } |
| @@ -170,6 +170,6 @@ void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, · 169 unmodified lines | ||
| 170 | 170 | int size, int qidx); |
| 171 | 171 | void otx2_sqe_flush(void *dev, struct otx2_snd_queue *sq, |
| 172 | 172 | int size, int qidx); |
| 173 | −void otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); | |
| 174 | −void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); | |
| 173 | +int otx2_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); | |
| 174 | +int cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); | |
| 175 | 175 | #endif /* OTX2_TXRX_H */ |
| @@ -2005,11 +2005,11 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, · 2004 unmodified lines | ||
| 2005 | 2005 | u8 *data, *new_data; |
| 2006 | 2006 | struct mtk_rx_dma_v2 *rxd, trxd; |
| 2007 | 2007 | int done = 0, bytes = 0; |
| 2008 | + dma_addr_t dma_addr = DMA_MAPPING_ERROR; | |
| 2008 | 2009 | |
| 2009 | 2010 | while (done < budget) { |
| 2010 | 2011 | unsigned int pktlen, *rxdcsum; |
| 2011 | 2012 | struct net_device *netdev; |
| 2012 | − dma_addr_t dma_addr; | |
| 2013 | 2013 | u32 hash, reason; |
| 2014 | 2014 | int mac = 0; |
| 2015 | 2015 | |
| @@ -2186,7 +2186,8 @@ release_desc: · 170 unmodified lines | ||
| 2186 | 2186 | else |
| 2187 | 2187 | rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); |
| 2188 | 2188 | |
| 2189 | − if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) | |
| 2189 | + if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA) && | |
| 2190 | + likely(dma_addr != DMA_MAPPING_ERROR)) | |
| 2190 | 2191 | rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); |
| 2191 | 2192 | |
| 2192 | 2193 | ring->calc_idx = idx; |
| @@ -2994,6 +2995,9 @@ static int mtk_hwlro_get_fdir_all(struct net_device *dev, · 801 unmodified lines | ||
| 2994 | 2995 | int i; |
| 2995 | 2996 | |
| 2996 | 2997 | for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) { |
| 2998 | + if (cnt == cmd->rule_cnt) | |
| 2999 | + return -EMSGSIZE; | |
| 3000 | + | |
| 2997 | 3001 | if (mac->hwlro_ip[i]) { |
| 2998 | 3002 | rule_locs[cnt] = i; |
| 2999 | 3003 | cnt++; |
| @@ -214,9 +214,11 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe, · 213 unmodified lines | ||
| 214 | 214 | dsa_port = mtk_flow_get_dsa_port(&dev); |
| 215 | 215 | |
| 216 | 216 | if (dev == eth->netdev[0]) |
| 217 | − pse_port = 1; | |
| 217 | + pse_port = PSE_GDM1_PORT; | |
| 218 | 218 | else if (dev == eth->netdev[1]) |
| 219 | − pse_port = 2; | |
| 219 | + pse_port = PSE_GDM2_PORT; | |
| 220 | + else if (dev == eth->netdev[2]) | |
| 221 | + pse_port = PSE_GDM3_PORT; | |
| 220 | 222 | else |
| 221 | 223 | return -EOPNOTSUPP; |
| 222 | 224 | |
| @@ -1021,18 +1021,32 @@ static struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri, · 1020 unmodified lines | ||
| 1021 | 1021 | list_for_each_entry(ckf, &ri->data.keyfields, ctrl.list) { |
| 1022 | 1022 | newckf = kmemdup(ckf, sizeof(*newckf), GFP_KERNEL); |
| 1023 | 1023 | if (!newckf) |
| 1024 | − return ERR_PTR(-ENOMEM); | |
| 1024 | + goto err; | |
| 1025 | 1025 | list_add_tail(&newckf->ctrl.list, &duprule->data.keyfields); |
| 1026 | 1026 | } |
| 1027 | 1027 | |
| 1028 | 1028 | list_for_each_entry(caf, &ri->data.actionfields, ctrl.list) { |
| 1029 | 1029 | newcaf = kmemdup(caf, sizeof(*newcaf), GFP_KERNEL); |
| 1030 | 1030 | if (!newcaf) |
| 1031 | − return ERR_PTR(-ENOMEM); | |
| 1031 | + goto err; | |
| 1032 | 1032 | list_add_tail(&newcaf->ctrl.list, &duprule->data.actionfields); |
| 1033 | 1033 | } |
| 1034 | 1034 | |
| 1035 | 1035 | return duprule; |
| 1036 | + | |
| 1037 | +err: | |
| 1038 | + list_for_each_entry_safe(ckf, newckf, &duprule->data.keyfields, ctrl.list) { | |
| 1039 | + list_del(&ckf->ctrl.list); | |
| 1040 | + kfree(ckf); | |
| 1041 | + } | |
| 1042 | + | |
| 1043 | + list_for_each_entry_safe(caf, newcaf, &duprule->data.actionfields, ctrl.list) { | |
| 1044 | + list_del(&caf->ctrl.list); | |
| 1045 | + kfree(caf); | |
| 1046 | + } | |
| 1047 | + | |
| 1048 | + kfree(duprule); | |
| 1049 | + return ERR_PTR(-ENOMEM); | |
| 1036 | 1050 | } |
| 1037 | 1051 | |
| 1038 | 1052 | static void vcap_apply_width(u8 *dst, int width, int bytes) |
| @@ -799,6 +799,7 @@ static int rswitch_poll(struct napi_struct *napi, int budget) · 798 unmodified lines | ||
| 799 | 799 | struct net_device *ndev = napi->dev; |
| 800 | 800 | struct rswitch_private *priv; |
| 801 | 801 | struct rswitch_device *rdev; |
| 802 | + unsigned long flags; | |
| 802 | 803 | int quota = budget; |
| 803 | 804 | |
| 804 | 805 | rdev = netdev_priv(ndev); |
| @@ -816,10 +817,12 @@ retry: · 11 unmodified lines | ||
| 816 | 817 | |
| 817 | 818 | netif_wake_subqueue(ndev, 0); |
| 818 | 819 | |
| 819 | − napi_complete(napi); | |
| 820 | − | |
| 821 | − rswitch_enadis_data_irq(priv, rdev->tx_queue->index, true); | |
| 822 | − rswitch_enadis_data_irq(priv, rdev->rx_queue->index, true); | |
| 820 | + if (napi_complete_done(napi, budget - quota)) { | |
| 821 | + spin_lock_irqsave(&priv->lock, flags); | |
| 822 | + rswitch_enadis_data_irq(priv, rdev->tx_queue->index, true); | |
| 823 | + rswitch_enadis_data_irq(priv, rdev->rx_queue->index, true); | |
| 824 | + spin_unlock_irqrestore(&priv->lock, flags); | |
| 825 | + } | |
| 823 | 826 | |
| 824 | 827 | out: |
| 825 | 828 | return budget - quota; |
| @@ -835,8 +838,10 @@ static void rswitch_queue_interrupt(struct net_device *ndev) · 9 unmodified lines | ||
| 835 | 838 | struct rswitch_device *rdev = netdev_priv(ndev); |
| 836 | 839 | |
| 837 | 840 | if (napi_schedule_prep(&rdev->napi)) { |
| 841 | + spin_lock(&rdev->priv->lock); | |
| 838 | 842 | rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, false); |
| 839 | 843 | rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, false); |
| 844 | + spin_unlock(&rdev->priv->lock); | |
| 840 | 845 | __napi_schedule(&rdev->napi); |
| 841 | 846 | } |
| 842 | 847 | } |
| @@ -1440,14 +1445,17 @@ static void rswitch_ether_port_deinit_all(struct rswitch_private *priv) · 597 unmodified lines | ||
| 1440 | 1445 | static int rswitch_open(struct net_device *ndev) |
| 1441 | 1446 | { |
| 1442 | 1447 | struct rswitch_device *rdev = netdev_priv(ndev); |
| 1448 | + unsigned long flags; | |
| 1443 | 1449 | |
| 1444 | 1450 | phy_start(ndev->phydev); |
| 1445 | 1451 | |
| 1446 | 1452 | napi_enable(&rdev->napi); |
| 1447 | 1453 | netif_start_queue(ndev); |
| 1448 | 1454 | |
| 1455 | + spin_lock_irqsave(&rdev->priv->lock, flags); | |
| 1449 | 1456 | rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, true); |
| 1450 | 1457 | rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, true); |
| 1458 | + spin_unlock_irqrestore(&rdev->priv->lock, flags); | |
| 1451 | 1459 | |
| 1452 | 1460 | if (bitmap_empty(rdev->priv->opened_ports, RSWITCH_NUM_PORTS)) |
| 1453 | 1461 | iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDIE); |
| @@ -1461,6 +1469,7 @@ static int rswitch_stop(struct net_device *ndev) · 7 unmodified lines | ||
| 1461 | 1469 | { |
| 1462 | 1470 | struct rswitch_device *rdev = netdev_priv(ndev); |
| 1463 | 1471 | struct rswitch_gwca_ts_info *ts_info, *ts_info2; |
| 1472 | + unsigned long flags; | |
| 1464 | 1473 | |
| 1465 | 1474 | netif_tx_stop_all_queues(ndev); |
| 1466 | 1475 | bitmap_clear(rdev->priv->opened_ports, rdev->port, 1); |
| @@ -1476,8 +1485,10 @@ static int rswitch_stop(struct net_device *ndev) · 9 unmodified lines | ||
| 1476 | 1485 | kfree(ts_info); |
| 1477 | 1486 | } |
| 1478 | 1487 | |
| 1488 | + spin_lock_irqsave(&rdev->priv->lock, flags); | |
| 1479 | 1489 | rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, false); |
| 1480 | 1490 | rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, false); |
| 1491 | + spin_unlock_irqrestore(&rdev->priv->lock, flags); | |
| 1481 | 1492 | |
| 1482 | 1493 | phy_stop(ndev->phydev); |
| 1483 | 1494 | napi_disable(&rdev->napi); |
| @@ -1887,6 +1898,7 @@ static int renesas_eth_sw_probe(struct platform_device *pdev) · 403 unmodified lines | ||
| 1887 | 1898 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
| 1888 | 1899 | if (!priv) |
| 1889 | 1900 | return -ENOMEM; |
| 1901 | + spin_lock_init(&priv->lock); | |
| 1890 | 1902 | |
| 1891 | 1903 | attr = soc_device_match(rswitch_soc_no_speed_change); |
| 1892 | 1904 | if (attr) |
| @@ -1011,6 +1011,8 @@ struct rswitch_private { · 1010 unmodified lines | ||
| 1011 | 1011 | struct rswitch_etha etha[RSWITCH_NUM_PORTS]; |
| 1012 | 1012 | struct rswitch_mfwd mfwd; |
| 1013 | 1013 | |
| 1014 | + spinlock_t lock; /* lock interrupt registers' control */ | |
| 1015 | + | |
| 1014 | 1016 | bool etha_no_runtime_change; |
| 1015 | 1017 | bool gwca_halt; |
| 1016 | 1018 | }; |
| @@ -2704,9 +2704,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) · 2703 unmodified lines | ||
| 2704 | 2704 | |
| 2705 | 2705 | /* We still have pending packets, let's call for a new scheduling */ |
| 2706 | 2706 | if (tx_q->dirty_tx != tx_q->cur_tx) |
| 2707 | − hrtimer_start(&tx_q->txtimer, | |
| 2708 | − STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), | |
| 2709 | − HRTIMER_MODE_REL); | |
| 2707 | + stmmac_tx_timer_arm(priv, queue); | |
| 2710 | 2708 | |
| 2711 | 2709 | flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp); |
| 2712 | 2710 | tx_q->txq_stats.tx_packets += tx_packets; |
| @@ -2995,9 +2993,13 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) · 282 unmodified lines | ||
| 2995 | 2993 | static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue) |
| 2996 | 2994 | { |
| 2997 | 2995 | struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; |
| 2996 | + u32 tx_coal_timer = priv->tx_coal_timer[queue]; | |
| 2997 | + | |
| 2998 | + if (!tx_coal_timer) | |
| 2999 | + return; | |
| 2998 | 3000 | |
| 2999 | 3001 | hrtimer_start(&tx_q->txtimer, |
| 3000 | − STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), | |
| 3002 | + STMMAC_COAL_TIMER(tx_coal_timer), | |
| 3001 | 3003 | HRTIMER_MODE_REL); |
| 3002 | 3004 | } |
| 3003 | 3005 | |
| @@ -2636,6 +2636,9 @@ static int r8152_poll(struct napi_struct *napi, int budget) · 2635 unmodified lines | ||
| 2636 | 2636 | struct r8152 *tp = container_of(napi, struct r8152, napi); |
| 2637 | 2637 | int work_done; |
| 2638 | 2638 | |
| 2639 | + if (!budget) | |
| 2640 | + return 0; | |
| 2641 | + | |
| 2639 | 2642 | work_done = rx_bottom(tp, budget); |
| 2640 | 2643 | |
| 2641 | 2644 | if (work_done < budget) { |
| @@ -1446,6 +1446,8 @@ static int veth_open(struct net_device *dev) · 1445 unmodified lines | ||
| 1446 | 1446 | netif_carrier_on(peer); |
| 1447 | 1447 | } |
| 1448 | 1448 | |
| 1449 | + veth_set_xdp_features(dev); | |
| 1450 | + | |
| 1449 | 1451 | return 0; |
| 1450 | 1452 | } |
| 1451 | 1453 | |
| @@ -784,6 +784,11 @@ static inline bool ipv6_addr_v4mapped(const struct in6_addr *a) · 783 unmodified lines | ||
| 784 | 784 | cpu_to_be32(0x0000ffff))) == 0UL; |
| 785 | 785 | } |
| 786 | 786 | |
| 787 | +static inline bool ipv6_addr_v4mapped_any(const struct in6_addr *a) | |
| 788 | +{ | |
| 789 | + return ipv6_addr_v4mapped(a) && ipv4_is_zeronet(a->s6_addr32[3]); | |
| 790 | +} | |
| 791 | + | |
| 787 | 792 | static inline bool ipv6_addr_v4mapped_loopback(const struct in6_addr *a) |
| 788 | 793 | { |
| 789 | 794 | return ipv6_addr_v4mapped(a) && ipv4_is_loopback(a->s6_addr32[3]); |
| @@ -1360,7 +1365,7 @@ static inline int __ip6_sock_set_addr_preferences(struct sock *sk, int val) · 570 unmodified lines | ||
| 1360 | 1365 | return 0; |
| 1361 | 1366 | } |
| 1362 | 1367 | |
| 1363 | −static inline int ip6_sock_set_addr_preferences(struct sock *sk, bool val) | |
| 1368 | +static inline int ip6_sock_set_addr_preferences(struct sock *sk, int val) | |
| 1364 | 1369 | { |
| 1365 | 1370 | int ret; |
| 1366 | 1371 | |
| @@ -594,6 +594,7 @@ static int fill_frame_info(struct hsr_frame_info *frame, · 593 unmodified lines | ||
| 594 | 594 | proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto; |
| 595 | 595 | /* FIXME: */ |
| 596 | 596 | netdev_warn_once(skb->dev, "VLAN not yet supported"); |
| 597 | + return -EINVAL; | |
| 597 | 598 | } |
| 598 | 599 | |
| 599 | 600 | frame->is_from_san = false; |
| @@ -355,14 +355,14 @@ static void __inet_del_ifa(struct in_device *in_dev, · 354 unmodified lines | ||
| 355 | 355 | { |
| 356 | 356 | struct in_ifaddr *promote = NULL; |
| 357 | 357 | struct in_ifaddr *ifa, *ifa1; |
| 358 | − struct in_ifaddr *last_prim; | |
| 358 | + struct in_ifaddr __rcu **last_prim; | |
| 359 | 359 | struct in_ifaddr *prev_prom = NULL; |
| 360 | 360 | int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev); |
| 361 | 361 | |
| 362 | 362 | ASSERT_RTNL(); |
| 363 | 363 | |
| 364 | 364 | ifa1 = rtnl_dereference(*ifap); |
| 365 | − last_prim = rtnl_dereference(in_dev->ifa_list); | |
| 365 | + last_prim = ifap; | |
| 366 | 366 | if (in_dev->dead) |
| 367 | 367 | goto no_promotions; |
| 368 | 368 | |
| @@ -376,7 +376,7 @@ static void __inet_del_ifa(struct in_device *in_dev, · 7 unmodified lines | ||
| 376 | 376 | while ((ifa = rtnl_dereference(*ifap1)) != NULL) { |
| 377 | 377 | if (!(ifa->ifa_flags & IFA_F_SECONDARY) && |
| 378 | 378 | ifa1->ifa_scope <= ifa->ifa_scope) |
| 379 | − last_prim = ifa; | |
| 379 | + last_prim = &ifa->ifa_next; | |
| 380 | 380 | |
| 381 | 381 | if (!(ifa->ifa_flags & IFA_F_SECONDARY) || |
| 382 | 382 | ifa1->ifa_mask != ifa->ifa_mask || |
| @@ -440,9 +440,9 @@ no_promotions: · 57 unmodified lines | ||
| 440 | 440 | |
| 441 | 441 | rcu_assign_pointer(prev_prom->ifa_next, next_sec); |
| 442 | 442 | |
| 443 | − last_sec = rtnl_dereference(last_prim->ifa_next); | |
| 443 | + last_sec = rtnl_dereference(*last_prim); | |
| 444 | 444 | rcu_assign_pointer(promote->ifa_next, last_sec); |
| 445 | − rcu_assign_pointer(last_prim->ifa_next, promote); | |
| 445 | + rcu_assign_pointer(*last_prim, promote); | |
| 446 | 446 | } |
| 447 | 447 | |
| 448 | 448 | promote->ifa_flags &= ~IFA_F_SECONDARY; |
| @@ -815,41 +815,45 @@ static bool inet_bind2_bucket_match(const struct inet_bind2_bucket *tb, · 814 unmodified lines | ||
| 815 | 815 | const struct net *net, unsigned short port, |
| 816 | 816 | int l3mdev, const struct sock *sk) |
| 817 | 817 | { |
| 818 | + if (!net_eq(ib2_net(tb), net) || tb->port != port || | |
| 819 | + tb->l3mdev != l3mdev) | |
| 820 | + return false; | |
| 821 | + | |
| 818 | 822 | #if IS_ENABLED(CONFIG_IPV6) |
| 819 | − if (sk->sk_family != tb->family) | |
| 823 | + if (sk->sk_family != tb->family) { | |
| 824 | + if (sk->sk_family == AF_INET) | |
| 825 | + return ipv6_addr_v4mapped(&tb->v6_rcv_saddr) && | |
| 826 | + tb->v6_rcv_saddr.s6_addr32[3] == sk->sk_rcv_saddr; | |
| 827 | + | |
| 820 | 828 | return false; |
| 829 | + } | |
| 821 | 830 | |
| 822 | 831 | if (sk->sk_family == AF_INET6) |
| 823 | − return net_eq(ib2_net(tb), net) && tb->port == port && | |
| 824 | − tb->l3mdev == l3mdev && | |
| 825 | − ipv6_addr_equal(&tb->v6_rcv_saddr, &sk->sk_v6_rcv_saddr); | |
| 826 | − else | |
| 832 | + return ipv6_addr_equal(&tb->v6_rcv_saddr, &sk->sk_v6_rcv_saddr); | |
| 827 | 833 | #endif |
| 828 | − return net_eq(ib2_net(tb), net) && tb->port == port && | |
| 829 | − tb->l3mdev == l3mdev && tb->rcv_saddr == sk->sk_rcv_saddr; | |
| 834 | + return tb->rcv_saddr == sk->sk_rcv_saddr; | |
| 830 | 835 | } |
| 831 | 836 | |
| 832 | 837 | bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const struct net *net, |
| 833 | 838 | unsigned short port, int l3mdev, const struct sock *sk) |
| 834 | 839 | { |
| 840 | + if (!net_eq(ib2_net(tb), net) || tb->port != port || | |
| 841 | + tb->l3mdev != l3mdev) | |
| 842 | + return false; | |
| 843 | + | |
| 835 | 844 | #if IS_ENABLED(CONFIG_IPV6) |
| 836 | 845 | if (sk->sk_family != tb->family) { |
| 837 | 846 | if (sk->sk_family == AF_INET) |
| 838 | − return net_eq(ib2_net(tb), net) && tb->port == port && | |
| 839 | − tb->l3mdev == l3mdev && | |
| 840 | − ipv6_addr_any(&tb->v6_rcv_saddr); | |
| 847 | + return ipv6_addr_any(&tb->v6_rcv_saddr) || | |
| 848 | + ipv6_addr_v4mapped_any(&tb->v6_rcv_saddr); | |
| 841 | 849 | |
| 842 | 850 | return false; |
| 843 | 851 | } |
| 844 | 852 | |
| 845 | 853 | if (sk->sk_family == AF_INET6) |
| 846 | − return net_eq(ib2_net(tb), net) && tb->port == port && | |
| 847 | − tb->l3mdev == l3mdev && | |
| 848 | − ipv6_addr_any(&tb->v6_rcv_saddr); | |
| 849 | − else | |
| 854 | + return ipv6_addr_any(&tb->v6_rcv_saddr); | |
| 850 | 855 | #endif |
| 851 | − return net_eq(ib2_net(tb), net) && tb->port == port && | |
| 852 | − tb->l3mdev == l3mdev && tb->rcv_saddr == 0; | |
| 856 | + return tb->rcv_saddr == 0; | |
| 853 | 857 | } |
| 854 | 858 | |
| 855 | 859 | /* The socket's bhash2 hashbucket spinlock must be held when this is called */ |
| @@ -930,15 +930,18 @@ partial_message: · 929 unmodified lines | ||
| 930 | 930 | out_error: |
| 931 | 931 | kcm_push(kcm); |
| 932 | 932 | |
| 933 | − if (copied && sock->type == SOCK_SEQPACKET) { | |
| 933 | + if (sock->type == SOCK_SEQPACKET) { | |
| 934 | 934 | /* Wrote some bytes before encountering an |
| 935 | 935 | * error, return partial success. |
| 936 | 936 | */ |
| 937 | − goto partial_message; | |
| 938 | − } | |
| 939 | − | |
| 940 | − if (head != kcm->seq_skb) | |
| 937 | + if (copied) | |
| 938 | + goto partial_message; | |
| 939 | + if (head != kcm->seq_skb) | |
| 940 | + kfree_skb(head); | |
| 941 | + } else { | |
| 941 | 942 | kfree_skb(head); |
| 943 | + kcm->seq_skb = NULL; | |
| 944 | + } | |
| 942 | 945 | |
| 943 | 946 | err = sk_stream_error(sk, msg->msg_flags, err); |
| 944 | 947 | |
| @@ -1662,6 +1662,7 @@ void smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport) · 1661 unmodified lines | ||
| 1662 | 1662 | { |
| 1663 | 1663 | struct smc_link_group *lgr, *n; |
| 1664 | 1664 | |
| 1665 | + spin_lock_bh(&smc_lgr_list.lock); | |
| 1665 | 1666 | list_for_each_entry_safe(lgr, n, &smc_lgr_list.list, list) { |
| 1666 | 1667 | struct smc_link *link; |
| 1667 | 1668 | |
| @@ -1680,6 +1681,7 @@ void smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport) · 12 unmodified lines | ||
| 1680 | 1681 | if (link) |
| 1681 | 1682 | smc_llc_add_link_local(link); |
| 1682 | 1683 | } |
| 1684 | + spin_unlock_bh(&smc_lgr_list.lock); | |
| 1683 | 1685 | } |
| 1684 | 1686 | |
| 1685 | 1687 | /* link is down - switch connections to alternate link, |
| @@ -243,8 +243,9 @@ while (0) · 242 unmodified lines | ||
| 243 | 243 | #define SMC_STAT_SERV_SUCC_INC(net, _ini) \ |
| 244 | 244 | do { \ |
| 245 | 245 | typeof(_ini) i = (_ini); \ |
| 246 | − bool is_v2 = (i->smcd_version & SMC_V2); \ | |
| 247 | 246 | bool is_smcd = (i->is_smcd); \ |
| 247 | + u8 version = is_smcd ? i->smcd_version : i->smcr_version; \ | |
| 248 | + bool is_v2 = (version & SMC_V2); \ | |
| 248 | 249 | typeof(net->smc.smc_stats) smc_stats = (net)->smc.smc_stats; \ |
| 249 | 250 | if (is_v2 && is_smcd) \ |
| 250 | 251 | this_cpu_inc(smc_stats->smc[SMC_TYPE_D].srv_v2_succ_cnt); \ |
| @@ -817,7 +817,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, · 816 unmodified lines | ||
| 817 | 817 | psock = sk_psock_get(sk); |
| 818 | 818 | if (!psock || !policy) { |
| 819 | 819 | err = tls_push_record(sk, flags, record_type); |
| 820 | − if (err && sk->sk_err == EBADMSG) { | |
| 820 | + if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) { | |
| 821 | 821 | *copied -= sk_msg_free(sk, msg); |
| 822 | 822 | tls_free_open_rec(sk); |
| 823 | 823 | err = -sk->sk_err; |
| @@ -846,7 +846,7 @@ more_data: · 22 unmodified lines | ||
| 846 | 846 | switch (psock->eval) { |
| 847 | 847 | case __SK_PASS: |
| 848 | 848 | err = tls_push_record(sk, flags, record_type); |
| 849 | − if (err && sk->sk_err == EBADMSG) { | |
| 849 | + if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) { | |
| 850 | 850 | *copied -= sk_msg_free(sk, msg); |
| 851 | 851 | tls_free_open_rec(sk); |
| 852 | 852 | err = -sk->sk_err; |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | |
| 4 | 4 | NR_FILES=32768 |
| 5 | −SAVED_NR_FILES=$(ulimit -n) | |
| 5 | +readonly NETNS="ns-$(mktemp -u XXXXXX)" | |
| 6 | 6 | |
| 7 | 7 | # default values |
| 8 | 8 | port=443 |
| @@ -36,21 +36,21 @@ while getopts "ha:p:64" opt; do · 27 unmodified lines | ||
| 36 | 36 | done |
| 37 | 37 | |
| 38 | 38 | setup() { |
| 39 | + ip netns add "${NETNS}" | |
| 40 | + ip -netns "${NETNS}" link add veth0 type veth peer name veth1 | |
| 41 | + ip -netns "${NETNS}" link set lo up | |
| 42 | + ip -netns "${NETNS}" link set veth0 up | |
| 43 | + ip -netns "${NETNS}" link set veth1 up | |
| 44 | + | |
| 39 | 45 | if [[ "$use_v6" == true ]]; then |
| 40 | − ip addr add $addr_v6 nodad dev eth0 | |
| 46 | + ip -netns "${NETNS}" addr add $addr_v6 nodad dev veth0 | |
| 41 | 47 | else |
| 42 | − ip addr add $addr_v4 dev lo | |
| 48 | + ip -netns "${NETNS}" addr add $addr_v4 dev lo | |
| 43 | 49 | fi |
| 44 | − ulimit -n $NR_FILES | |
| 45 | 50 | } |
| 46 | 51 | |
| 47 | 52 | cleanup() { |
| 48 | − if [[ "$use_v6" == true ]]; then | |
| 49 | − ip addr del $addr_v6 dev eth0 | |
| 50 | − else | |
| 51 | − ip addr del $addr_v4/32 dev lo | |
| 52 | − fi | |
| 53 | − ulimit -n $SAVED_NR_FILES | |
| 53 | + ip netns del "${NETNS}" | |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | 56 | if [[ "$addr" != "" ]]; then |
| @@ -59,8 +59,10 @@ if [[ "$addr" != "" ]]; then · 2 unmodified lines | ||
| 59 | 59 | fi |
| 60 | 60 | setup |
| 61 | 61 | if [[ "$use_v6" == true ]] ; then |
| 62 | − ./bind_bhash $port "ipv6" $addr_v6 | |
| 62 | + ip netns exec "${NETNS}" sh -c \ | |
| 63 | + "ulimit -n ${NR_FILES};./bind_bhash ${port} ipv6 ${addr_v6}" | |
| 63 | 64 | else |
| 64 | − ./bind_bhash $port "ipv4" $addr_v4 | |
| 65 | + ip netns exec "${NETNS}" sh -c \ | |
| 66 | + "ulimit -n ${NR_FILES};./bind_bhash ${port} ipv4 ${addr_v4}" | |
| 65 | 67 | fi |
| 66 | 68 | cleanup |
| @@ -6,41 +6,91 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | #include "../kselftest_harness.h" |
| 8 | 8 | |
| 9 | +struct in6_addr in6addr_v4mapped_any = { | |
| 10 | + .s6_addr = { | |
| 11 | + 0, 0, 0, 0, | |
| 12 | + 0, 0, 0, 0, | |
| 13 | + 0, 0, 255, 255, | |
| 14 | + 0, 0, 0, 0 | |
| 15 | + } | |
| 16 | +}; | |
| 17 | + | |
| 18 | +struct in6_addr in6addr_v4mapped_loopback = { | |
| 19 | + .s6_addr = { | |
| 20 | + 0, 0, 0, 0, | |
| 21 | + 0, 0, 0, 0, | |
| 22 | + 0, 0, 255, 255, | |
| 23 | + 127, 0, 0, 1 | |
| 24 | + } | |
| 25 | +}; | |
| 26 | + | |
| 9 | 27 | FIXTURE(bind_wildcard) |
| 10 | 28 | { |
| 11 | 29 | struct sockaddr_in addr4; |
| 12 | 30 | struct sockaddr_in6 addr6; |
| 13 | − int expected_errno; | |
| 14 | 31 | }; |
| 15 | 32 | |
| 16 | 33 | FIXTURE_VARIANT(bind_wildcard) |
| 17 | 34 | { |
| 18 | 35 | const __u32 addr4_const; |
| 19 | 36 | const struct in6_addr *addr6_const; |
| 37 | + int expected_errno; | |
| 20 | 38 | }; |
| 21 | 39 | |
| 22 | 40 | FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_any) |
| 23 | 41 | { |
| 24 | 42 | .addr4_const = INADDR_ANY, |
| 25 | 43 | .addr6_const = &in6addr_any, |
| 44 | + .expected_errno = EADDRINUSE, | |
| 26 | 45 | }; |
| 27 | 46 | |
| 28 | 47 | FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_local) |
| 29 | 48 | { |
| 30 | 49 | .addr4_const = INADDR_ANY, |
| 31 | 50 | .addr6_const = &in6addr_loopback, |
| 51 | + .expected_errno = 0, | |
| 52 | +}; | |
| 53 | + | |
| 54 | +FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_v4mapped_any) | |
| 55 | +{ | |
| 56 | + .addr4_const = INADDR_ANY, | |
| 57 | + .addr6_const = &in6addr_v4mapped_any, | |
| 58 | + .expected_errno = EADDRINUSE, | |
| 59 | +}; | |
| 60 | + | |
| 61 | +FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_v4mapped_local) | |
| 62 | +{ | |
| 63 | + .addr4_const = INADDR_ANY, | |
| 64 | + .addr6_const = &in6addr_v4mapped_loopback, | |
| 65 | + .expected_errno = EADDRINUSE, | |
| 32 | 66 | }; |
| 33 | 67 | |
| 34 | 68 | FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_any) |
| 35 | 69 | { |
| 36 | 70 | .addr4_const = INADDR_LOOPBACK, |
| 37 | 71 | .addr6_const = &in6addr_any, |
| 72 | + .expected_errno = EADDRINUSE, | |
| 38 | 73 | }; |
| 39 | 74 | |
| 40 | 75 | FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_local) |
| 41 | 76 | { |
| 42 | 77 | .addr4_const = INADDR_LOOPBACK, |
| 43 | 78 | .addr6_const = &in6addr_loopback, |
| 79 | + .expected_errno = 0, | |
| 80 | +}; | |
| 81 | + | |
| 82 | +FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_v4mapped_any) | |
| 83 | +{ | |
| 84 | + .addr4_const = INADDR_LOOPBACK, | |
| 85 | + .addr6_const = &in6addr_v4mapped_any, | |
| 86 | + .expected_errno = EADDRINUSE, | |
| 87 | +}; | |
| 88 | + | |
| 89 | +FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_v4mapped_local) | |
| 90 | +{ | |
| 91 | + .addr4_const = INADDR_LOOPBACK, | |
| 92 | + .addr6_const = &in6addr_v4mapped_loopback, | |
| 93 | + .expected_errno = EADDRINUSE, | |
| 44 | 94 | }; |
| 45 | 95 | |
| 46 | 96 | FIXTURE_SETUP(bind_wildcard) |
| @@ -52,11 +102,6 @@ FIXTURE_SETUP(bind_wildcard) · 5 unmodified lines | ||
| 52 | 102 | self->addr6.sin6_family = AF_INET6; |
| 53 | 103 | self->addr6.sin6_port = htons(0); |
| 54 | 104 | self->addr6.sin6_addr = *variant->addr6_const; |
| 55 | − | |
| 56 | − if (variant->addr6_const == &in6addr_any) | |
| 57 | − self->expected_errno = EADDRINUSE; | |
| 58 | − else | |
| 59 | − self->expected_errno = 0; | |
| 60 | 105 | } |
| 61 | 106 | |
| 62 | 107 | FIXTURE_TEARDOWN(bind_wildcard) |
| @@ -65,6 +110,7 @@ FIXTURE_TEARDOWN(bind_wildcard) · 2 unmodified lines | ||
| 65 | 110 | |
| 66 | 111 | void bind_sockets(struct __test_metadata *_metadata, |
| 67 | 112 | FIXTURE_DATA(bind_wildcard) *self, |
| 113 | + int expected_errno, | |
| 68 | 114 | struct sockaddr *addr1, socklen_t addrlen1, |
| 69 | 115 | struct sockaddr *addr2, socklen_t addrlen2) |
| 70 | 116 | { |
| @@ -86,9 +132,9 @@ void bind_sockets(struct __test_metadata *_metadata, · 15 unmodified lines | ||
| 86 | 132 | ASSERT_GT(fd[1], 0); |
| 87 | 133 | |
| 88 | 134 | ret = bind(fd[1], addr2, addrlen2); |
| 89 | − if (self->expected_errno) { | |
| 135 | + if (expected_errno) { | |
| 90 | 136 | ASSERT_EQ(ret, -1); |
| 91 | − ASSERT_EQ(errno, self->expected_errno); | |
| 137 | + ASSERT_EQ(errno, expected_errno); | |
| 92 | 138 | } else { |
| 93 | 139 | ASSERT_EQ(ret, 0); |
| 94 | 140 | } |
| @@ -99,14 +145,14 @@ void bind_sockets(struct __test_metadata *_metadata, · 4 unmodified lines | ||
| 99 | 145 | |
| 100 | 146 | TEST_F(bind_wildcard, v4_v6) |
| 101 | 147 | { |
| 102 | − bind_sockets(_metadata, self, | |
| 103 | − (struct sockaddr *)&self->addr4, sizeof(self->addr6), | |
| 148 | + bind_sockets(_metadata, self, variant->expected_errno, | |
| 149 | + (struct sockaddr *)&self->addr4, sizeof(self->addr4), | |
| 104 | 150 | (struct sockaddr *)&self->addr6, sizeof(self->addr6)); |
| 105 | 151 | } |
| 106 | 152 | |
| 107 | 153 | TEST_F(bind_wildcard, v6_v4) |
| 108 | 154 | { |
| 109 | − bind_sockets(_metadata, self, | |
| 155 | + bind_sockets(_metadata, self, variant->expected_errno, | |
| 110 | 156 | (struct sockaddr *)&self->addr6, sizeof(self->addr6), |
| 111 | 157 | (struct sockaddr *)&self->addr4, sizeof(self->addr4)); |
| 112 | 158 | } |