Message ID | 20230609212959.32061-1-ematsumiya@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] smb/client: print "Unknown" instead of bogus link speed value | expand |
On Sat, Jun 10, 2023 at 3:00 AM Enzo Matsumiya <ematsumiya@suse.de> wrote: > > The virtio driver for Linux guests will not set a link speed to its > paravirtualized NICs. This will be seen as -1 in the ethernet layer, and > when some servers (e.g. samba) fetches it, it's converted to an unsigned > value (and multiplied by 1000 * 1000), so in client side we end up with: > > 1) Speed: 4294967295000000 bps > > in DebugData. > > This patch introduces a helper that returns a speed string (in Mbps or > Gbps) if interface speed is valid (>= SPEED_10 and <= SPEED_800000), or > "Unknown" otherwise. > > The reason to not change the value in iface->speed is because we don't > know the real speed of the HW backing the server NIC, so let's keep > considering these as the fastest NICs available. > > Also print "Capabilities: None" when the interface doesn't support any. > > Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de> > --- > v2: remove dependency on CONFIG_PHYLIB by creating our own helper > > fs/smb/client/cifs_debug.c | 47 +++++++++++++++++++++++++++++++++++++- > 1 file changed, 46 insertions(+), 1 deletion(-) > > diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c > index 5034b862cec2..c5d9579e1861 100644 > --- a/fs/smb/client/cifs_debug.c > +++ b/fs/smb/client/cifs_debug.c > @@ -12,6 +12,7 @@ > #include <linux/module.h> > #include <linux/proc_fs.h> > #include <linux/uaccess.h> > +#include <uapi/linux/ethtool.h> > #include "cifspdu.h" > #include "cifsglob.h" > #include "cifsproto.h" > @@ -146,18 +147,62 @@ cifs_dump_channel(struct seq_file *m, int i, struct cifs_chan *chan) > atomic_read(&server->num_waiters)); > } > > +static inline const char *smb_speed_to_str(size_t bps) > +{ > + size_t mbps = bps / 1000 / 1000; > + > + switch (mbps) { > + case SPEED_10: > + return "10Mbps"; > + case SPEED_100: > + return "100Mbps"; > + case SPEED_1000: > + return "1Gbps"; > + case SPEED_2500: > + return "2.5Gbps"; > + case SPEED_5000: > + return "5Gbps"; > + case SPEED_10000: > + return "10Gbps"; > + case SPEED_14000: > + return "14Gbps"; > + case SPEED_20000: > + return "20Gbps"; > + case SPEED_25000: > + return "25Gbps"; > + case SPEED_40000: > + return "40Gbps"; > + case SPEED_50000: > + return "50Gbps"; > + case SPEED_56000: > + return "56Gbps"; > + case SPEED_100000: > + return "100Gbps"; > + case SPEED_200000: > + return "200Gbps"; > + case SPEED_400000: > + return "400Gbps"; > + case SPEED_800000: > + return "800Gbps"; > + default: > + return "Unknown"; > + } > +} > + > static void > cifs_dump_iface(struct seq_file *m, struct cifs_server_iface *iface) > { > struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr; > struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr; > > - seq_printf(m, "\tSpeed: %zu bps\n", iface->speed); > + seq_printf(m, "\tSpeed: %s\n", smb_speed_to_str(iface->speed)); > seq_puts(m, "\t\tCapabilities: "); > if (iface->rdma_capable) > seq_puts(m, "rdma "); > if (iface->rss_capable) > seq_puts(m, "rss "); > + if (!iface->rdma_capable && !iface->rss_capable) > + seq_puts(m, "None"); > seq_putc(m, '\n'); > if (iface->sockaddr.ss_family == AF_INET) > seq_printf(m, "\t\tIPv4: %pI4\n", &ipv4->sin_addr); > -- > 2.40.1 > Looks good to me.
diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c index 5034b862cec2..c5d9579e1861 100644 --- a/fs/smb/client/cifs_debug.c +++ b/fs/smb/client/cifs_debug.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/proc_fs.h> #include <linux/uaccess.h> +#include <uapi/linux/ethtool.h> #include "cifspdu.h" #include "cifsglob.h" #include "cifsproto.h" @@ -146,18 +147,62 @@ cifs_dump_channel(struct seq_file *m, int i, struct cifs_chan *chan) atomic_read(&server->num_waiters)); } +static inline const char *smb_speed_to_str(size_t bps) +{ + size_t mbps = bps / 1000 / 1000; + + switch (mbps) { + case SPEED_10: + return "10Mbps"; + case SPEED_100: + return "100Mbps"; + case SPEED_1000: + return "1Gbps"; + case SPEED_2500: + return "2.5Gbps"; + case SPEED_5000: + return "5Gbps"; + case SPEED_10000: + return "10Gbps"; + case SPEED_14000: + return "14Gbps"; + case SPEED_20000: + return "20Gbps"; + case SPEED_25000: + return "25Gbps"; + case SPEED_40000: + return "40Gbps"; + case SPEED_50000: + return "50Gbps"; + case SPEED_56000: + return "56Gbps"; + case SPEED_100000: + return "100Gbps"; + case SPEED_200000: + return "200Gbps"; + case SPEED_400000: + return "400Gbps"; + case SPEED_800000: + return "800Gbps"; + default: + return "Unknown"; + } +} + static void cifs_dump_iface(struct seq_file *m, struct cifs_server_iface *iface) { struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr; struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr; - seq_printf(m, "\tSpeed: %zu bps\n", iface->speed); + seq_printf(m, "\tSpeed: %s\n", smb_speed_to_str(iface->speed)); seq_puts(m, "\t\tCapabilities: "); if (iface->rdma_capable) seq_puts(m, "rdma "); if (iface->rss_capable) seq_puts(m, "rss "); + if (!iface->rdma_capable && !iface->rss_capable) + seq_puts(m, "None"); seq_putc(m, '\n'); if (iface->sockaddr.ss_family == AF_INET) seq_printf(m, "\t\tIPv4: %pI4\n", &ipv4->sin_addr);
The virtio driver for Linux guests will not set a link speed to its paravirtualized NICs. This will be seen as -1 in the ethernet layer, and when some servers (e.g. samba) fetches it, it's converted to an unsigned value (and multiplied by 1000 * 1000), so in client side we end up with: 1) Speed: 4294967295000000 bps in DebugData. This patch introduces a helper that returns a speed string (in Mbps or Gbps) if interface speed is valid (>= SPEED_10 and <= SPEED_800000), or "Unknown" otherwise. The reason to not change the value in iface->speed is because we don't know the real speed of the HW backing the server NIC, so let's keep considering these as the fastest NICs available. Also print "Capabilities: None" when the interface doesn't support any. Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de> --- v2: remove dependency on CONFIG_PHYLIB by creating our own helper fs/smb/client/cifs_debug.c | 47 +++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-)