Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: dsa: mv88e6xxx: Add FID map cache

Add a cached FID bitmap. This mitigates the need to walk all VTU entries
to find the next free FID.

When flushing the VTU (during init), zero the FID bitmap. Use and
manipulate this bitmap from now on, instead of reading HW for the FID
map.

The repeated VTU walks are costly and can take ~40 mins if ~4000 vlans
are added. Caching the FID map reduces this time to <2 mins.

Signed-off-by: Aryan Srivastava <aryan.srivastava@alliedtelesis.co.nz>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20241006212905.3142976-1-aryan.srivastava@alliedtelesis.co.nz
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Aryan Srivastava and committed by
Jakub Kicinski
ada5c322 42b23310

+14 -38
+7 -28
drivers/net/dsa/mv88e6xxx/chip.c
··· 1930 1930 return chip->info->ops->vtu_loadpurge(chip, entry); 1931 1931 } 1932 1932 1933 - static int mv88e6xxx_fid_map_vlan(struct mv88e6xxx_chip *chip, 1934 - const struct mv88e6xxx_vtu_entry *entry, 1935 - void *_fid_bitmap) 1936 - { 1937 - unsigned long *fid_bitmap = _fid_bitmap; 1938 - 1939 - set_bit(entry->fid, fid_bitmap); 1940 - return 0; 1941 - } 1942 - 1943 - int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap) 1944 - { 1945 - bitmap_zero(fid_bitmap, MV88E6XXX_N_FID); 1946 - 1947 - /* Every FID has an associated VID, so walking the VTU 1948 - * will discover the full set of FIDs in use. 1949 - */ 1950 - return mv88e6xxx_vtu_walk(chip, mv88e6xxx_fid_map_vlan, fid_bitmap); 1951 - } 1952 - 1953 1933 static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid) 1954 1934 { 1955 - DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID); 1956 - int err; 1957 - 1958 - err = mv88e6xxx_fid_map(chip, fid_bitmap); 1959 - if (err) 1960 - return err; 1961 - 1962 - *fid = find_first_zero_bit(fid_bitmap, MV88E6XXX_N_FID); 1935 + *fid = find_first_zero_bit(chip->fid_bitmap, MV88E6XXX_N_FID); 1963 1936 if (unlikely(*fid >= mv88e6xxx_num_databases(chip))) 1964 1937 return -ENOSPC; 1965 1938 ··· 2639 2666 port, vid); 2640 2667 } 2641 2668 2669 + /* Record FID used in SW FID map */ 2670 + bitmap_set(chip->fid_bitmap, vlan.fid, 1); 2671 + 2642 2672 return 0; 2643 2673 } 2644 2674 ··· 2747 2771 err = mv88e6xxx_mst_put(chip, vlan.sid); 2748 2772 if (err) 2749 2773 return err; 2774 + 2775 + /* Record FID freed in SW FID map */ 2776 + bitmap_clear(chip->fid_bitmap, vlan.fid, 1); 2750 2777 } 2751 2778 2752 2779 return mv88e6xxx_g1_atu_remove(chip, vlan.fid, port, false);
+3 -2
drivers/net/dsa/mv88e6xxx/chip.h
··· 440 440 441 441 /* Bridge MST to SID mappings */ 442 442 struct list_head msts; 443 + 444 + /* FID map */ 445 + DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID); 443 446 }; 444 447 445 448 struct mv88e6xxx_bus_ops { ··· 845 842 const struct mv88e6xxx_vtu_entry *entry, 846 843 void *priv), 847 844 void *priv); 848 - 849 - int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *bitmap); 850 845 851 846 #endif /* _MV88E6XXX_CHIP_H */
+1 -8
drivers/net/dsa/mv88e6xxx/devlink.c
··· 374 374 u8 **data) 375 375 { 376 376 struct dsa_switch *ds = dsa_devlink_to_ds(dl); 377 - DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID); 378 377 struct mv88e6xxx_devlink_atu_entry *table; 379 378 struct mv88e6xxx_chip *chip = ds->priv; 380 379 int fid = -1, count, err; ··· 391 392 392 393 mv88e6xxx_reg_lock(chip); 393 394 394 - err = mv88e6xxx_fid_map(chip, fid_bitmap); 395 - if (err) { 396 - kfree(table); 397 - goto out; 398 - } 399 - 400 395 while (1) { 401 - fid = find_next_bit(fid_bitmap, MV88E6XXX_N_FID, fid + 1); 396 + fid = find_next_bit(chip->fid_bitmap, MV88E6XXX_N_FID, fid + 1); 402 397 if (fid == MV88E6XXX_N_FID) 403 398 break; 404 399
+3
drivers/net/dsa/mv88e6xxx/global1_vtu.c
··· 471 471 { 472 472 int err; 473 473 474 + /* As part of the VTU flush, refresh FID map */ 475 + bitmap_zero(chip->fid_bitmap, MV88E6XXX_N_FID); 476 + 474 477 err = mv88e6xxx_g1_vtu_op_wait(chip); 475 478 if (err) 476 479 return err;