From patchwork Fri Jun 1 11:21:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eelco Chaudron X-Patchwork-Id: 923957 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40y23H5dh5z9ry1 for ; Fri, 1 Jun 2018 21:21:47 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 4054FCD6; Fri, 1 Jun 2018 11:21:45 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 08E09CC7 for ; Fri, 1 Jun 2018 11:21:44 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 1402C70F for ; Fri, 1 Jun 2018 11:21:41 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 30BD340BC056 for ; Fri, 1 Jun 2018 11:21:41 +0000 (UTC) Received: from rhvm.com (ovpn-116-35.ams2.redhat.com [10.36.116.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id CC2D32144B24 for ; Fri, 1 Jun 2018 11:21:40 +0000 (UTC) From: Eelco Chaudron To: dev@openvswitch.org Date: Fri, 1 Jun 2018 13:21:31 +0200 Message-Id: <1a4f573218cb8de139a438879c347a3c098bb316.1527852063.git.echaudro@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Fri, 01 Jun 2018 11:21:41 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Fri, 01 Jun 2018 11:21:41 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'echaudro@redhat.com' RCPT:'' X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH 1/1] Utilities: Add the simap and netdev_provider dump commands to gdb X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org This changes add two additional gdb commands: - ovs_dump_netdev_provider - ovs_dump_ovs_list Here are some examples of their output: ovs_dump_netdev_provider: ========================= (gdb) ovs_dump_netdev_provider (struct netdev_registered_class *) 0x2b2c540: refcnt = {count = 3}, (struct netdev_class *) 0x9555c0 = {type = tap, is_pmd = false, ...}, (struct netdev_registered_class *) 0x2b2c5a0: refcnt = {count = 2}, (struct netdev_class *) 0xc439d8 = {type = vxlan, is_pmd = false, ...}, (struct vport_class *) 0xc439d0 = { dpif_port = vxlan_sys, ... } (struct netdev_registered_class *) 0x2b2c960: refcnt = {count = 1}, (struct netdev_class *) 0xc442f8 = {type = ip6erspan, is_pmd = false, ...}, (struct vport_class *) 0xc442f0 = { dpif_port = ip6erspan_sys, ... } (struct netdev_registered_class *) 0x2b2c980: refcnt = {count = 1}, (struct netdev_class *) 0xc44540 = {type = ip6gre, is_pmd = false, ...}, (struct vport_class *) 0xc44538 = { dpif_port = ip6gre_sys, ... } (struct netdev_registered_class *) 0x2b2ebe0: refcnt = {count = 3}, (struct netdev_class *) 0x95b8c0 = {type = dpdk, is_pmd = true, ...}, ovs_dump_ovs_list: ================== (gdb) b memory_report Breakpoint 1 at 0x753190: file lib/memory.c, line 136. (gdb) set want_report=1 (gdb) c Continuing. Breakpoint 1, memory_report (usage=usage@entry=0x7fff0683d920) at lib/memory.c:136 136 { (gdb) p usage $20 = (const struct simap *) 0x7fff0683d920 (gdb) p* usage $21 = {map = {buckets = 0x2b64df0, one = 0x0, mask = 3, n = 4}} (gdb) p *usage (gdb) ovs_dump_simap usage handlers : 40 / 0x28 ports : 6 / 0x6 revalidators: 16 / 0x10 rules : 10 / 0xa Signed-off-by: Eelco Chaudron --- utilities/gdb/ovs_gdb.py | 113 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/utilities/gdb/ovs_gdb.py b/utilities/gdb/ovs_gdb.py index 6a82e4076..538383c72 100644 --- a/utilities/gdb/ovs_gdb.py +++ b/utilities/gdb/ovs_gdb.py @@ -27,7 +27,9 @@ # - ovs_dump_dp_netdev_ports # - ovs_dump_dp_provider # - ovs_dump_netdev +# - ovs_dump_netdev_provider # - ovs_dump_ovs_list {[] [] {dump}]} +# - ovs_dump_simap # # Example: # $ gdb $(which ovs-vswitchd) $(pidof ovs-vswitchd) @@ -239,6 +241,19 @@ class ForEachSHASH(ForEachHMAP): return node['data'].cast(gdb.lookup_type(self.data_typeobj).pointer()) +# +# Class that will provide an iterator over an OVS simap. +# +class ForEachSIMAP(ForEachHMAP): + def __init__(self, shash): + super(ForEachSIMAP, self).__init__(shash['map'], + "struct simap_node", "node") + + def next(self): + node = super(ForEachSIMAP, self).next() + return node['name'], node['data'] + + # # Class that will provide an iterator over an OVS list. # @@ -473,7 +488,6 @@ class CmdDumpDpProvider(gdb.Command): gdb.COMMAND_DATA) def invoke(self, arg, from_tty): - dp_providers = get_global_variable('dpif_classes') if dp_providers is None: return @@ -518,6 +532,66 @@ class CmdDumpNetdev(gdb.Command): self.display_single_netdev(netdev) +# +# Implements the GDB "ovs_dump_netdev_provider" command +# +class CmdDumpNetdevProvider(gdb.Command): + """Dump all registered netdev providers. + Usage: ovs_dump_netdev_provider + """ + def __init__(self): + super(CmdDumpNetdevProvider, self).__init__("ovs_dump_netdev_provider", + gdb.COMMAND_DATA) + + @staticmethod + def is_class_vport_class(netdev_class): + netdev_class = netdev_class.cast( + gdb.lookup_type('struct netdev_class').pointer()) + + vport_construct = gdb.lookup_symbol('netdev_vport_construct')[0] + + if netdev_class['construct'] == vport_construct.value(): + return True + return False + + @staticmethod + def display_single_netdev_provider(reg_class, indent=0): + indent = " " * indent + print("{}(struct netdev_registered_class *) {}: refcnt = {},". + format(indent, reg_class, reg_class['refcnt'])) + + print("{} (struct netdev_class *) 0x{:x} = {{type = {}, " + "is_pmd = {}, ...}}, ". + format(indent, long(reg_class['class']), + reg_class['class']['type'].string(), + reg_class['class']['is_pmd'])) + + if CmdDumpNetdevProvider.is_class_vport_class(reg_class['class']): + vport = container_of( + reg_class['class'], + gdb.lookup_type('struct vport_class').pointer(), + 'netdev_class') + + if vport['dpif_port'] != 0: + dpif_port = vport['dpif_port'].string() + else: + dpif_port = "\"\"" + + print("{} (struct vport_class *) 0x{:x} = " + "{{ dpif_port = {}, ... }}". + format(indent, long(vport), dpif_port)) + + def invoke(self, arg, from_tty): + netdev_classes = get_global_variable('netdev_classes') + if netdev_classes is None: + return + + for reg_class in ForEachCMAP(netdev_classes, + "struct netdev_registered_class", + "cmap_node"): + self.display_single_netdev_provider(reg_class) + + # # Implements the GDB "ovs_dump_ovs_list" command # @@ -591,6 +665,41 @@ class CmdDumpOvsList(gdb.Command): member).dereference())) +# +# Implements the GDB "ovs_dump_simap" command +# +class CmdDumpSimap(gdb.Command): + """Dump all nodes of an ovs_list give + Usage: ovs_dump_ovs_list + """ + + def __init__(self): + super(CmdDumpSimap, self).__init__("ovs_dump_simap", + gdb.COMMAND_DATA) + + def invoke(self, arg, from_tty): + arg_list = gdb.string_to_argv(arg) + + if len(arg_list) != 1: + print("ERROR: Missing argument!\n") + print(self.__doc__) + return + + simap = gdb.parse_and_eval(arg_list[0]).cast( + gdb.lookup_type('struct simap').pointer()) + + values = dict() + max_name_len = 0 + for name, value in ForEachSIMAP(simap.dereference()): + values[name.string()] = long(value) + if len(name.string()) > max_name_len: + max_name_len = len(name.string()) + + for name in sorted(values.iterkeys()): + print("{}: {} / 0x{:x}".format(name.ljust(max_name_len), + values[name], values[name])) + + # # Initialize all GDB commands # @@ -601,4 +710,6 @@ CmdDumpDpNetdevPollThreads() CmdDumpDpNetdevPorts() CmdDumpDpProvider() CmdDumpNetdev() +CmdDumpNetdevProvider() CmdDumpOvsList() +CmdDumpSimap()