Netdev List
 help / color / mirror / Atom feed
* [PATCH][next] rtlwifi: rtl8192ce: fix typo, "PairwiseENcAlgorithm" -> "PairwiseEncAlgorithm"
From: Colin King @ 2019-02-20  9:27 UTC (permalink / raw)
  To: Ping-Ke Shih, Kalle Valo, David S . Miller, Larry Finger,
	linux-wireless, netdev
  Cc: kernel-janitors, linux-kernel

From: Colin Ian King <colin.king@canonical.com>

There is an uppercase 'N' that should be a lowercase 'n', fix this.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
index 5cf5a85d1376..d8f496e2d68b 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
@@ -876,7 +876,7 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw)
 	u8 sec_reg_value;
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 "PairwiseENcAlgorithm = %d GroupEncAlgorithm = %d\n",
+		 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
 		 rtlpriv->sec.pairwise_enc_algorithm,
 		 rtlpriv->sec.group_enc_algorithm);
 
-- 
2.20.1


^ permalink raw reply related

* [patch iproute2] devlink: relax dpipe table show dependency on resources
From: Jiri Pirko @ 2019-02-20  9:21 UTC (permalink / raw)
  To: netdev; +Cc: stephen, dsahern, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Dpipe table show command has a depencency on getting resources.
If resource get command is not supported by the driver, dpipe table
show fails. However, resource is only additional information
in dpipe table show output. So relax the dependency and let
the dpipe tables be shown even if resources get command fails.

Fixes: ead180274caf ("devlink: Add support for resource/dpipe relation")
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 devlink/devlink.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 3651e90c1159..00a76060b31d 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -4351,7 +4351,8 @@ static int dpipe_table_show(struct dpipe_ctx *ctx, struct nlattr *nl)
 	size = mnl_attr_get_u32(nla_table[DEVLINK_ATTR_DPIPE_TABLE_SIZE]);
 	counters_enabled = !!mnl_attr_get_u8(nla_table[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
 
-	resource_valid = !!nla_table[DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID];
+	resource_valid = !!nla_table[DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID] &&
+			 ctx->resources;
 	if (resource_valid) {
 		table->resource_id = mnl_attr_get_u64(nla_table[DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID]);
 		table->resource_valid = true;
@@ -4467,12 +4468,9 @@ static int cmd_dpipe_table_show(struct dl *dl)
 	dl_opts_put(nlh, dl);
 	err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_resource_dump_cb,
 				  &resource_ctx);
-	if (err) {
-		pr_err("error get resources %s\n", strerror(resource_ctx.err));
-		goto err_resource_dump;
-	}
+	if (!err)
+		dpipe_ctx.resources = resource_ctx.resources;
 
-	dpipe_ctx.resources = resource_ctx.resources;
 	flags = NLM_F_REQUEST | NLM_F_ACK;
 	nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_DPIPE_TABLE_GET, flags);
 	dl_opts_put(nlh, dl);
@@ -4485,8 +4483,6 @@ static int cmd_dpipe_table_show(struct dl *dl)
 	dpipe_ctx_fini(&dpipe_ctx);
 	return 0;
 
-err_resource_dump:
-	resource_ctx_fini(&resource_ctx);
 err_resource_ctx_init:
 err_headers_get:
 	dpipe_ctx_fini(&dpipe_ctx);
-- 
2.14.5


^ permalink raw reply related

* Re: [Outreachy kernel] [PATCH] net: dsa: add missing of_node_put
From: Himadri Pandya @ 2019-02-20  9:10 UTC (permalink / raw)
  To: Vaishali Thakkar
  Cc: outreachy-kernel, Julia Lawall, andrew, Florian Fainelli,
	David S. Miller, netdev, Linux Kernel Mailing List
In-Reply-To: <CAK-LDb+pTxoeuVYb+V6N6everYRtOvJwo26O-=LVVEbsXqBOFA@mail.gmail.com>


On 20/02/19 9:23 AM, Vaishali Thakkar wrote:
> On Wed, Feb 20, 2019 at 8:54 AM Himadri Pandya <himadri18.07@gmail.com> wrote:
> Hi Himadri,
>
> Thanks for the patch!
>
> For the scope of Outreachy, we prefer that you send patches in staging
> directory as Greg makes sure to pick them during the application
> period. Of course, you're very much encouraged to contribute to other
> subsystems as well but there patches are mainly picked up based on
> maintainer's cycle which may or may not be picked up for linux-next when
> selection of interns happens.
>
> I hope that makes sense.
Understood. Thank you for letting me know that.
>> Decrement the reference count on port while returning out of the loop.
> How did you find out about this issue?
I believe that Julia Lawall has been working on this for a while. After 
doing some cleanup patches, I'm trying to continue the work with her help.
> I think it would be good to
> give credit to tool in commit log if the issue is identified or produced
> by tool. [In this case, I assume it's Coccinelle]

Yes, it was identified by Coccinelle and I should include it in the 
commit message. Thank you for the remark. I'll revise the patch accordingly.

- Himadri


>> Signed-off-by: Himadri Pandya <himadri18.07@gmail.com>
>> ---
>>   net/dsa/dsa2.c | 14 ++++++++++----
>>   1 file changed, 10 insertions(+), 4 deletions(-)
>>
>> diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
>> index a1917025e155..396e7433dd8f 100644
>> --- a/net/dsa/dsa2.c
>> +++ b/net/dsa/dsa2.c
>> @@ -624,19 +624,25 @@ static int dsa_switch_parse_ports_of(struct dsa_switch *ds,
>>          for_each_available_child_of_node(ports, port) {
>>                  err = of_property_read_u32(port, "reg", &reg);
>>                  if (err)
>> -                       return err;
>> +                       goto put_port;
>>
>> -               if (reg >= ds->num_ports)
>> -                       return -EINVAL;
>> +               if (reg >= ds->num_ports) {
>> +                       err = -EINVAL;
>> +                       goto put_port;
>> +               }
>>
>>                  dp = &ds->ports[reg];
>>
>>                  err = dsa_port_parse_of(dp, port);
>>                  if (err)
>> -                       return err;
>> +                       goto put_port;
>>          }
>>
>>          return 0;
>> +
>> +put_port:
>> +       of_node_put(port);
>> +       return err;
>>   }
>>
>>   static int dsa_switch_parse_member_of(struct dsa_switch *ds,
>> --
>> 2.17.1
>>
>> --
>> You received this message because you are subscribed to the Google Groups "outreachy-kernel" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to outreachy-kernel+unsubscribe@googlegroups.com.
>> To post to this group, send email to outreachy-kernel@googlegroups.com.
>> To view this discussion on the web visit https://groups.google.com/d/msgid/outreachy-kernel/20190220032432.2878-1-himadri18.07%40gmail.com.
>> For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* Re: [PATCH net-next 3/3] nfp: devlink: allow flashing the device via devlink
From: Jiri Pirko @ 2019-02-20  8:37 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: davem, netdev, oss-drivers, mkubecek, andrew
In-Reply-To: <20190219164926.23981359@cakuba.netronome.com>

Wed, Feb 20, 2019 at 01:49:26AM CET, jakub.kicinski@netronome.com wrote:
>On Tue, 19 Feb 2019 10:19:42 +0100, Jiri Pirko wrote:
>> Fri, Feb 15, 2019 at 04:44:29PM CET, jakub.kicinski@netronome.com wrote:
>> >On Fri, 15 Feb 2019 11:15:14 +0100, Jiri Pirko wrote:  
>> >> > static const struct ethtool_ops nfp_net_ethtool_ops = {    
>> >> 
>> >> Why don't you use the compat fallback? I think you should.  
>> >
>> >You and Michal both asked the same so let me answer the first to ask :)
>> >- if devlink is built as a module the fallback is not reachable.  
>> 
>> So the fallback is not really good as you can't use it for real drivers
>> anyway. Odd. Maybe we should compile devlink in without possibility to
>> have it as module.
>
>Ack, I'll make devlink a bool.

Thanks!

>
>I need a little extra time, I forgot that nfp's flower offload still
>doesn't register all ports (using your port flavour infrastructure).

Finally :)

^ permalink raw reply

* Re: [PATCH net v2] team: use operstate consistently for linkup
From: Jiri Pirko @ 2019-02-20  8:36 UTC (permalink / raw)
  To: George Wilkie; +Cc: David S. Miller, netdev
In-Reply-To: <20190220081911.803-1-gwilkie@vyatta.att-mail.com>

Wed, Feb 20, 2019 at 09:19:11AM CET, gwilkie@vyatta.att-mail.com wrote:
>When a port is added to a team, its initial state is derived
>from netif_carrier_ok rather than netif_oper_up.
>If it is carrier up but operationally down at the time of being
>added, the port state.linkup will be set prematurely.
>port state.linkup should be set consistently using
>netif_oper_up rather than netif_carrier_ok.
>
>Fixes: f1d22a1e0595 ("team: account for oper state")
>Signed-off-by: George Wilkie <gwilkie@vyatta.att-mail.com>

Acked-by: Jiri Pirko <jiri@mellanox.com>

^ permalink raw reply

* Re: linux-next: Fixes tag needs some work in the net-next tree
From: Jiri Pirko @ 2019-02-20  8:36 UTC (permalink / raw)
  To: David Miller; +Cc: vkoul, sfr, netdev, linux-next, linux-kernel, andrew
In-Reply-To: <20190219.224813.723564128666927693.davem@davemloft.net>

Wed, Feb 20, 2019 at 07:48:13AM CET, davem@davemloft.net wrote:
>From: Vinod Koul <vkoul@kernel.org>
>Date: Wed, 20 Feb 2019 10:10:55 +0530
>
>> On 20-02-19, 09:31, Stephen Rothwell wrote:
>>> Hi all,
>>> 
>>> In commit
>>> 
>>>   a968b5e9d587 ("net: dsa: qca8k: Enable delay for RGMII_ID mode")
>>> 
>>> Fixes tag
>>> 
>>>   Fixes: 40269aa9f40a ("net: dsa: qca8k: disable delay for RGMII mode")
>>> 
>>> has these problem(s):
>>> 
>>>   - Target SHA1 does not exist
>>> 
>>> Did you mean:
>>> 
>>>   Fixes: 5ecdd77c61c8 ("net: dsa: qca8k: disable delay for RGMII mode")
>> 
>> Yes looks like I messed up the commit id.. Not sure why :(
>> 
>> Dave would you like to drop this and me sending updated patch or
>> something else..
>> 
>> Sorry about the miss
>
>Doesn't work that way, something in my tree is there forever.

Would be good to have some robot checking "Fixes" sanity...


^ permalink raw reply

* [PATCH net-next] selftest/tls: Add test to verify received 'type' of non-data record
From: Vakul Garg @ 2019-02-20  8:43 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: borisp@mellanox.com, aviadye@mellanox.com, davejwatson@fb.com,
	davem@davemloft.net, doronrk@fb.com, Vakul Garg

Test case 'control_msg' has been updated to peek non-data record and
then verify the type of record received. Subsequently, the same record
is retrieved without MSG_PEEK flag in recvmsg().

Signed-off-by: Vakul Garg <vakul.garg@nxp.com>
---
 tools/testing/selftests/net/tls.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c
index 4ac50ccb3272..47ddfc154036 100644
--- a/tools/testing/selftests/net/tls.c
+++ b/tools/testing/selftests/net/tls.c
@@ -753,6 +753,20 @@ TEST_F(tls, control_msg)
 	EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1);
 
 	vec.iov_base = buf;
+	EXPECT_EQ(recvmsg(self->cfd, &msg, MSG_WAITALL | MSG_PEEK), send_len);
+
+	cmsg = CMSG_FIRSTHDR(&msg);
+	EXPECT_NE(cmsg, NULL);
+	EXPECT_EQ(cmsg->cmsg_level, SOL_TLS);
+	EXPECT_EQ(cmsg->cmsg_type, TLS_GET_RECORD_TYPE);
+	record_type = *((unsigned char *)CMSG_DATA(cmsg));
+	EXPECT_EQ(record_type, 100);
+	EXPECT_EQ(memcmp(buf, test_str, send_len), 0);
+
+	/* Recv the message again without MSG_PEEK */
+	record_type = 0;
+	memset(buf, 0, sizeof(buf));
+
 	EXPECT_EQ(recvmsg(self->cfd, &msg, MSG_WAITALL), send_len);
 	cmsg = CMSG_FIRSTHDR(&msg);
 	EXPECT_NE(cmsg, NULL);
-- 
2.13.6


^ permalink raw reply related

* Re: [PATCH net-next] net: udp Allow CHECKSUM_UNNECESSARY packets to do GRO.
From: maowenan @ 2019-02-20  8:32 UTC (permalink / raw)
  To: Tom Herbert
  Cc: Linux Kernel Network Developers, David S. Miller, Eric Dumazet
In-Reply-To: <CALx6S37fpFimxrQ1hfvhDs7ukOvNKmm1jHYmx00APYfif3-OMQ@mail.gmail.com>



On 2019/1/31 12:33, Tom Herbert wrote:
> On Wed, Jan 30, 2019 at 6:59 PM maowenan <maowenan@huawei.com> wrote:
>>
>>
>>
>> On 2019/1/31 10:43, Tom Herbert wrote:
>>> On Wed, Jan 30, 2019 at 5:58 PM maowenan <maowenan@huawei.com> wrote:
>>>>
>>>>
>>>>
>>>> On 2019/1/30 4:24, Tom Herbert wrote:
>>>>> On Tue, Jan 29, 2019 at 12:08 AM maowenan <maowenan@huawei.com> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 2019/1/29 14:24, Tom Herbert wrote:
>>>>>>> On Mon, Jan 28, 2019 at 10:04 PM maowenan <maowenan@huawei.com> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On 2019/1/29 12:01, Tom Herbert wrote:
>>>>>>>>> On Mon, Jan 28, 2019 at 7:00 PM maowenan <maowenan@huawei.com> wrote:
>>>>>>>>>>
>>>>>>>>>> Hi all,
>>>>>>>>>> Do you have any comments about this change?
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 2019/1/23 11:33, Mao Wenan wrote:
>>>>>>>>>>> When udp4_gro_receive() get one packet that uh->check=0,
>>>>>>>>>>> skb_gro_checksum_validate_zero_check() will set the
>>>>>>>>>>> skb->ip_summed = CHECKSUM_UNNECESSARY;
>>>>>>>>>>> skb->csum_level = 0;
>>>>>>>>>>> Then udp_gro_receive() will flush the packet which is not CHECKSUM_PARTIAL,
>>>>>>>>>>> It is not our expect,  because check=0 in udp header indicates this
>>>>>>>>>>> packet is no need to caculate checksum, we should go further to do GRO.
>>>>>>>>>>>
>>>>>>>>>>> This patch changes the value of csum_cnt according to skb->csum_level.
>>>>>>>>>>> ---
>>>>>>>>>>>  include/linux/netdevice.h | 1 +
>>>>>>>>>>>  1 file changed, 1 insertion(+)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>>>>>>>>>>> index 1377d08..9c819f1 100644
>>>>>>>>>>> --- a/include/linux/netdevice.h
>>>>>>>>>>> +++ b/include/linux/netdevice.h
>>>>>>>>>>> @@ -2764,6 +2764,7 @@ static inline void skb_gro_incr_csum_unnecessary(struct sk_buff *skb)
>>>>>>>>>>>                * during GRO. This saves work if we fallback to normal path.
>>>>>>>>>>>                */
>>>>>>>>>>>               __skb_incr_checksum_unnecessary(skb);
>>>>>>>>>>> +             NAPI_GRO_CB(skb)->csum_cnt = skb->csum_level + 1;
>>>>>>>>>
>>>>>>>>> That doesn't look right. This would be reinitializing the GRO
>>>>>>>>> checksums from the beginning.
>>>>>>>>>
>>>>>>>>>>>       }
>>>>>>>>>>>  }
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>> I assume the code is bailing on this conditional:
>>>>>>>>>
>>>>>>>>> if (NAPI_GRO_CB(skb)->encap_mark ||
>>>>>>>>>             (skb->ip_summed != CHECKSUM_PARTIAL &&
>>>>>>>>>              NAPI_GRO_CB(skb)->csum_cnt == 0 &&
>>>>>>>>>              !NAPI_GRO_CB(skb)->csum_valid) ||
>>>>>>>>>             !udp_sk(sk)->gro_receive)
>>>>>>>>>                 goto out_unlock;
>>>>>>>>>
>>>>>>>>> I am trying to remember why this needs to check csum_cnt. If there was
>>>>>>>>> a csum_cnt for the UDP csum being zero from checksum-unnecessary, it
>>>>>>>>> was consumed by skb_gro_checksum_validate_zero_check in UDP4 GRO
>>>>>>>>> received.
>>>>>>>>
>>>>>>>> We have met the scene about two VMs in different host with vxlan packets, when udp4_gro_receive receives
>>>>>>>> one packet with ip_summed=CHECKSUM_NONE,csum_cnt=0,csum_valid=0,and udp->check=0, then skb_gro_checksum_validate_zero_check()->
>>>>>>>> skb_gro_incr_csum_unnecessary() validate it and set ip_summed=CHECKSUM_UNNECESSARY,csum_level=0, but csum_cnt and csum_valid
>>>>>>>> keep zero value. Then it will be flushed in udp_gro_receive(), the codes as you have showed.
>>>>>>>>
>>>>>>>> so I think it forgets to modify csum_cnt since csum_level is changed in skb_gro_incr_csum_unnecessary()->__skb_incr_checksum_unnecessary().
>>>>>>>>
>>>>>>> Yes, but the csum_level is changing since we've gone beyond the
>>>>>>> checksums initially reported inc checksum-unnecessary. GRO csum_cnt is
>>>>>>> initialized to skb->csum_level + 1 at the start of GRO processing.
>>>>>>>
>>>>>>> If I recall, the rule is that UDP GRO requires at least one non-zero
>>>>>>> checksum to be verified. The idea is that if we end up computing
>>>>>>> packet checksums on the host for inner checksums like TCP during GRO,
>>>>>>> then that's negating the performance benefits of GRO. Had UDP check
>>>>>>> not been zero then we would do checksum unnecessary conversion and so
>>>>>>> csum_valid would be set for the remainded of GRO processing. The
>>>>>>> existing code is following the rule I believe, so this may be working
>>>>>>> as intended.
>>>>>>
>>>>>> Do you have any suggestion if I need do GRO as udp->check is zero?
>>>>>> My previous modification which works fine as below:
>>>>>>         if (NAPI_GRO_CB(skb)->encap_mark ||
>>>>>>             (skb->ip_summed != CHECKSUM_PARTIAL &&
>>>>>> +            skb->ip_summed != CHECKSUM_UNNECESSARY &&
>>>>>
>>>>> That's effectively disabling the rule that we need a real checksum
>>>>> calculation to proceed with GRO. Besides that, the device returning
>>>>> one checksum-unnecessary level because UDP csum is zero is pretty
>>>>> pointelss; we can just as easily deduce get to same state just by
>>>>> looking at the field with CHECKSUM_NONE. What we really want to see
>>>>> for GRO is a real checksum computation being done on the packet.
>>>>>
>>>>> A few questions:
>>>>>
>>>>> What type of packets are being GROed? Are these TCP? What performance
>>>>> difference do you see with our patch? Can you try enabling UDP
>>>>> checksums, and even RCO with VXLAN? With UDP encapsulation we
>>>>> generally see better performance with checksum enabled since UDP
>>>>> checksum offload is ubiquitous and we can easily convert
>>>>> checksum-unnecessary (with non-zero csum) to checksum-complete.
>>>>
>>>> We use the physical network card calculate the checksum of the inner packet with checksum offload.
>>>> Set the udp checksum of the vxlan header is 0.
>>>>
>>> I see. It sounds like the device is really verifying two checksums in
>>> the packet, the outer UDP checksum (which is zero for UDP) and an
>>> inner checksum, but only reporting one checksum was verified. The
>>> driver needs to set csum_level to 1 in this case (meaning two
>>> checksums have been verified for checksum-unnecessary). What NIC are
>>> you using?
>>
>> Currently it is 82599, whose driver can't recognize the vxlan packet.
>> I guess so many NICs can't do this checking in it's driver, so I think this is a
>> common case, will we fix it in stack?
>>
> Mao,
> 
> The problem isn't in the stack, it seems to be in the driver. If the
> device reports a verified checksum for an encpasulated packet then the
> driver needs to set csum_level to 1. Otherwise, the stack can't just
> assume that the inner checksum was verified. *How* a driver deduces
> that the device is reporting about an encapsulated checksum is
> specific to the device and its driver. I'm not sure which driver your
> running, but if you search the code there should be something like
> "skb->csum_level =1" that would be a clue about support. A good
> example is ixgbe, if the device reports checksum verified and that
> packet was VXLAN, it deduces that the inner checksum was verified and
> so the driver sets CHECKSUM_UNNECESSARY and skb->csum_level. Of course
> all this complexity goes away when devices just provide
> checksum-complete.
> 
> Tom

Hi Tom,

I have checked code in ixgbe_main.c ixgbe_rx_checksum(). UDP frames with a 0 checksum can be marked as
checksum errors. If it returns here, skb->ip_summed will be set to CHECKSUM_NONE.
Then the packet will be flush to stack in udp_gro_receive().
Do you think whether it is the fault of driver or not?

ixgbe_rx_checksum():
	if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_TCPE)) {
		/*
		 * 82599 errata, UDP frames with a 0 checksum can be marked as
		 * checksum errors.
		 */
		if ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_UDP)) &&
		    test_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state))
			return;

		ring->rx_stats.csum_err++;
		return;
	}

udp_gro_receive():
if (NAPI_GRO_CB(skb)->encap_mark ||
	    (skb->ip_summed != CHECKSUM_PARTIAL &&
	     NAPI_GRO_CB(skb)->csum_cnt == 0 &&
	     !NAPI_GRO_CB(skb)->csum_valid) ||
	    !udp_sk(sk)->gro_receive)
		goto out_unlock;

> 
>>>
>>> Tom
>>>
>>>
>>>> With this patch, the bandwidth of TCP between two VMs increase from 2Gbit/s to 6Gbit/s.
>>>>
>>>>>
>>>>> Tom
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>              NAPI_GRO_CB(skb)->csum_cnt == 0 &&
>>>>>>              !NAPI_GRO_CB(skb)->csum_valid) ||
>>>>>>             !udp_sk(sk)->gro_receive)
>>>>>>                 goto out_unlock;
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> Tom
>>>>>>>
>>>>>>>>>
>>>>>>>>> .
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>> .
>>>>>>>
>>>>>>
>>>>>
>>>>> .
>>>>>
>>>>
>>>
>>> .
>>>
>>
> 
> .
> 


^ permalink raw reply

* Re: [PATCH 0/2] ARM: dts: am335x-evm/evmsk: Fix PHY mode for ethernet
From: Peter Ujfalusi @ 2019-02-20  8:30 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: bcousson, linux-omap, devicetree, linux-arm-kernel, nsekhar,
	grygorii.strashko, vkoul, netdev, f.fainelli, marc.w.gonzalez,
	niklas.cassel
In-Reply-To: <20190219165231.GK15711@atomide.com>

Hi Tony,

On 19/02/2019 18.52, Tony Lindgren wrote:
> * Peter Ujfalusi <peter.ujfalusi@ti.com> [190219 08:02]:
>> On 18/02/2019 18.26, Tony Lindgren wrote:
>>> OK so sounds like these are OK to wait for v5.1 merge window
>>> then as the dts changes alone won't fix anything?
>>
>> I think it would be better to send these to 5.0 to avoid the regression
>> siting in linux-next.
>>
>> The patches are actually doing to the correct thing (we need rgmii-id,
>> not rmgii-txid for these boards).
>> It was just a matter of luck that it worked with rgmii-txid as the
>> driver was broken and did not disabled the rxid when it should have.
> 
> OK applying into omap-for-v5.0/fixes-v2. I'll send a pull
> request on Thursday most likely then, let's see if it makes
> it for v5.0.

Thank you!

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

^ permalink raw reply

* [PATCH net] net: ip6_gre: fix possible NULL pointer dereference in ip6erspan_set_version
From: Lorenzo Bianconi @ 2019-02-20  8:23 UTC (permalink / raw)
  To: davem; +Cc: netdev, syzbot+30191cf1057abd3064af
In-Reply-To: <cover.1550620650.git.lorenzo.bianconi@redhat.com>

Fix a possible NULL pointer dereference in ip6erspan_set_version checking
nlattr data pointer

kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] PREEMPT SMP KASAN
CPU: 1 PID: 7549 Comm: syz-executor432 Not tainted 5.0.0-rc6-next-20190218  
#37
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011
RIP: 0010:ip6erspan_set_version+0x5c/0x350 net/ipv6/ip6_gre.c:1726
Code: 07 38 d0 7f 08 84 c0 0f 85 9f 02 00 00 49 8d bc 24 b0 00 00 00 c6 43  
54 01 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f  
85 9a 02 00 00 4d 8b ac 24 b0 00 00 00 4d 85 ed 0f
RSP: 0018:ffff888089ed7168 EFLAGS: 00010202
RAX: dffffc0000000000 RBX: ffff8880869d6e58 RCX: 0000000000000000
RDX: 0000000000000016 RSI: ffffffff862736b4 RDI: 00000000000000b0
RBP: ffff888089ed7180 R08: 1ffff11010d3adcb R09: ffff8880869d6e58
R10: ffffed1010d3add5 R11: ffff8880869d6eaf R12: 0000000000000000
R13: ffffffff8931f8c0 R14: ffffffff862825d0 R15: ffff8880869d6e58
FS:  0000000000b3d880(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000184 CR3: 0000000092cc5000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
  ip6erspan_newlink+0x66/0x7b0 net/ipv6/ip6_gre.c:2210
  __rtnl_newlink+0x107b/0x16c0 net/core/rtnetlink.c:3176
  rtnl_newlink+0x69/0xa0 net/core/rtnetlink.c:3234
  rtnetlink_rcv_msg+0x465/0xb00 net/core/rtnetlink.c:5192
  netlink_rcv_skb+0x17a/0x460 net/netlink/af_netlink.c:2485
  rtnetlink_rcv+0x1d/0x30 net/core/rtnetlink.c:5210
  netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline]
  netlink_unicast+0x536/0x720 net/netlink/af_netlink.c:1336
  netlink_sendmsg+0x8ae/0xd70 net/netlink/af_netlink.c:1925
  sock_sendmsg_nosec net/socket.c:621 [inline]
  sock_sendmsg+0xdd/0x130 net/socket.c:631
  ___sys_sendmsg+0x806/0x930 net/socket.c:2136
  __sys_sendmsg+0x105/0x1d0 net/socket.c:2174
  __do_sys_sendmsg net/socket.c:2183 [inline]
  __se_sys_sendmsg net/socket.c:2181 [inline]
  __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2181
  do_syscall_64+0x103/0x610 arch/x86/entry/common.c:290
  entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x440159
Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7  
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff  
ff 0f 83 fb 13 fc ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007fffa69156e8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 0000000000440159
RDX: 0000000000000000 RSI: 0000000020001340 RDI: 0000000000000003
RBP: 00000000006ca018 R08: 0000000000000001 R09: 00000000004002c8
R10: 0000000000000011 R11: 0000000000000246 R12: 00000000004019e0
R13: 0000000000401a70 R14: 0000000000000000 R15: 0000000000000000
Modules linked in:
---[ end trace 09f8a7d13b4faaa1 ]---
RIP: 0010:ip6erspan_set_version+0x5c/0x350 net/ipv6/ip6_gre.c:1726
Code: 07 38 d0 7f 08 84 c0 0f 85 9f 02 00 00 49 8d bc 24 b0 00 00 00 c6 43  
54 01 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f  
85 9a 02 00 00 4d 8b ac 24 b0 00 00 00 4d 85 ed 0f
RSP: 0018:ffff888089ed7168 EFLAGS: 00010202
RAX: dffffc0000000000 RBX: ffff8880869d6e58 RCX: 0000000000000000
RDX: 0000000000000016 RSI: ffffffff862736b4 RDI: 00000000000000b0
RBP: ffff888089ed7180 R08: 1ffff11010d3adcb R09: ffff8880869d6e58
R10: ffffed1010d3add5 R11: ffff8880869d6eaf R12: 0000000000000000
R13: ffffffff8931f8c0 R14: ffffffff862825d0 R15: ffff8880869d6e58
FS:  0000000000b3d880(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000184 CR3: 0000000092cc5000 CR4: 00000000001406e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400


Fixes: 4974d5f678ab ("net: ip6_gre: initialize erspan_ver just for erspan tunnels")
Reported-and-tested-by: syzbot+30191cf1057abd3064af@syzkaller.appspotmail.com
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
 net/ipv6/ip6_gre.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 43890898b0b5..4b9dd5e88329 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -1722,6 +1722,9 @@ static int ip6erspan_tap_validate(struct nlattr *tb[], struct nlattr *data[],
 static void ip6erspan_set_version(struct nlattr *data[],
 				  struct __ip6_tnl_parm *parms)
 {
+	if (!data)
+		return;
+
 	parms->erspan_ver = 1;
 	if (data[IFLA_GRE_ERSPAN_VER])
 		parms->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]);
-- 
2.20.1


^ permalink raw reply related

* [PATCH net v2] team: use operstate consistently for linkup
From: George Wilkie @ 2019-02-20  8:19 UTC (permalink / raw)
  To: Jiri Pirko, David S. Miller; +Cc: netdev

When a port is added to a team, its initial state is derived
from netif_carrier_ok rather than netif_oper_up.
If it is carrier up but operationally down at the time of being
added, the port state.linkup will be set prematurely.
port state.linkup should be set consistently using
netif_oper_up rather than netif_carrier_ok.

Fixes: f1d22a1e0595 ("team: account for oper state")
Signed-off-by: George Wilkie <gwilkie@vyatta.att-mail.com>
---
 drivers/net/team/team.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 958f1cf67282..6ce3f666d142 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1256,7 +1256,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
 	list_add_tail_rcu(&port->list, &team->port_list);
 	team_port_enable(team, port);
 	__team_compute_features(team);
-	__team_port_change_port_added(port, !!netif_carrier_ok(port_dev));
+	__team_port_change_port_added(port, !!netif_oper_up(port_dev));
 	__team_options_change_check(team);
 
 	netdev_info(dev, "Port device %s added\n", portname);
@@ -2915,7 +2915,7 @@ static int team_device_event(struct notifier_block *unused,
 
 	switch (event) {
 	case NETDEV_UP:
-		if (netif_carrier_ok(dev))
+		if (netif_oper_up(dev))
 			team_port_change_check(port, true);
 		break;
 	case NETDEV_DOWN:
-- 
2.11.0


^ permalink raw reply related

* Re: [RFC PATCH net-next v3 05/21] ethtool: netlink bitset handling
From: Michal Kubecek @ 2019-02-20  8:16 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: netdev, David Miller, Andrew Lunn, Jiri Pirko, linux-kernel
In-Reply-To: <20190219182759.0abf08ae@cakuba.netronome.com>

On Tue, Feb 19, 2019 at 06:27:59PM -0800, Jakub Kicinski wrote:
> On Mon, 18 Feb 2019 19:21:49 +0100 (CET), Michal Kubecek wrote:
> > +		else if (is_u32)
> > +			bitmap_from_arr32(val, bitmap, nbits);
> > +		else
> > +			bitmap_copy(val, bitmap, nbits);
> > +		nla_for_each_nested(bit_attr, tb[ETHA_BITSET_BITS], rem) {
> > +			*err = ethnl_update_bit(val, mask, nbits, bit_attr,
> > +						is_list, names, legacy, info);
> > +			if (*err < 0)
> > +				goto out_free;
> > +		}
> > +		if (bitmask)
> > +			__bitmap_to_any(bitmask, mask, nbits, is_u32);
> > +	} else {
> > +		unsigned int change_words = DIV_ROUND_UP(change_bits, 32);
> > +
> > +		*err = 0;
> > +		if (change_bits == 0 && tb[ETHA_BITSET_MASK])
> > +			goto out_free;
> > +		*err = -EINVAL;
> > +		if (!tb[ETHA_BITSET_VALUE])
> > +			goto out_free;
> 
> !tb[ETHA_BITSET_BITS] && !tb[ETHA_BITSET_VALUE] is already rejected
> above.

Thank you. I'll drop this test.

Michal

^ permalink raw reply

* Re: [PATCH net] mlxsw: __mlxsw_sp_port_headroom_set(): Fix a use of local variable
From: Ido Schimmel @ 2019-02-20  8:12 UTC (permalink / raw)
  To: David Miller; +Cc: netdev@vger.kernel.org, Jiri Pirko, Petr Machata, mlxsw
In-Reply-To: <20190219.103338.1703676672870024906.davem@davemloft.net>

On Tue, Feb 19, 2019 at 10:33:38AM -0800, David Miller wrote:
> From: Ido Schimmel <idosch@mellanox.com>
> Date: Tue, 19 Feb 2019 09:30:31 +0000
> 
> > We have a series for net-next that adds support for Spectrum-2 shared
> > buffers and it depends on this patch. I was wondering if you could merge
> > net into net-next today or later this week, so that we could submit it.
> > 
> > Normally I would just wait for the merge to happen, but it looks like
> > this is going to be the last week to submit changes and I prefer not to
> > miss the window while waiting for the inevitable merge.
> > 
> > Thanks and sorry about the noise.
> 
> Ido, I will send Linus a pull request today and he should pull it in and
> I should therefore be able to get net-next sync'd with it by the end of
> tomorrow.

Great, thanks!

^ permalink raw reply

* Re: Handling an Extra Signal at PHY Reset
From: Thomas Petazzoni @ 2019-02-20  8:06 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Paul Kocialkowski, Florian Fainelli, Heiner Kallweit, netdev,
	Mylène Josserand
In-Reply-To: <20190219133629.GN14879@lunn.ch>

On Tue, 19 Feb 2019 14:36:29 +0100
Andrew Lunn <andrew@lunn.ch> wrote:

> This seems like an odd design. I've normally seen weak pull up/down
> resistors, not a switch, so i'm wondering why it is designed like
> this.

The key point here is that this "CONFIG" pin of the PHY is used during
reset to configure the PHY, but then once the reset sequence is
finished, this pin is used for PTP. From the datasheet, section 2.28.1
"PTP Control":

"""
To support the PTP Time Stamping function, the device has four pins
that are global to the entire PHY:

- PTP clock input pin (The CONFIG pin is used for this purpose.)
- PTP Event Request input pin (The LED[1] pin is used for this purpose)
- PTP Event Request input pin (The LED[1] pin is used for this purpose)
- Interrupt Pin (The LED[2] pin is used for this purpose)
"""

A bit further down in the datasheet:

"After configuration is completed and the external clock source is
enabled, the CONFIG pin is used as the external 125 Mhz reference clock
input"

So that's why our design as a switch: it allows the CONFIG pin to be
used for configuration during the reset sequence, and then as the pin
for the PTP clock input.

Does that clarify why the CONFIG pin is not simply connected to some
static pull-up/pull-down ?

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* Re: Possible bug into DSA2 code.
From: Rodolfo Giometti @ 2019-02-20  7:54 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: Florian Fainelli, Vivien Didelot, David S. Miller, netdev
In-Reply-To: <20190219000340.GJ14879@lunn.ch>

On 19/02/2019 01:03, Andrew Lunn wrote:
>> diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
>> index 54a5b660640a..bb46ebbb2bb8 100644
>> --- a/drivers/net/dsa/mv88e6xxx/chip.c
>> +++ b/drivers/net/dsa/mv88e6xxx/chip.c
>> @@ -2399,7 +2399,7 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
>>          int i;
>>
>>          chip->ds = ds;
>> -       ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip);
>> +       ds->slave_mii_bus = NULL;
>>
>>          mutex_lock(&chip->reg_lock);
>>
>> Is that right?
> 
> Hi Rodolfo
> 
> Humm, that needs testing. There are two used combinations you need to
> test:
> 
> No MDIO node in device tree, e.g.
> arch/arm/boot/dts/kirkwood-dir665.dts
> 
> MDIO node in device tree, e.g:
> arch/arm/boot/dts/vf610-zii-dev-rev-b.dts

I'm sorry but I haven't such boards... :'(

> There is a third combination which will appear soon. There is only the
> external mdio bus in device tree:
> 
>                                  port@9 {
>                                          reg = <9>;
>                                          label = "eth_cu_1000_2";
>                                          phy-handle = <&phy9>;
>                                          phy-mode = "sgmii";
>                                          managed = "in-band-status";
>                                  };
>                          };
> 
>                          mdio1 {
>                                  compatible = "marvell,mv88e6xxx-mdio-external";
>                                  #address-cells = <1>;
>                                  #size-cells = <0>;
> 
>                                  phy9: phy9@0 {
>                                          compatible = "ethernet-phy-ieee802.3-c45";
>                                          pinctrl-0 = <&pinctrl_gpio_phy9>;
>                                          pinctrl-names = "default";
>                                          interrupt-parent = <&gpio2>;
>                                          interrupts = <30 IRQ_TYPE_LEVEL_LOW>;
>                                          reg = <0>;
>                                  };
>                          };
> 
> Here port 9 uses the external MDIO bus and all the other ports
> implicitly make use of the internal MDIO bus.

Mmm... maybe should code into drivers/net/dsa/mv88e6xxx use private data to hold 
used mdio busses instead of ds->slave_mii_bus pointer?

Ciao,

Rodolfo

-- 
GNU/Linux Solutions                  e-mail: giometti@enneenne.com
Linux Device Driver                          giometti@linux.it
Embedded Systems                     phone:  +39 349 2432127
UNIX programming                     skype:  rodolfo.giometti

^ permalink raw reply

* Re: [RFC v1 15/19] RDMA/irdma: Add miscellaneous utility definitions
From: Leon Romanovsky @ 2019-02-20  7:51 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Shiraz Saleem, dledford, davem, linux-rdma, netdev,
	mustafa.ismail, jeffrey.t.kirsher
In-Reply-To: <20190215174714.GE30706@ziepe.ca>

[-- Attachment #1: Type: text/plain, Size: 2538 bytes --]

On Fri, Feb 15, 2019 at 10:47:14AM -0700, Jason Gunthorpe wrote:
> On Fri, Feb 15, 2019 at 11:11:02AM -0600, Shiraz Saleem wrote:
> > From: Mustafa Ismail <mustafa.ismail@intel.com>
> >
> > Add miscellaneous utility functions and headers.
> >
> > Signed-off-by: Mustafa Ismail <mustafa.ismail@intel.com>
> > Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com>
> >  drivers/infiniband/hw/irdma/osdep.h  |  153 ++
> >  drivers/infiniband/hw/irdma/protos.h |  118 ++
> >  drivers/infiniband/hw/irdma/status.h |   70 +
> >  drivers/infiniband/hw/irdma/utils.c  | 2565 ++++++++++++++++++++++++++++++++++
> >  4 files changed, 2906 insertions(+)
> >  create mode 100644 drivers/infiniband/hw/irdma/osdep.h
> >  create mode 100644 drivers/infiniband/hw/irdma/protos.h
> >  create mode 100644 drivers/infiniband/hw/irdma/status.h
> >  create mode 100644 drivers/infiniband/hw/irdma/utils.c
> >
> > diff --git a/drivers/infiniband/hw/irdma/osdep.h b/drivers/infiniband/hw/irdma/osdep.h
> > new file mode 100644
> > index 0000000..ade5536
> > +++ b/drivers/infiniband/hw/irdma/osdep.h
> > @@ -0,0 +1,153 @@
> > +/* SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB */
> > +/* Copyright (c) 2019, Intel Corporation. */
> > +
> > +#ifndef IRDMA_OSDEP_H
> > +#define IRDMA_OSDEP_H
> > +
> > +#include <linux/version.h>
> > +#include <linux/kernel.h>
> > +#include <linux/vmalloc.h>
> > +#include <linux/string.h>
> > +#include <linux/bitops.h>
> > +#include <linux/pci.h>
> > +#include <net/tcp.h>
> > +#include <crypto/hash.h>
> > +/* get readq/writeq support for 32 bit kernels, use the low-first version */
> > +#include <linux/io-64-nonatomic-lo-hi.h>
> > +
> > +#define STATS_TIMER_DELAY	60000
> > +#define MAKEMASK(m, s)		((m) << (s))

Really? Abstraction for "<<"?

> > +
> > +#define irdma_pr_err(fmt, args ...)				\
> > +	pr_err("%s: "fmt, __func__, ## args)
> > +
> > +#define irdma_pr_info(fmt, args ...)				\
> > +	pr_info("%s: " fmt, __func__, ## args)
> > +
> > +#define irdma_pr_warn(fmt, args ...)				\
> > +	pr_warn("%s: " fmt, __func__, ## args)
> > +
> > +#define irdma_dev_err(dev, fmt, args ...)			\
> > +	dev_err(to_device(dev), "%s: "fmt, __func__, ## args)
> > +
> > +#define irdma_dev_info(dev, fmt, args ...)			\
> > +	dev_info(to_device(dev), "%s: "fmt, __func__, ## args)
> > +
> > +#define irdma_dev_warn(dev, fmt, args ...)			\
> > +	dev_warn(to_device(dev), "%s: "fmt, __func__, ## args)
>
> Does every driver really have to define these macros?

Every time when I see it, I'm asking myself the same question.

Thanks

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply

* [PATCH iproute2-next v1 15/19] rdma: Separate PD code
From: Leon Romanovsky @ 2019-02-20  7:21 UTC (permalink / raw)
  To: David Ahern; +Cc: Leon Romanovsky, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <20190220072136.3840-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/res-pd.c | 170 ++++++++++++++++++++++++++------------------------
 1 file changed, 89 insertions(+), 81 deletions(-)

diff --git a/rdma/res-pd.c b/rdma/res-pd.c
index 24ac7f1b..3c9ffa4e 100644
--- a/rdma/res-pd.c
+++ b/rdma/res-pd.c
@@ -7,11 +7,95 @@
 #include "res.h"
 #include <inttypes.h>
 
+static int res_pd_line(struct rd *rd, const char *name, int idx,
+		       struct nlattr *nla_entry)
+{
+	uint32_t local_dma_lkey = 0, unsafe_global_rkey = 0;
+	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+	char *comm = NULL;
+	uint32_t ctxn = 0;
+	uint32_t pid = 0;
+	uint32_t pdn = 0;
+	uint64_t users;
+	int err;
+
+	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+	if (err != MNL_CB_OK)
+		return MNL_CB_ERROR;
+
+	if (!nla_line[RDMA_NLDEV_ATTR_RES_USECNT] ||
+	    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
+	     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
+		return MNL_CB_ERROR;
+	}
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY])
+		local_dma_lkey = mnl_attr_get_u32(
+			nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY]);
+
+	users = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_USECNT]);
+	if (rd_check_is_filtered(rd, "users", users))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY])
+		unsafe_global_rkey = mnl_attr_get_u32(
+			nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY]);
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
+		pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]);
+		comm = get_task_name(pid);
+	}
+
+	if (rd_check_is_filtered(rd, "pid", pid))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
+		ctxn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
+
+	if (rd_check_is_filtered(rd, "ctxn", ctxn))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
+		pdn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
+	if (rd_check_is_filtered(rd, "pdn", pdn))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
+		/* discard const from mnl_attr_get_str */
+		comm = (char *)mnl_attr_get_str(
+			nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
+
+	if (rd->json_output)
+		jsonw_start_array(rd->jw);
+
+	print_dev(rd, idx, name);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY])
+		print_key(rd, "local_dma_lkey", local_dma_lkey);
+	res_print_uint(rd, "users", users);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY])
+		print_key(rd, "unsafe_global_rkey", unsafe_global_rkey);
+	res_print_uint(rd, "pid", pid);
+	print_comm(rd, comm, nla_line);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
+		res_print_uint(rd, "ctxn", ctxn);
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
+		res_print_uint(rd, "pdn", pdn);
+
+	print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
+	newline(rd);
+
+out:	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
+		free(comm);
+	return MNL_CB_OK;
+}
+
 int res_pd_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
 	struct nlattr *nla_table, *nla_entry;
 	struct rd *rd = data;
+	int ret = MNL_CB_OK;
 	const char *name;
 	uint32_t idx;
 
@@ -25,86 +109,10 @@ int res_pd_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_PD];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		uint32_t local_dma_lkey = 0, unsafe_global_rkey = 0;
-		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
-		char *comm = NULL;
-		uint32_t ctxn = 0;
-		uint32_t pid = 0;
-		uint32_t pdn = 0;
-		uint64_t users;
-		int err;
-
-		err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-		if (err != MNL_CB_OK)
-			return MNL_CB_ERROR;
-
-		if (!nla_line[RDMA_NLDEV_ATTR_RES_USECNT] ||
-		    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
-		     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
-			return MNL_CB_ERROR;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY])
-			local_dma_lkey = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY]);
-
-		users = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_USECNT]);
-		if (rd_check_is_filtered(rd, "users", users))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY])
-			unsafe_global_rkey = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY]);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
-			pid = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_PID]);
-			comm = get_task_name(pid);
-		}
-
-		if (rd_check_is_filtered(rd, "pid", pid))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
-			ctxn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
-
-		if (rd_check_is_filtered(rd, "ctxn", ctxn))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
-			pdn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
-		if (rd_check_is_filtered(rd, "pdn", pdn))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
-			/* discard const from mnl_attr_get_str */
-			comm = (char *)mnl_attr_get_str(
-				nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
-
-		if (rd->json_output)
-			jsonw_start_array(rd->jw);
-
-		print_dev(rd, idx, name);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY])
-			print_key(rd, "local_dma_lkey", local_dma_lkey);
-		res_print_uint(rd, "users", users);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY])
-			print_key(rd, "unsafe_global_rkey", unsafe_global_rkey);
-		res_print_uint(rd, "pid", pid);
-		print_comm(rd, comm, nla_line);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
-			res_print_uint(rd, "ctxn", ctxn);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
-			res_print_uint(rd, "pdn", pdn);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
-			free(comm);
-
-		print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
-		newline(rd);
+		ret = res_pd_line(rd, name, idx, nla_entry);
+
+		if (ret != MNL_CB_OK)
+			break;
 	}
-	return MNL_CB_OK;
+	return ret;
 }
-- 
2.19.1


^ permalink raw reply related

* [PATCH iproute2-next v1 19/19] rdma: Provide and reuse filter functions
From: Leon Romanovsky @ 2019-02-20  7:21 UTC (permalink / raw)
  To: David Ahern; +Cc: Leon Romanovsky, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <20190220072136.3840-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

Globally replace all filter function in safer variants of those
is_filterred functions, which take into account the availability/lack
of netlink attributes.

Such conversion allowed to fix a number of places in the code, where
the previous implementation didn't honor filter requests if netlink
attribute wasn't present.

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/rdma.h     |  7 +++---
 rdma/res-cmid.c | 57 +++++++++++++++++++++++++++----------------------
 rdma/res-cq.c   | 22 +++++++++++--------
 rdma/res-mr.c   | 12 +++++++----
 rdma/res-pd.c   | 12 +++++++----
 rdma/res-qp.c   | 53 ++++++++++++++++++++++-----------------------
 rdma/utils.c    | 26 ++++++++++++++++++----
 7 files changed, 112 insertions(+), 77 deletions(-)

diff --git a/rdma/rdma.h b/rdma/rdma.h
index e86c7f21..1022e9a2 100644
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -110,9 +110,10 @@ struct dev_map *dev_map_lookup(struct rd *rd, bool allow_port_index);
  */
 bool rd_doit_index(struct rd *rd, uint32_t *idx);
 int rd_build_filter(struct rd *rd, const struct filters valid_filters[]);
-bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val);
-bool rd_check_is_string_filtered(struct rd *rd, const char *key, const char *val);
-bool rd_check_is_key_exist(struct rd *rd, const char *key);
+bool rd_is_filtered_attr(struct rd *rd, const char *key, uint32_t val,
+			 struct nlattr *attr);
+bool rd_is_string_filtered_attr(struct rd *rd, const char *key, const char *val,
+				struct nlattr *attr);
 /*
  * Netlink
  */
diff --git a/rdma/res-cmid.c b/rdma/res-cmid.c
index 0b61e433..0b830088 100644
--- a/rdma/res-cmid.c
+++ b/rdma/res-cmid.c
@@ -132,57 +132,64 @@ static int res_cm_id_line(struct rd *rd, const char *name, int idx,
 	if (port && port != rd->port_idx)
 		goto out;
 
-	if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN]) {
+	if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN])
 		lqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
-		if (rd_check_is_filtered(rd, "lqpn", lqpn))
-			goto out;
-	}
-	if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE]) {
+
+	if (rd_is_filtered_attr(rd, "lqpn", lqpn,
+				nla_line[RDMA_NLDEV_ATTR_RES_LQPN]))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE])
 		type = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_TYPE]);
-		if (rd_check_is_string_filtered(rd, "qp-type",
-						qp_types_to_str(type)))
-			goto out;
-	}
+	if (rd_is_string_filtered_attr(rd, "qp-type", qp_types_to_str(type),
+				       nla_line[RDMA_NLDEV_ATTR_RES_TYPE]))
+		goto out;
 
 	ps = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PS]);
-	if (rd_check_is_string_filtered(rd, "ps", cm_id_ps_to_str(ps)))
+	if (rd_is_string_filtered_attr(rd, "ps", cm_id_ps_to_str(ps),
+				       nla_line[RDMA_NLDEV_ATTR_RES_PS]))
 		goto out;
 
 	state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]);
-	if (rd_check_is_string_filtered(rd, "state", cm_id_state_to_str(state)))
+	if (rd_is_string_filtered_attr(rd, "state", cm_id_state_to_str(state),
+				       nla_line[RDMA_NLDEV_ATTR_RES_STATE]))
 		goto out;
 
-	if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]) {
+	if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR])
 		if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR],
 			    src_addr_str, &src_port))
 			goto out;
-		if (rd_check_is_string_filtered(rd, "src-addr", src_addr_str))
-			goto out;
-		if (rd_check_is_filtered(rd, "src-port", src_port))
-			goto out;
-	}
+	if (rd_is_string_filtered_attr(rd, "src-addr", src_addr_str,
+				       nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]))
+		goto out;
+	if (rd_is_filtered_attr(rd, "src-port", src_port,
+				nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]))
+		goto out;
 
-	if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]) {
+	if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR])
 		if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR],
 			    dst_addr_str, &dst_port))
 			goto out;
-		if (rd_check_is_string_filtered(rd, "dst-addr", dst_addr_str))
-			goto out;
-		if (rd_check_is_filtered(rd, "dst-port", dst_port))
-			goto out;
-	}
+	if (rd_is_string_filtered_attr(rd, "dst-addr", dst_addr_str,
+				       nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]))
+		goto out;
+	if (rd_is_filtered_attr(rd, "dst-port", dst_port,
+				nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]))
+		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
 		pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]);
 		comm = get_task_name(pid);
 	}
 
-	if (rd_check_is_filtered(rd, "pid", pid))
+	if (rd_is_filtered_attr(rd, "pid", pid,
+				nla_line[RDMA_NLDEV_ATTR_RES_PID]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])
 		cm_idn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]);
-	if (rd_check_is_filtered(rd, "cm-idn", cm_idn))
+	if (rd_is_filtered_attr(rd, "cm-idn", cm_idn,
+				nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) {
diff --git a/rdma/res-cq.c b/rdma/res-cq.c
index c14637e6..5afb97c5 100644
--- a/rdma/res-cq.c
+++ b/rdma/res-cq.c
@@ -51,32 +51,36 @@ static int res_cq_line(struct rd *rd, const char *name, int idx,
 	cqe = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CQE]);
 
 	users = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_USECNT]);
-	if (rd_check_is_filtered(rd, "users", users))
+	if (rd_is_filtered_attr(rd, "users", users,
+				nla_line[RDMA_NLDEV_ATTR_RES_USECNT]))
 		goto out;
 
-	if (nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX]) {
+	if (nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX])
 		poll_ctx =
 			mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX]);
-		if (rd_check_is_string_filtered(rd, "poll-ctx",
-						poll_ctx_to_str(poll_ctx)))
-			goto out;
-	}
+	if (rd_is_string_filtered_attr(rd, "poll-ctx",
+				       poll_ctx_to_str(poll_ctx),
+				       nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX]))
+		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
 		pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]);
 		comm = get_task_name(pid);
 	}
 
-	if (rd_check_is_filtered(rd, "pid", pid))
+	if (rd_is_filtered_attr(rd, "pid", pid,
+				nla_line[RDMA_NLDEV_ATTR_RES_PID]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_CQN])
 		cqn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CQN]);
-	if (rd_check_is_filtered(rd, "cqn", cqn))
+	if (rd_is_filtered_attr(rd, "cqn", cqn,
+				nla_line[RDMA_NLDEV_ATTR_RES_CQN]))
 		goto out;
 	if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
 		ctxn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
-	if (rd_check_is_filtered(rd, "ctxn", ctxn))
+	if (rd_is_filtered_attr(rd, "ctxn", ctxn,
+				nla_line[RDMA_NLDEV_ATTR_RES_CTXN]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
diff --git a/rdma/res-mr.c b/rdma/res-mr.c
index d42e8d81..f4a24dc1 100644
--- a/rdma/res-mr.c
+++ b/rdma/res-mr.c
@@ -31,7 +31,8 @@ static int res_mr_line(struct rd *rd, const char *name, int idx,
 		iova = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_IOVA]);
 
 	mrlen = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_MRLEN]);
-	if (rd_check_is_filtered(rd, "mrlen", mrlen))
+	if (rd_is_filtered_attr(rd, "mrlen", mrlen,
+				nla_line[RDMA_NLDEV_ATTR_RES_MRLEN]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
@@ -39,17 +40,20 @@ static int res_mr_line(struct rd *rd, const char *name, int idx,
 		comm = get_task_name(pid);
 	}
 
-	if (rd_check_is_filtered(rd, "pid", pid))
+	if (rd_is_filtered_attr(rd, "pid", pid,
+				nla_line[RDMA_NLDEV_ATTR_RES_PID]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_MRN])
 		mrn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_MRN]);
-	if (rd_check_is_filtered(rd, "mrn", mrn))
+	if (rd_is_filtered_attr(rd, "mrn", mrn,
+				nla_line[RDMA_NLDEV_ATTR_RES_MRN]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
 		pdn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
-	if (rd_check_is_filtered(rd, "pdn", pdn))
+	if (rd_is_filtered_attr(rd, "pdn", pdn,
+				nla_line[RDMA_NLDEV_ATTR_RES_PDN]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
diff --git a/rdma/res-pd.c b/rdma/res-pd.c
index 956d4d9f..07c836e8 100644
--- a/rdma/res-pd.c
+++ b/rdma/res-pd.c
@@ -28,7 +28,8 @@ static int res_pd_line(struct rd *rd, const char *name, int idx,
 			nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY]);
 
 	users = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_USECNT]);
-	if (rd_check_is_filtered(rd, "users", users))
+	if (rd_is_filtered_attr(rd, "users", users,
+				nla_line[RDMA_NLDEV_ATTR_RES_USECNT]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY])
@@ -40,18 +41,21 @@ static int res_pd_line(struct rd *rd, const char *name, int idx,
 		comm = get_task_name(pid);
 	}
 
-	if (rd_check_is_filtered(rd, "pid", pid))
+	if (rd_is_filtered_attr(rd, "pid", pid,
+				nla_line[RDMA_NLDEV_ATTR_RES_PID]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
 		ctxn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
 
-	if (rd_check_is_filtered(rd, "ctxn", ctxn))
+	if (rd_is_filtered_attr(rd, "ctxn", ctxn,
+				nla_line[RDMA_NLDEV_ATTR_RES_CTXN]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
 		pdn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
-	if (rd_check_is_filtered(rd, "pdn", pdn))
+	if (rd_is_filtered_attr(rd, "pdn", pdn,
+				nla_line[RDMA_NLDEV_ATTR_RES_PDN]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
diff --git a/rdma/res-qp.c b/rdma/res-qp.c
index ac9976fc..954e465d 100644
--- a/rdma/res-qp.c
+++ b/rdma/res-qp.c
@@ -103,53 +103,49 @@ static int res_qp_line(struct rd *rd, const char *name, int idx,
 		goto out;
 
 	lqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
-	if (rd_check_is_filtered(rd, "lqpn", lqpn))
+	if (rd_is_filtered_attr(rd, "lqpn", lqpn,
+				nla_line[RDMA_NLDEV_ATTR_RES_LQPN]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
 		pdn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
-	if (rd_check_is_filtered(rd, "pdn", pdn))
+	if (rd_is_filtered_attr(rd, "pdn", pdn,
+				nla_line[RDMA_NLDEV_ATTR_RES_PDN]))
 		goto out;
 
-	if (nla_line[RDMA_NLDEV_ATTR_RES_RQPN]) {
+	if (nla_line[RDMA_NLDEV_ATTR_RES_RQPN])
 		rqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQPN]);
-		if (rd_check_is_filtered(rd, "rqpn", rqpn))
-			goto out;
-	} else {
-		if (rd_check_is_key_exist(rd, "rqpn"))
-			goto out;
-	}
+	if (rd_is_filtered_attr(rd, "rqpn", rqpn,
+				nla_line[RDMA_NLDEV_ATTR_RES_RQPN]))
+		goto out;
 
-	if (nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]) {
+	if (nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN])
 		rq_psn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]);
-		if (rd_check_is_filtered(rd, "rq-psn", rq_psn))
-			goto out;
-	} else {
-		if (rd_check_is_key_exist(rd, "rq-psn"))
-			goto out;
-	}
+	if (rd_is_filtered_attr(rd, "rq-psn", rq_psn,
+				nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]))
+		goto out;
 
 	sq_psn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN]);
-	if (rd_check_is_filtered(rd, "sq-psn", sq_psn))
+	if (rd_is_filtered_attr(rd, "sq-psn", sq_psn,
+				nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN]))
 		goto out;
 
-	if (nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]) {
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE])
 		path_mig_state = mnl_attr_get_u8(
 			nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]);
-		if (rd_check_is_string_filtered(rd, "path-mig-state",
-						path_mig_to_str(path_mig_state)))
-			goto out;
-	} else {
-		if (rd_check_is_key_exist(rd, "path-mig-state"))
-			goto out;
-	}
+	if (rd_is_string_filtered_attr(
+		    rd, "path-mig-state", path_mig_to_str(path_mig_state),
+		    nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]))
+		goto out;
 
 	type = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_TYPE]);
-	if (rd_check_is_string_filtered(rd, "type", qp_types_to_str(type)))
+	if (rd_is_string_filtered_attr(rd, "type", qp_types_to_str(type),
+				       nla_line[RDMA_NLDEV_ATTR_RES_TYPE]))
 		goto out;
 
 	state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]);
-	if (rd_check_is_string_filtered(rd, "state", qp_states_to_str(state)))
+	if (rd_is_string_filtered_attr(rd, "state", qp_states_to_str(state),
+				       nla_line[RDMA_NLDEV_ATTR_RES_STATE]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
@@ -157,7 +153,8 @@ static int res_qp_line(struct rd *rd, const char *name, int idx,
 		comm = get_task_name(pid);
 	}
 
-	if (rd_check_is_filtered(rd, "pid", pid))
+	if (rd_is_filtered_attr(rd, "pid", pid,
+				nla_line[RDMA_NLDEV_ATTR_RES_PID]))
 		goto out;
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
diff --git a/rdma/utils.c b/rdma/utils.c
index cff5297d..6bc14cd5 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -233,7 +233,7 @@ out:
 	return ret;
 }
 
-bool rd_check_is_key_exist(struct rd *rd, const char *key)
+static bool rd_check_is_key_exist(struct rd *rd, const char *key)
 {
 	struct filter_entry *fe;
 
@@ -249,8 +249,8 @@ bool rd_check_is_key_exist(struct rd *rd, const char *key)
  * Check if string entry is filtered:
  *  * key doesn't exist -> user didn't request -> not filtered
  */
-bool rd_check_is_string_filtered(struct rd *rd,
-				 const char *key, const char *val)
+static bool rd_check_is_string_filtered(struct rd *rd, const char *key,
+					const char *val)
 {
 	bool key_is_filtered = false;
 	struct filter_entry *fe;
@@ -300,7 +300,7 @@ out:
  * Check if key is filtered:
  * key doesn't exist -> user didn't request -> not filtered
  */
-bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val)
+static bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val)
 {
 	bool key_is_filtered = false;
 	struct filter_entry *fe;
@@ -349,6 +349,24 @@ out:
 	return key_is_filtered;
 }
 
+bool rd_is_filtered_attr(struct rd *rd, const char *key, uint32_t val,
+			 struct nlattr *attr)
+{
+	if (!attr)
+		return rd_check_is_key_exist(rd, key);
+
+	return rd_check_is_filtered(rd, key, val);
+}
+
+bool rd_is_string_filtered_attr(struct rd *rd, const char *key, const char *val,
+				struct nlattr *attr)
+{
+	if (!attr)
+		rd_check_is_key_exist(rd, key);
+
+	return rd_check_is_string_filtered(rd, key, val);
+}
+
 static void filters_cleanup(struct rd *rd)
 {
 	struct filter_entry *fe, *tmp;
-- 
2.19.1


^ permalink raw reply related

* [PATCH iproute2-next v1 18/19] rdma: Perform single .doit call to query specific objects
From: Leon Romanovsky @ 2019-02-20  7:21 UTC (permalink / raw)
  To: David Ahern; +Cc: Leon Romanovsky, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <20190220072136.3840-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

If user provides specific index, we can speedup query
by using .doit callback and save full dump and filtering
after that.

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/rdma.h     | 10 +++++-
 rdma/res-cmid.c | 33 +++++++++++++------
 rdma/res-cq.c   | 34 ++++++++++++++------
 rdma/res-mr.c   | 33 ++++++++++++++-----
 rdma/res-pd.c   | 32 ++++++++++++++-----
 rdma/res-qp.c   | 32 ++++++++++++++-----
 rdma/res.c      | 34 +++++++++++++++++++-
 rdma/res.h      | 84 ++++++++++++++++++++++++++++++++-----------------
 rdma/utils.c    | 20 ++++++++++++
 9 files changed, 239 insertions(+), 73 deletions(-)

diff --git a/rdma/rdma.h b/rdma/rdma.h
index d2559e7c..e86c7f21 100644
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -30,13 +30,20 @@
 #define MAX_NUMBER_OF_FILTERS 64
 struct filters {
 	const char *name;
-	bool is_number;
+	uint8_t is_number:1;
+	uint8_t is_doit:1;
 };
 
 struct filter_entry {
 	struct list_head list;
 	char *key;
 	char *value;
+	/*
+	 * This field menas that we can try to issue .doit calback
+	 * on value above. This value can be converted to integer
+	 * with simple atoi(). Otherwise "is_doit" will be false.
+	 */
+	uint8_t is_doit:1;
 };
 
 struct dev_map {
@@ -101,6 +108,7 @@ struct dev_map *dev_map_lookup(struct rd *rd, bool allow_port_index);
 /*
  * Filter manipulation
  */
+bool rd_doit_index(struct rd *rd, uint32_t *idx);
 int rd_build_filter(struct rd *rd, const struct filters valid_filters[]);
 bool rd_check_is_filtered(struct rd *rd, const char *key, uint32_t val);
 bool rd_check_is_string_filtered(struct rd *rd, const char *key, const char *val);
diff --git a/rdma/res-cmid.c b/rdma/res-cmid.c
index 22d99a8b..0b61e433 100644
--- a/rdma/res-cmid.c
+++ b/rdma/res-cmid.c
@@ -107,11 +107,9 @@ static int ss_ntop(struct nlattr *nla_line, char *addr_str, uint16_t *port)
 	}
 	return 0;
 }
-
 static int res_cm_id_line(struct rd *rd, const char *name, int idx,
-			  struct nlattr *nla_entry)
+		       struct nlattr **nla_line)
 {
-	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
 	char src_addr_str[INET6_ADDRSTRLEN];
 	char dst_addr_str[INET6_ADDRSTRLEN];
 	uint16_t src_port, dst_port;
@@ -120,11 +118,6 @@ static int res_cm_id_line(struct rd *rd, const char *name, int idx,
 	uint32_t lqpn = 0, ps;
 	uint32_t cm_idn = 0;
 	char *comm = NULL;
-	int err;
-
-	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-	if (err != MNL_CB_OK)
-		return MNL_CB_ERROR;
 
 	if (!nla_line[RDMA_NLDEV_ATTR_RES_STATE] ||
 	    !nla_line[RDMA_NLDEV_ATTR_RES_PS] ||
@@ -225,6 +218,23 @@ out:	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
 	return MNL_CB_OK;
 }
 
+int res_cm_id_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct rd *rd = data;
+	const char *name;
+	int idx;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+
+	return res_cm_id_line(rd, name, idx, tb);
+}
+
 int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -244,8 +254,13 @@ int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_CM_ID];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		ret = res_cm_id_line(rd, name, idx, nla_entry);
+		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+
+		ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+		if (ret != MNL_CB_OK)
+			break;
 
+		ret = res_cm_id_line(rd, name, idx, nla_line);
 		if (ret != MNL_CB_OK)
 			break;
 	}
diff --git a/rdma/res-cq.c b/rdma/res-cq.c
index cea4f6bd..c14637e6 100644
--- a/rdma/res-cq.c
+++ b/rdma/res-cq.c
@@ -31,9 +31,8 @@ static void print_poll_ctx(struct rd *rd, uint8_t poll_ctx, struct nlattr *attr)
 }
 
 static int res_cq_line(struct rd *rd, const char *name, int idx,
-		       struct nlattr *nla_entry)
+		       struct nlattr **nla_line)
 {
-	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
 	char *comm = NULL;
 	uint32_t pid = 0;
 	uint8_t poll_ctx = 0;
@@ -41,11 +40,6 @@ static int res_cq_line(struct rd *rd, const char *name, int idx,
 	uint32_t cqn = 0;
 	uint64_t users;
 	uint32_t cqe;
-	int err;
-
-	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-	if (err != MNL_CB_OK)
-		return MNL_CB_ERROR;
 
 	if (!nla_line[RDMA_NLDEV_ATTR_RES_CQE] ||
 	    !nla_line[RDMA_NLDEV_ATTR_RES_USECNT] ||
@@ -80,7 +74,6 @@ static int res_cq_line(struct rd *rd, const char *name, int idx,
 		cqn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CQN]);
 	if (rd_check_is_filtered(rd, "cqn", cqn))
 		goto out;
-
 	if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
 		ctxn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
 	if (rd_check_is_filtered(rd, "ctxn", ctxn))
@@ -112,6 +105,23 @@ out:	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
 	return MNL_CB_OK;
 }
 
+int res_cq_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct rd *rd = data;
+	const char *name;
+	uint32_t idx;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+
+	return res_cq_line(rd, name, idx, tb);
+}
+
 int res_cq_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -131,7 +141,13 @@ int res_cq_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_CQ];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		ret = res_cq_line(rd, name, idx, nla_entry);
+		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+
+		ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+		if (ret != MNL_CB_OK)
+			break;
+
+		ret = res_cq_line(rd, name, idx, nla_line);
 
 		if (ret != MNL_CB_OK)
 			break;
diff --git a/rdma/res-mr.c b/rdma/res-mr.c
index 82e6d150..d42e8d81 100644
--- a/rdma/res-mr.c
+++ b/rdma/res-mr.c
@@ -8,20 +8,14 @@
 #include <inttypes.h>
 
 static int res_mr_line(struct rd *rd, const char *name, int idx,
-		       struct nlattr *nla_entry)
+		       struct nlattr **nla_line)
 {
-	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
 	uint32_t rkey = 0, lkey = 0;
 	uint64_t iova = 0, mrlen;
 	char *comm = NULL;
 	uint32_t pdn = 0;
 	uint32_t mrn = 0;
 	uint32_t pid = 0;
-	int err;
-
-	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-	if (err != MNL_CB_OK)
-		return MNL_CB_ERROR;
 
 	if (!nla_line[RDMA_NLDEV_ATTR_RES_MRLEN] ||
 	    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
@@ -84,6 +78,24 @@ out:
 		free(comm);
 	return MNL_CB_OK;
 }
+
+int res_mr_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct rd *rd = data;
+	const char *name;
+	uint32_t idx;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+
+	return res_mr_line(rd, name, idx, tb);
+}
+
 int res_mr_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -103,8 +115,13 @@ int res_mr_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_MR];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		ret = res_mr_line(rd, name, idx, nla_entry);
+		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+
+		ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+		if (ret != MNL_CB_OK)
+			break;
 
+		ret = res_mr_line(rd, name, idx, nla_line);
 		if (ret != MNL_CB_OK)
 			break;
 	}
diff --git a/rdma/res-pd.c b/rdma/res-pd.c
index e8c042dc..956d4d9f 100644
--- a/rdma/res-pd.c
+++ b/rdma/res-pd.c
@@ -8,20 +8,14 @@
 #include <inttypes.h>
 
 static int res_pd_line(struct rd *rd, const char *name, int idx,
-		       struct nlattr *nla_entry)
+		       struct nlattr **nla_line)
 {
 	uint32_t local_dma_lkey = 0, unsafe_global_rkey = 0;
-	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
 	char *comm = NULL;
 	uint32_t ctxn = 0;
 	uint32_t pid = 0;
 	uint32_t pdn = 0;
 	uint64_t users;
-	int err;
-
-	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-	if (err != MNL_CB_OK)
-		return MNL_CB_ERROR;
 
 	if (!nla_line[RDMA_NLDEV_ATTR_RES_USECNT] ||
 	    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
@@ -88,6 +82,23 @@ out:	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
 	return MNL_CB_OK;
 }
 
+int res_pd_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct rd *rd = data;
+	const char *name;
+	uint32_t idx;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+
+	return res_pd_line(rd, name, idx, tb);
+}
+
 int res_pd_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -107,8 +118,13 @@ int res_pd_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_PD];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		ret = res_pd_line(rd, name, idx, nla_entry);
+		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+
+		ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+		if (ret != MNL_CB_OK)
+			break;
 
+		ret = res_pd_line(rd, name, idx, nla_line);
 		if (ret != MNL_CB_OK)
 			break;
 	}
diff --git a/rdma/res-qp.c b/rdma/res-qp.c
index 5d5ef27b..ac9976fc 100644
--- a/rdma/res-qp.c
+++ b/rdma/res-qp.c
@@ -79,19 +79,13 @@ static void print_pathmig(struct rd *rd, uint32_t val, struct nlattr **nla_line)
 }
 
 static int res_qp_line(struct rd *rd, const char *name, int idx,
-		       struct nlattr *nla_entry)
+		       struct nlattr **nla_line)
 {
-	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
 	uint32_t lqpn, rqpn = 0, rq_psn = 0, sq_psn;
 	uint8_t type, state, path_mig_state = 0;
 	uint32_t port = 0, pid = 0;
 	uint32_t pdn = 0;
 	char *comm = NULL;
-	int err;
-
-	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-	if (err != MNL_CB_OK)
-		return MNL_CB_ERROR;
 
 	if (!nla_line[RDMA_NLDEV_ATTR_RES_LQPN] ||
 	    !nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN] ||
@@ -199,6 +193,23 @@ out:
 	return MNL_CB_OK;
 }
 
+int res_qp_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct rd *rd = data;
+	const char *name;
+	uint32_t idx;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+
+	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+
+	return res_qp_line(rd, name, idx, tb);
+}
+
 int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -218,8 +229,13 @@ int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_QP];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		ret = res_qp_line(rd, name, idx, nla_entry);
+		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+
+		ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+		if (ret != MNL_CB_OK)
+			break;
 
+		ret = res_qp_line(rd, name, idx, nla_line);
 		if (ret != MNL_CB_OK)
 			break;
 	}
diff --git a/rdma/res.c b/rdma/res.c
index 564af9b4..ef863f14 100644
--- a/rdma/res.c
+++ b/rdma/res.c
@@ -54,6 +54,11 @@ static int res_print_summary(struct rd *rd, struct nlattr **tb)
 	return 0;
 }
 
+static int res_no_args_idx_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	return MNL_CB_OK;
+}
+
 static int res_no_args_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
@@ -83,6 +88,33 @@ static int res_no_args_parse_cb(const struct nlmsghdr *nlh, void *data)
 	return MNL_CB_OK;
 }
 
+int _res_send_idx_msg(struct rd *rd, uint32_t command, mnl_cb_t callback,
+		      uint32_t idx, uint32_t id)
+{
+	uint32_t flags = NLM_F_REQUEST | NLM_F_ACK;
+	uint32_t seq;
+	int ret;
+
+	rd_prepare_msg(rd, command, &seq, flags);
+	mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
+	if (rd->port_idx)
+		mnl_attr_put_u32(rd->nlh,
+				 RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx);
+
+	mnl_attr_put_u32(rd->nlh, id, idx);
+
+	ret = rd_send_msg(rd);
+	if (ret)
+		return ret;
+
+	if (rd->json_output)
+		jsonw_start_object(rd->jw);
+	ret = rd_recv_msg(rd, callback, rd, seq);
+	if (rd->json_output)
+		jsonw_end_object(rd->jw);
+	return ret;
+}
+
 int _res_send_msg(struct rd *rd, uint32_t command, mnl_cb_t callback)
 {
 	uint32_t flags = NLM_F_REQUEST | NLM_F_ACK;
@@ -214,7 +246,7 @@ void res_print_uint(struct rd *rd, const char *name, uint64_t val,
 		pr_out("%s %" PRIu64 " ", name, val);
 }
 
-RES_FUNC(res_no_args,	RDMA_NLDEV_CMD_RES_GET,	NULL, true);
+RES_FUNC(res_no_args,	RDMA_NLDEV_CMD_RES_GET,	NULL, true, 0);
 
 static int res_show(struct rd *rd)
 {
diff --git a/rdma/res.h b/rdma/res.h
index 575e1192..b4a7e552 100644
--- a/rdma/res.h
+++ b/rdma/res.h
@@ -9,31 +9,52 @@
 #include "rdma.h"
 
 int _res_send_msg(struct rd *rd, uint32_t command, mnl_cb_t callback);
+int _res_send_idx_msg(struct rd *rd, uint32_t command, mnl_cb_t callback,
+		      uint32_t idx, uint32_t id);
+
 int res_pd_parse_cb(const struct nlmsghdr *nlh, void *data);
+int res_pd_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
 int res_mr_parse_cb(const struct nlmsghdr *nlh, void *data);
+int res_mr_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
 int res_cq_parse_cb(const struct nlmsghdr *nlh, void *data);
+int res_cq_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
 int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data);
+int res_cm_id_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
 int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data);
+int res_qp_idx_parse_cb(const struct nlmsghdr *nlh, void *data);
 
-#define RES_FUNC(name, command, valid_filters, strict_port) \
-	static inline int _##name(struct rd *rd)\
-	{ \
-		return _res_send_msg(rd, command, name##_parse_cb); \
-	} \
-	static inline int name(struct rd *rd) \
-	{\
-		int ret = rd_build_filter(rd, valid_filters); \
-		if (ret) \
-			return ret; \
-		if ((uintptr_t)valid_filters != (uintptr_t)NULL) { \
-			ret = rd_set_arg_to_devname(rd); \
-			if (ret) \
-				return ret;\
-		} \
-		if (strict_port) \
-			return rd_exec_dev(rd, _##name); \
-		else \
-			return rd_exec_link(rd, _##name, strict_port); \
+#define RES_FUNC(name, command, valid_filters, strict_port, id)                        \
+	static inline int _##name(struct rd *rd)                                       \
+	{                                                                              \
+		uint32_t idx;                                                          \
+		int ret;                                                               \
+		if (id) {                                                              \
+			ret = rd_doit_index(rd, &idx);                                 \
+			if (ret) {                                                     \
+				ret = _res_send_idx_msg(rd, command,                   \
+							name##_idx_parse_cb,           \
+							idx, id);                      \
+				if (!ret)                                              \
+					return ret;                                    \
+				/* Fallback for old systems without .doit callbacks */ \
+			}                                                              \
+		}                                                                      \
+		return _res_send_msg(rd, command, name##_parse_cb);                    \
+	}                                                                              \
+	static inline int name(struct rd *rd)                                          \
+	{                                                                              \
+		int ret = rd_build_filter(rd, valid_filters);                          \
+		if (ret)                                                               \
+			return ret;                                                    \
+		if ((uintptr_t)valid_filters != (uintptr_t)NULL) {                     \
+			ret = rd_set_arg_to_devname(rd);                               \
+			if (ret)                                                       \
+				return ret;                                            \
+		}                                                                      \
+		if (strict_port)                                                       \
+			return rd_exec_dev(rd, _##name);                               \
+		else                                                                   \
+			return rd_exec_link(rd, _##name, strict_port);                 \
 	}
 
 static const
@@ -42,11 +63,12 @@ struct filters pd_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "users", .is_number = true },
 	{ .name = "pid", .is_number = true },
 	{ .name = "ctxn", .is_number = true },
-	{ .name = "pdn", .is_number = true },
+	{ .name = "pdn", .is_number = true, .is_doit = true },
 	{ .name = "ctxn", .is_number = true }
 };
 
-RES_FUNC(res_pd, RDMA_NLDEV_CMD_RES_PD_GET, pd_valid_filters, true);
+RES_FUNC(res_pd, RDMA_NLDEV_CMD_RES_PD_GET, pd_valid_filters, true,
+	 RDMA_NLDEV_ATTR_RES_PDN);
 
 static const
 struct filters mr_valid_filters[MAX_NUMBER_OF_FILTERS] = {
@@ -55,11 +77,12 @@ struct filters mr_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "lkey", .is_number = true },
 	{ .name = "mrlen", .is_number = true },
 	{ .name = "pid", .is_number = true },
-	{ .name = "mrn", .is_number = true },
+	{ .name = "mrn", .is_number = true, .is_doit = true },
 	{ .name = "pdn", .is_number = true }
 };
 
-RES_FUNC(res_mr, RDMA_NLDEV_CMD_RES_MR_GET, mr_valid_filters, true);
+RES_FUNC(res_mr, RDMA_NLDEV_CMD_RES_MR_GET, mr_valid_filters, true,
+	 RDMA_NLDEV_ATTR_RES_MRN);
 
 static const
 struct filters cq_valid_filters[MAX_NUMBER_OF_FILTERS] = {
@@ -67,11 +90,12 @@ struct filters cq_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "users", .is_number = true },
 	{ .name = "poll-ctx", .is_number = false },
 	{ .name = "pid", .is_number = true },
-	{ .name = "cqn", .is_number = true },
+	{ .name = "cqn", .is_number = true, .is_doit = true },
 	{ .name = "ctxn", .is_number = true }
 };
 
-RES_FUNC(res_cq, RDMA_NLDEV_CMD_RES_CQ_GET, cq_valid_filters, true);
+RES_FUNC(res_cq, RDMA_NLDEV_CMD_RES_CQ_GET, cq_valid_filters, true,
+	 RDMA_NLDEV_ATTR_RES_CQN);
 
 static const
 struct filters cm_id_valid_filters[MAX_NUMBER_OF_FILTERS] = {
@@ -87,15 +111,16 @@ struct filters cm_id_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "src-port", .is_number = true },
 	{ .name = "dst-addr", .is_number = false },
 	{ .name = "dst-port", .is_number = true },
-	{ .name = "cm-idn", .is_number = true }
+	{ .name = "cm-idn", .is_number = true, .is_doit = true }
 };
 
-RES_FUNC(res_cm_id, RDMA_NLDEV_CMD_RES_CM_ID_GET, cm_id_valid_filters, false);
+RES_FUNC(res_cm_id, RDMA_NLDEV_CMD_RES_CM_ID_GET, cm_id_valid_filters, false,
+	 RDMA_NLDEV_ATTR_RES_CM_IDN);
 
 static const struct
 filters qp_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "link", .is_number = false },
-	{ .name = "lqpn", .is_number = true },
+	{ .name = "lqpn", .is_number = true, .is_doit = true },
 	{ .name = "rqpn", .is_number = true },
 	{ .name = "pid",  .is_number = true },
 	{ .name = "sq-psn", .is_number = true },
@@ -106,7 +131,8 @@ filters qp_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 	{ .name = "pdn", .is_number = true },
 };
 
-RES_FUNC(res_qp,	RDMA_NLDEV_CMD_RES_QP_GET, qp_valid_filters, false);
+RES_FUNC(res_qp, RDMA_NLDEV_CMD_RES_QP_GET, qp_valid_filters, false,
+	 RDMA_NLDEV_ATTR_RES_LQPN);
 
 char *get_task_name(uint32_t pid);
 void print_dev(struct rd *rd, uint32_t idx, const char *name);
diff --git a/rdma/utils.c b/rdma/utils.c
index bce052d5..cff5297d 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -121,6 +121,7 @@ static int add_filter(struct rd *rd, char *key, char *value,
 	struct filter_entry *fe;
 	bool key_found = false;
 	int idx = 0;
+	char *endp;
 	int ret;
 
 	fe = calloc(1, sizeof(*fe));
@@ -163,6 +164,11 @@ static int add_filter(struct rd *rd, char *key, char *value,
 		goto err_alloc;
 	}
 
+	errno = 0;
+	strtol(fe->value, &endp, 10);
+	if (valid_filters[idx].is_doit && !errno && *endp == '\0')
+		fe->is_doit = true;
+
 	for (idx = 0; idx < strlen(fe->value); idx++)
 		fe->value[idx] = tolower(fe->value[idx]);
 
@@ -177,6 +183,20 @@ err:
 	return ret;
 }
 
+bool rd_doit_index(struct rd *rd, uint32_t *idx)
+{
+	struct filter_entry *fe;
+
+	list_for_each_entry(fe, &rd->filter_list, list) {
+		if (fe->is_doit) {
+			*idx = atoi(fe->value);
+			return true;
+		}
+	}
+
+	return false;
+}
+
 int rd_build_filter(struct rd *rd, const struct filters valid_filters[])
 {
 	int ret = 0;
-- 
2.19.1


^ permalink raw reply related

* [PATCH iproute2-next v1 17/19] rdma: Unify netlink attribute checks prior to prints
From: Leon Romanovsky @ 2019-02-20  7:21 UTC (permalink / raw)
  To: David Ahern; +Cc: Leon Romanovsky, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <20190220072136.3840-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

Place check if netlink attribute available in general place,
instead of doing the same check in many paces.

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/res-cmid.c |  9 ++++-----
 rdma/res-cq.c   | 22 +++++++++++-----------
 rdma/res-mr.c   | 21 +++++++--------------
 rdma/res-pd.c   | 20 +++++++++-----------
 rdma/res-qp.c   | 10 +++++-----
 rdma/res.c      | 16 +++++++++++++---
 rdma/res.h      |  6 ++++--
 7 files changed, 53 insertions(+), 51 deletions(-)

diff --git a/rdma/res-cmid.c b/rdma/res-cmid.c
index 12d1acee..22d99a8b 100644
--- a/rdma/res-cmid.c
+++ b/rdma/res-cmid.c
@@ -202,16 +202,15 @@ static int res_cm_id_line(struct rd *rd, const char *name, int idx,
 		jsonw_start_array(rd->jw);
 
 	print_link(rd, idx, name, port, nla_line);
-	if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN])
-		res_print_uint(rd, "lqpn", lqpn);
+	res_print_uint(rd, "cm-idn", cm_idn,
+		       nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]);
+	res_print_uint(rd, "lqpn", lqpn, nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
 	if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE])
 		print_qp_type(rd, type);
 	print_cm_id_state(rd, state);
 	print_ps(rd, ps);
-	res_print_uint(rd, "pid", pid);
+	res_print_uint(rd, "pid", pid, nla_line[RDMA_NLDEV_ATTR_RES_PID]);
 	print_comm(rd, comm, nla_line);
-	if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])
-		res_print_uint(rd, "cm-idn", cm_idn);
 
 	if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR])
 		print_ipaddr(rd, "src-addr", src_addr_str, src_port);
diff --git a/rdma/res-cq.c b/rdma/res-cq.c
index e50d76ce..cea4f6bd 100644
--- a/rdma/res-cq.c
+++ b/rdma/res-cq.c
@@ -17,8 +17,11 @@ static const char *poll_ctx_to_str(uint8_t idx)
 	return "UNKNOWN";
 }
 
-static void print_poll_ctx(struct rd *rd, uint8_t poll_ctx)
+static void print_poll_ctx(struct rd *rd, uint8_t poll_ctx, struct nlattr *attr)
 {
+	if (!attr)
+		return;
+
 	if (rd->json_output) {
 		jsonw_string_field(rd->jw, "poll-ctx",
 				   poll_ctx_to_str(poll_ctx));
@@ -92,18 +95,15 @@ static int res_cq_line(struct rd *rd, const char *name, int idx,
 		jsonw_start_array(rd->jw);
 
 	print_dev(rd, idx, name);
-	res_print_uint(rd, "cqe", cqe);
-	res_print_uint(rd, "users", users);
-	if (nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX])
-		print_poll_ctx(rd, poll_ctx);
-	res_print_uint(rd, "pid", pid);
+	res_print_uint(rd, "cqn", cqn, nla_line[RDMA_NLDEV_ATTR_RES_CQN]);
+	res_print_uint(rd, "cqe", cqe, nla_line[RDMA_NLDEV_ATTR_RES_CQE]);
+	res_print_uint(rd, "users", users,
+		       nla_line[RDMA_NLDEV_ATTR_RES_USECNT]);
+	print_poll_ctx(rd, poll_ctx, nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX]);
+	res_print_uint(rd, "ctxn", ctxn, nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
+	res_print_uint(rd, "pid", pid, nla_line[RDMA_NLDEV_ATTR_RES_PID]);
 	print_comm(rd, comm, nla_line);
 
-	if (nla_line[RDMA_NLDEV_ATTR_RES_CQN])
-		res_print_uint(rd, "cqn", cqn);
-	if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
-		res_print_uint(rd, "ctxn", ctxn);
-
 	print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
 	newline(rd);
 
diff --git a/rdma/res-mr.c b/rdma/res-mr.c
index 36993b5e..82e6d150 100644
--- a/rdma/res-mr.c
+++ b/rdma/res-mr.c
@@ -67,22 +67,15 @@ static int res_mr_line(struct rd *rd, const char *name, int idx,
 		jsonw_start_array(rd->jw);
 
 	print_dev(rd, idx, name);
-	if (nla_line[RDMA_NLDEV_ATTR_RES_RKEY])
-		print_key(rd, "rkey", rkey);
-	if (nla_line[RDMA_NLDEV_ATTR_RES_LKEY])
-		print_key(rd, "lkey", lkey);
-	if (nla_line[RDMA_NLDEV_ATTR_RES_IOVA])
-		print_key(rd, "iova", iova);
-	res_print_uint(rd, "mrlen", mrlen);
-	res_print_uint(rd, "pid", pid);
+	res_print_uint(rd, "mrn", mrn, nla_line[RDMA_NLDEV_ATTR_RES_MRN]);
+	print_key(rd, "rkey", rkey, nla_line[RDMA_NLDEV_ATTR_RES_RKEY]);
+	print_key(rd, "lkey", lkey, nla_line[RDMA_NLDEV_ATTR_RES_LKEY]);
+	print_key(rd, "iova", iova, nla_line[RDMA_NLDEV_ATTR_RES_IOVA]);
+	res_print_uint(rd, "mrlen", mrlen, nla_line[RDMA_NLDEV_ATTR_RES_MRLEN]);
+	res_print_uint(rd, "pdn", pdn, nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
+	res_print_uint(rd, "pid", pid, nla_line[RDMA_NLDEV_ATTR_RES_PID]);
 	print_comm(rd, comm, nla_line);
 
-	if (nla_line[RDMA_NLDEV_ATTR_RES_MRN])
-		res_print_uint(rd, "mrn", mrn);
-
-	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
-		res_print_uint(rd, "pdn", pdn);
-
 	print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
 	newline(rd);
 
diff --git a/rdma/res-pd.c b/rdma/res-pd.c
index 3c9ffa4e..e8c042dc 100644
--- a/rdma/res-pd.c
+++ b/rdma/res-pd.c
@@ -69,18 +69,16 @@ static int res_pd_line(struct rd *rd, const char *name, int idx,
 		jsonw_start_array(rd->jw);
 
 	print_dev(rd, idx, name);
-	if (nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY])
-		print_key(rd, "local_dma_lkey", local_dma_lkey);
-	res_print_uint(rd, "users", users);
-	if (nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY])
-		print_key(rd, "unsafe_global_rkey", unsafe_global_rkey);
-	res_print_uint(rd, "pid", pid);
+	res_print_uint(rd, "pdn", pdn, nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
+	print_key(rd, "local_dma_lkey", local_dma_lkey,
+		  nla_line[RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY]);
+	res_print_uint(rd, "users", users,
+		       nla_line[RDMA_NLDEV_ATTR_RES_USECNT]);
+	print_key(rd, "unsafe_global_rkey", unsafe_global_rkey,
+		  nla_line[RDMA_NLDEV_ATTR_RES_UNSAFE_GLOBAL_RKEY]);
+	res_print_uint(rd, "ctxn", ctxn, nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
+	res_print_uint(rd, "pid", pid, nla_line[RDMA_NLDEV_ATTR_RES_PID]);
 	print_comm(rd, comm, nla_line);
-	if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
-		res_print_uint(rd, "ctxn", ctxn);
-
-	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
-		res_print_uint(rd, "pdn", pdn);
 
 	print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
 	newline(rd);
diff --git a/rdma/res-qp.c b/rdma/res-qp.c
index e74c8b01..5d5ef27b 100644
--- a/rdma/res-qp.c
+++ b/rdma/res-qp.c
@@ -176,19 +176,19 @@ static int res_qp_line(struct rd *rd, const char *name, int idx,
 
 	print_link(rd, idx, name, port, nla_line);
 
-	res_print_uint(rd, "lqpn", lqpn);
-	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
-		res_print_uint(rd, "pdn", pdn);
+	res_print_uint(rd, "lqpn", lqpn, nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
 	print_rqpn(rd, rqpn, nla_line);
 
 	print_type(rd, type);
 	print_state(rd, state);
 
 	print_rqpsn(rd, rq_psn, nla_line);
-	res_print_uint(rd, "sq-psn", sq_psn);
+	res_print_uint(rd, "sq-psn", sq_psn,
+		       nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN]);
 
 	print_pathmig(rd, path_mig_state, nla_line);
-	res_print_uint(rd, "pid", pid);
+	res_print_uint(rd, "pdn", pdn, nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
+	res_print_uint(rd, "pid", pid, nla_line[RDMA_NLDEV_ATTR_RES_PID]);
 	print_comm(rd, comm, nla_line);
 
 	print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
diff --git a/rdma/res.c b/rdma/res.c
index 140c0908..564af9b4 100644
--- a/rdma/res.c
+++ b/rdma/res.c
@@ -47,7 +47,9 @@ static int res_print_summary(struct rd *rd, struct nlattr **tb)
 
 		name = mnl_attr_get_str(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME]);
 		curr = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]);
-		res_print_uint(rd, name, curr);
+		res_print_uint(
+			rd, name, curr,
+			nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]);
 	}
 	return 0;
 }
@@ -188,16 +190,24 @@ char *get_task_name(uint32_t pid)
 	return comm;
 }
 
-void print_key(struct rd *rd, const char *name, uint64_t val)
+void print_key(struct rd *rd, const char *name, uint64_t val,
+	       struct nlattr *nlattr)
 {
+	if (!nlattr)
+		return;
+
 	if (rd->json_output)
 		jsonw_xint_field(rd->jw, name, val);
 	else
 		pr_out("%s 0x%" PRIx64 " ", name, val);
 }
 
-void res_print_uint(struct rd *rd, const char *name, uint64_t val)
+void res_print_uint(struct rd *rd, const char *name, uint64_t val,
+		    struct nlattr *nlattr)
 {
+	if (!nlattr)
+		return;
+
 	if (rd->json_output)
 		jsonw_u64_field(rd->jw, name, val);
 	else
diff --git a/rdma/res.h b/rdma/res.h
index 89dd818a..575e1192 100644
--- a/rdma/res.h
+++ b/rdma/res.h
@@ -112,8 +112,10 @@ char *get_task_name(uint32_t pid);
 void print_dev(struct rd *rd, uint32_t idx, const char *name);
 void print_link(struct rd *rd, uint32_t idx, const char *name, uint32_t port,
 		struct nlattr **nla_line);
-void print_key(struct rd *rd, const char *name, uint64_t val);
-void res_print_uint(struct rd *rd, const char *name, uint64_t val);
+void print_key(struct rd *rd, const char *name, uint64_t val,
+	       struct nlattr *nlattr);
+void res_print_uint(struct rd *rd, const char *name, uint64_t val,
+		    struct nlattr *nlattr);
 void print_comm(struct rd *rd, const char *str, struct nlattr **nla_line);
 const char *qp_types_to_str(uint8_t idx);
 
-- 
2.19.1


^ permalink raw reply related

* [PATCH iproute2-next v1 16/19] rdma: Move QP code to separate function
From: Leon Romanovsky @ 2019-02-20  7:21 UTC (permalink / raw)
  To: David Ahern; +Cc: Leon Romanovsky, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <20190220072136.3840-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/res-qp.c | 253 +++++++++++++++++++++++++-------------------------
 1 file changed, 127 insertions(+), 126 deletions(-)

diff --git a/rdma/res-qp.c b/rdma/res-qp.c
index ecd2cbd6..e74c8b01 100644
--- a/rdma/res-qp.c
+++ b/rdma/res-qp.c
@@ -78,11 +78,133 @@ static void print_pathmig(struct rd *rd, uint32_t val, struct nlattr **nla_line)
 		pr_out("path-mig-state %s ", path_mig_to_str(val));
 }
 
+static int res_qp_line(struct rd *rd, const char *name, int idx,
+		       struct nlattr *nla_entry)
+{
+	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+	uint32_t lqpn, rqpn = 0, rq_psn = 0, sq_psn;
+	uint8_t type, state, path_mig_state = 0;
+	uint32_t port = 0, pid = 0;
+	uint32_t pdn = 0;
+	char *comm = NULL;
+	int err;
+
+	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+	if (err != MNL_CB_OK)
+		return MNL_CB_ERROR;
+
+	if (!nla_line[RDMA_NLDEV_ATTR_RES_LQPN] ||
+	    !nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN] ||
+	    !nla_line[RDMA_NLDEV_ATTR_RES_TYPE] ||
+	    !nla_line[RDMA_NLDEV_ATTR_RES_STATE] ||
+	    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
+	     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
+		return MNL_CB_ERROR;
+	}
+
+	if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX])
+		port = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]);
+
+	if (port != rd->port_idx)
+		goto out;
+
+	lqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
+	if (rd_check_is_filtered(rd, "lqpn", lqpn))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
+		pdn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
+	if (rd_check_is_filtered(rd, "pdn", pdn))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_RQPN]) {
+		rqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQPN]);
+		if (rd_check_is_filtered(rd, "rqpn", rqpn))
+			goto out;
+	} else {
+		if (rd_check_is_key_exist(rd, "rqpn"))
+			goto out;
+	}
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]) {
+		rq_psn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]);
+		if (rd_check_is_filtered(rd, "rq-psn", rq_psn))
+			goto out;
+	} else {
+		if (rd_check_is_key_exist(rd, "rq-psn"))
+			goto out;
+	}
+
+	sq_psn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN]);
+	if (rd_check_is_filtered(rd, "sq-psn", sq_psn))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]) {
+		path_mig_state = mnl_attr_get_u8(
+			nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]);
+		if (rd_check_is_string_filtered(rd, "path-mig-state",
+						path_mig_to_str(path_mig_state)))
+			goto out;
+	} else {
+		if (rd_check_is_key_exist(rd, "path-mig-state"))
+			goto out;
+	}
+
+	type = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_TYPE]);
+	if (rd_check_is_string_filtered(rd, "type", qp_types_to_str(type)))
+		goto out;
+
+	state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]);
+	if (rd_check_is_string_filtered(rd, "state", qp_states_to_str(state)))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
+		pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]);
+		comm = get_task_name(pid);
+	}
+
+	if (rd_check_is_filtered(rd, "pid", pid))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
+		/* discard const from mnl_attr_get_str */
+		comm = (char *)mnl_attr_get_str(
+			nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
+
+	if (rd->json_output)
+		jsonw_start_array(rd->jw);
+
+	print_link(rd, idx, name, port, nla_line);
+
+	res_print_uint(rd, "lqpn", lqpn);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
+		res_print_uint(rd, "pdn", pdn);
+	print_rqpn(rd, rqpn, nla_line);
+
+	print_type(rd, type);
+	print_state(rd, state);
+
+	print_rqpsn(rd, rq_psn, nla_line);
+	res_print_uint(rd, "sq-psn", sq_psn);
+
+	print_pathmig(rd, path_mig_state, nla_line);
+	res_print_uint(rd, "pid", pid);
+	print_comm(rd, comm, nla_line);
+
+	print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
+	newline(rd);
+out:
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
+		free(comm);
+	return MNL_CB_OK;
+}
+
 int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
 	struct nlattr *nla_table, *nla_entry;
 	struct rd *rd = data;
+	int ret = MNL_CB_OK;
 	const char *name;
 	uint32_t idx;
 
@@ -96,131 +218,10 @@ int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_QP];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
-		uint32_t lqpn, rqpn = 0, rq_psn = 0, sq_psn;
-		uint8_t type, state, path_mig_state = 0;
-		uint32_t port = 0, pid = 0;
-		uint32_t pdn = 0;
-		char *comm = NULL;
-		int err;
-
-		err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-		if (err != MNL_CB_OK)
-			return MNL_CB_ERROR;
-
-		if (!nla_line[RDMA_NLDEV_ATTR_RES_LQPN] ||
-		    !nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN] ||
-		    !nla_line[RDMA_NLDEV_ATTR_RES_TYPE] ||
-		    !nla_line[RDMA_NLDEV_ATTR_RES_STATE] ||
-		    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
-		     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
-			return MNL_CB_ERROR;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX])
-			port = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]);
-
-		if (port != rd->port_idx)
-			continue;
-
-		lqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
-		if (rd_check_is_filtered(rd, "lqpn", lqpn))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
-			pdn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
-		if (rd_check_is_filtered(rd, "pdn", pdn))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_RQPN]) {
-			rqpn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_RQPN]);
-			if (rd_check_is_filtered(rd, "rqpn", rqpn))
-				continue;
-		} else {
-			if (rd_check_is_key_exist(rd, "rqpn"))
-				continue;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]) {
-			rq_psn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_RQ_PSN]);
-			if (rd_check_is_filtered(rd, "rq-psn", rq_psn))
-				continue;
-		} else {
-			if (rd_check_is_key_exist(rd, "rq-psn"))
-				continue;
-		}
-
-		sq_psn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_SQ_PSN]);
-		if (rd_check_is_filtered(rd, "sq-psn", sq_psn))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]) {
-			path_mig_state = mnl_attr_get_u8(
-				nla_line[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE]);
-			if (rd_check_is_string_filtered(
-				    rd, "path-mig-state",
-				    path_mig_to_str(path_mig_state)))
-				continue;
-		} else {
-			if (rd_check_is_key_exist(rd, "path-mig-state"))
-				continue;
-		}
-
-		type = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_TYPE]);
-		if (rd_check_is_string_filtered(rd, "type",
-						qp_types_to_str(type)))
-			continue;
-
-		state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]);
-		if (rd_check_is_string_filtered(rd, "state",
-						qp_states_to_str(state)))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
-			pid = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_PID]);
-			comm = get_task_name(pid);
-		}
-
-		if (rd_check_is_filtered(rd, "pid", pid)) {
-			free(comm);
-			continue;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
-			/* discard const from mnl_attr_get_str */
-			comm = (char *)mnl_attr_get_str(
-				nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
-
-		if (rd->json_output)
-			jsonw_start_array(rd->jw);
-
-		print_link(rd, idx, name, port, nla_line);
-
-		res_print_uint(rd, "lqpn", lqpn);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
-			res_print_uint(rd, "pdn", pdn);
-		print_rqpn(rd, rqpn, nla_line);
-
-		print_type(rd, type);
-		print_state(rd, state);
-
-		print_rqpsn(rd, rq_psn, nla_line);
-		res_print_uint(rd, "sq-psn", sq_psn);
-
-		print_pathmig(rd, path_mig_state, nla_line);
-		res_print_uint(rd, "pid", pid);
-		print_comm(rd, comm, nla_line);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
-			free(comm);
-
-		print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
-		newline(rd);
+		ret = res_qp_line(rd, name, idx, nla_entry);
+
+		if (ret != MNL_CB_OK)
+			break;
 	}
-	return MNL_CB_OK;
+	return ret;
 }
-- 
2.19.1


^ permalink raw reply related

* [PATCH iproute2-next v1 08/19] rdma: Move out resource CM-ID logic to separate file
From: Leon Romanovsky @ 2019-02-20  7:21 UTC (permalink / raw)
  To: David Ahern; +Cc: Leon Romanovsky, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <20190220072136.3840-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

Logically separate resource CM-ID logic to separate file,
in order to make CM-ID specific logic self-contained.

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/Makefile   |   3 +-
 rdma/res-cmid.c | 252 ++++++++++++++++++++++++++++++++++++++++++++
 rdma/res.c      | 271 +-----------------------------------------------
 rdma/res.h      |  24 +++++
 4 files changed, 282 insertions(+), 268 deletions(-)
 create mode 100644 rdma/res-cmid.c

diff --git a/rdma/Makefile b/rdma/Makefile
index e32ccd18..ef240404 100644
--- a/rdma/Makefile
+++ b/rdma/Makefile
@@ -6,7 +6,8 @@ TARGETS :=
 ifeq ($(HAVE_MNL),y)
 CFLAGS += -I./include/uapi/
 
-RDMA_OBJ = rdma.o utils.o dev.o link.o res.o res-pd.o res-mr.o res-cq.o
+RDMA_OBJ = rdma.o utils.o dev.o link.o res.o res-pd.o res-mr.o res-cq.o \
+	   res-cmid.o
 
 TARGETS += rdma
 endif
diff --git a/rdma/res-cmid.c b/rdma/res-cmid.c
new file mode 100644
index 00000000..b63634a3
--- /dev/null
+++ b/rdma/res-cmid.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/*
+ * res-cmid.c	RDMA tool
+ * Authors:     Leon Romanovsky <leonro@mellanox.com>
+ */
+
+#include "res.h"
+#include <inttypes.h>
+
+static void print_qp_type(struct rd *rd, uint32_t val)
+{
+	if (rd->json_output)
+		jsonw_string_field(rd->jw, "qp-type", qp_types_to_str(val));
+	else
+		pr_out("qp-type %s ", qp_types_to_str(val));
+}
+
+static const char *cm_id_state_to_str(uint8_t idx)
+{
+	static const char *const cm_id_states_str[] = {
+		"IDLE",		  "ADDR_QUERY",     "ADDR_RESOLVED",
+		"ROUTE_QUERY",    "ROUTE_RESOLVED", "CONNECT",
+		"DISCONNECT",     "ADDR_BOUND",     "LISTEN",
+		"DEVICE_REMOVAL", "DESTROYING"
+	};
+
+	if (idx < ARRAY_SIZE(cm_id_states_str))
+		return cm_id_states_str[idx];
+	return "UNKNOWN";
+}
+
+static const char *cm_id_ps_to_str(uint32_t ps)
+{
+	switch (ps) {
+	case RDMA_PS_IPOIB:
+		return "IPoIB";
+	case RDMA_PS_IB:
+		return "IPoIB";
+	case RDMA_PS_TCP:
+		return "TCP";
+	case RDMA_PS_UDP:
+		return "UDP";
+	default:
+		return "---";
+	}
+}
+
+static void print_cm_id_state(struct rd *rd, uint8_t state)
+{
+	if (rd->json_output) {
+		jsonw_string_field(rd->jw, "state", cm_id_state_to_str(state));
+		return;
+	}
+	pr_out("state %s ", cm_id_state_to_str(state));
+}
+
+static void print_ps(struct rd *rd, uint32_t ps)
+{
+	if (rd->json_output) {
+		jsonw_string_field(rd->jw, "ps", cm_id_ps_to_str(ps));
+		return;
+	}
+	pr_out("ps %s ", cm_id_ps_to_str(ps));
+}
+
+static void print_ipaddr(struct rd *rd, const char *key, char *addrstr,
+			 uint16_t port)
+{
+	if (rd->json_output) {
+		int name_size = INET6_ADDRSTRLEN + strlen(":65535");
+		char json_name[name_size];
+
+		snprintf(json_name, name_size, "%s:%u", addrstr, port);
+		jsonw_string_field(rd->jw, key, json_name);
+		return;
+	}
+	pr_out("%s %s:%u ", key, addrstr, port);
+}
+
+static int ss_ntop(struct nlattr *nla_line, char *addr_str, uint16_t *port)
+{
+	struct __kernel_sockaddr_storage *addr;
+
+	addr = (struct __kernel_sockaddr_storage *)mnl_attr_get_payload(
+		nla_line);
+	switch (addr->ss_family) {
+	case AF_INET: {
+		struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+
+		if (!inet_ntop(AF_INET, (const void *)&sin->sin_addr, addr_str,
+			       INET6_ADDRSTRLEN))
+			return -EINVAL;
+		*port = ntohs(sin->sin_port);
+		break;
+	}
+	case AF_INET6: {
+		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
+
+		if (!inet_ntop(AF_INET6, (const void *)&sin6->sin6_addr,
+			       addr_str, INET6_ADDRSTRLEN))
+			return -EINVAL;
+		*port = ntohs(sin6->sin6_port);
+		break;
+	}
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
+	struct nlattr *nla_table, *nla_entry;
+	struct rd *rd = data;
+	const char *name;
+	int idx;
+
+	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
+	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME] ||
+	    !tb[RDMA_NLDEV_ATTR_RES_CM_ID])
+		return MNL_CB_ERROR;
+
+	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
+	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
+	nla_table = tb[RDMA_NLDEV_ATTR_RES_CM_ID];
+	mnl_attr_for_each_nested(nla_entry, nla_table) {
+		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+		char src_addr_str[INET6_ADDRSTRLEN];
+		char dst_addr_str[INET6_ADDRSTRLEN];
+		uint16_t src_port, dst_port;
+		uint32_t port = 0, pid = 0;
+		uint8_t type = 0, state;
+		uint32_t lqpn = 0, ps;
+		uint32_t cm_idn = 0;
+		char *comm = NULL;
+		int err;
+
+		err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+		if (err != MNL_CB_OK)
+			return -EINVAL;
+
+		if (!nla_line[RDMA_NLDEV_ATTR_RES_STATE] ||
+		    !nla_line[RDMA_NLDEV_ATTR_RES_PS] ||
+		    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
+		     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
+			return MNL_CB_ERROR;
+		}
+
+		if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX])
+			port = mnl_attr_get_u32(
+				nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]);
+
+		if (port && port != rd->port_idx)
+			continue;
+
+		if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN]) {
+			lqpn = mnl_attr_get_u32(
+				nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
+			if (rd_check_is_filtered(rd, "lqpn", lqpn))
+				continue;
+		}
+		if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE]) {
+			type = mnl_attr_get_u8(
+				nla_line[RDMA_NLDEV_ATTR_RES_TYPE]);
+			if (rd_check_is_string_filtered(rd, "qp-type",
+							qp_types_to_str(type)))
+				continue;
+		}
+
+		ps = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PS]);
+		if (rd_check_is_string_filtered(rd, "ps", cm_id_ps_to_str(ps)))
+			continue;
+
+		state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]);
+		if (rd_check_is_string_filtered(rd, "state",
+						cm_id_state_to_str(state)))
+			continue;
+
+		if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]) {
+			if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR],
+				    src_addr_str, &src_port))
+				continue;
+			if (rd_check_is_string_filtered(rd, "src-addr",
+							src_addr_str))
+				continue;
+			if (rd_check_is_filtered(rd, "src-port", src_port))
+				continue;
+		}
+
+		if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]) {
+			if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR],
+				    dst_addr_str, &dst_port))
+				continue;
+			if (rd_check_is_string_filtered(rd, "dst-addr",
+							dst_addr_str))
+				continue;
+			if (rd_check_is_filtered(rd, "dst-port", dst_port))
+				continue;
+		}
+
+		if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
+			pid = mnl_attr_get_u32(
+				nla_line[RDMA_NLDEV_ATTR_RES_PID]);
+			comm = get_task_name(pid);
+		}
+
+		if (rd_check_is_filtered(rd, "pid", pid)) {
+			free(comm);
+			continue;
+		}
+
+		if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])
+			cm_idn = mnl_attr_get_u32(
+				nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]);
+		if (rd_check_is_filtered(rd, "cm-idn", cm_idn))
+			continue;
+
+		if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) {
+			/* discard const from mnl_attr_get_str */
+			comm = (char *)mnl_attr_get_str(
+				nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
+		}
+
+		if (rd->json_output)
+			jsonw_start_array(rd->jw);
+
+		print_link(rd, idx, name, port, nla_line);
+		if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN])
+			print_lqpn(rd, lqpn);
+		if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE])
+			print_qp_type(rd, type);
+		print_cm_id_state(rd, state);
+		print_ps(rd, ps);
+		print_pid(rd, pid);
+		print_comm(rd, comm, nla_line);
+		if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])
+			res_print_uint(rd, "cm-idn", cm_idn);
+
+		if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR])
+			print_ipaddr(rd, "src-addr", src_addr_str, src_port);
+		if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR])
+			print_ipaddr(rd, "dst-addr", dst_addr_str, dst_port);
+
+		if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
+			free(comm);
+
+		print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
+		newline(rd);
+	}
+	return MNL_CB_OK;
+}
diff --git a/rdma/res.c b/rdma/res.c
index 7956882e..d5ae60e1 100644
--- a/rdma/res.c
+++ b/rdma/res.c
@@ -140,7 +140,7 @@ static const char *qp_states_to_str(uint8_t idx)
 	return "UNKNOWN";
 }
 
-static const char *qp_types_to_str(uint8_t idx)
+const char *qp_types_to_str(uint8_t idx)
 {
 	static const char * const qp_types_str[] = { "SMI", "GSI", "RC",
 						     "UC", "UD", "RAW_IPV6",
@@ -153,7 +153,7 @@ static const char *qp_types_to_str(uint8_t idx)
 	return "UNKNOWN";
 }
 
-static void print_lqpn(struct rd *rd, uint32_t val)
+void print_lqpn(struct rd *rd, uint32_t val)
 {
 	if (rd->json_output)
 		jsonw_uint_field(rd->jw, "lqpn", val);
@@ -259,8 +259,8 @@ void print_dev(struct rd *rd, uint32_t idx, const char *name)
 	}
 }
 
-static void print_link(struct rd *rd, uint32_t idx, const char *name,
-		       uint32_t port, struct nlattr **nla_line)
+void print_link(struct rd *rd, uint32_t idx, const char *name, uint32_t port,
+		struct nlattr **nla_line)
 {
 	if (rd->json_output) {
 		jsonw_uint_field(rd->jw, "ifindex", idx);
@@ -451,250 +451,6 @@ static int res_qp_parse_cb(const struct nlmsghdr *nlh, void *data)
 	return MNL_CB_OK;
 }
 
-static void print_qp_type(struct rd *rd, uint32_t val)
-{
-	if (rd->json_output)
-		jsonw_string_field(rd->jw, "qp-type",
-				   qp_types_to_str(val));
-	else
-		pr_out("qp-type %s ", qp_types_to_str(val));
-}
-
-static const char *cm_id_state_to_str(uint8_t idx)
-{
-	static const char * const cm_id_states_str[] = {
-		"IDLE", "ADDR_QUERY", "ADDR_RESOLVED", "ROUTE_QUERY",
-		"ROUTE_RESOLVED", "CONNECT", "DISCONNECT", "ADDR_BOUND",
-		"LISTEN", "DEVICE_REMOVAL", "DESTROYING" };
-
-	if (idx < ARRAY_SIZE(cm_id_states_str))
-		return cm_id_states_str[idx];
-	return "UNKNOWN";
-}
-
-static const char *cm_id_ps_to_str(uint32_t ps)
-{
-	switch (ps) {
-	case RDMA_PS_IPOIB:
-		return "IPoIB";
-	case RDMA_PS_IB:
-		return "IPoIB";
-	case RDMA_PS_TCP:
-		return "TCP";
-	case RDMA_PS_UDP:
-		return "UDP";
-	default:
-		return "---";
-	}
-}
-
-static void print_cm_id_state(struct rd *rd, uint8_t state)
-{
-	if (rd->json_output) {
-		jsonw_string_field(rd->jw, "state", cm_id_state_to_str(state));
-		return;
-	}
-	pr_out("state %s ", cm_id_state_to_str(state));
-}
-
-static void print_ps(struct rd *rd, uint32_t ps)
-{
-	if (rd->json_output) {
-		jsonw_string_field(rd->jw, "ps", cm_id_ps_to_str(ps));
-		return;
-	}
-	pr_out("ps %s ", cm_id_ps_to_str(ps));
-}
-
-static void print_ipaddr(struct rd *rd, const char *key, char *addrstr,
-			 uint16_t port)
-{
-	if (rd->json_output) {
-		int name_size = INET6_ADDRSTRLEN+strlen(":65535");
-		char json_name[name_size];
-
-		snprintf(json_name, name_size, "%s:%u", addrstr, port);
-		jsonw_string_field(rd->jw, key, json_name);
-		return;
-	}
-	pr_out("%s %s:%u ", key, addrstr, port);
-}
-
-static int ss_ntop(struct nlattr *nla_line, char *addr_str, uint16_t *port)
-{
-	struct __kernel_sockaddr_storage *addr;
-
-	addr = (struct __kernel_sockaddr_storage *)
-						mnl_attr_get_payload(nla_line);
-	switch (addr->ss_family) {
-	case AF_INET: {
-		struct sockaddr_in *sin = (struct sockaddr_in *)addr;
-
-		if (!inet_ntop(AF_INET, (const void *)&sin->sin_addr, addr_str,
-			       INET6_ADDRSTRLEN))
-			return -EINVAL;
-		*port = ntohs(sin->sin_port);
-		break;
-	}
-	case AF_INET6: {
-		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
-
-		if (!inet_ntop(AF_INET6, (const void *)&sin6->sin6_addr,
-			       addr_str, INET6_ADDRSTRLEN))
-			return -EINVAL;
-		*port = ntohs(sin6->sin6_port);
-		break;
-	}
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data)
-{
-	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
-	struct nlattr *nla_table, *nla_entry;
-	struct rd *rd = data;
-	const char *name;
-	int idx;
-
-	mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
-	if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] ||
-	    !tb[RDMA_NLDEV_ATTR_DEV_NAME] ||
-	    !tb[RDMA_NLDEV_ATTR_RES_CM_ID])
-		return MNL_CB_ERROR;
-
-	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
-	idx =  mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
-	nla_table = tb[RDMA_NLDEV_ATTR_RES_CM_ID];
-	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
-		char src_addr_str[INET6_ADDRSTRLEN];
-		char dst_addr_str[INET6_ADDRSTRLEN];
-		uint16_t src_port, dst_port;
-		uint32_t port = 0, pid = 0;
-		uint8_t type = 0, state;
-		uint32_t lqpn = 0, ps;
-		uint32_t cm_idn = 0;
-		char *comm = NULL;
-		int err;
-
-		err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-		if (err != MNL_CB_OK)
-			return -EINVAL;
-
-		if (!nla_line[RDMA_NLDEV_ATTR_RES_STATE] ||
-		    !nla_line[RDMA_NLDEV_ATTR_RES_PS] ||
-		    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
-		     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
-			return MNL_CB_ERROR;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX])
-			port = mnl_attr_get_u32(
-					nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]);
-
-		if (port && port != rd->port_idx)
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN]) {
-			lqpn = mnl_attr_get_u32(
-					nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
-			if (rd_check_is_filtered(rd, "lqpn", lqpn))
-				continue;
-		}
-		if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE]) {
-			type = mnl_attr_get_u8(
-					nla_line[RDMA_NLDEV_ATTR_RES_TYPE]);
-			if (rd_check_is_string_filtered(rd, "qp-type",
-							qp_types_to_str(type)))
-				continue;
-		}
-
-		ps = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PS]);
-		if (rd_check_is_string_filtered(rd, "ps", cm_id_ps_to_str(ps)))
-			continue;
-
-		state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]);
-		if (rd_check_is_string_filtered(rd, "state",
-						cm_id_state_to_str(state)))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]) {
-			if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR],
-				    src_addr_str, &src_port))
-				continue;
-			if (rd_check_is_string_filtered(rd, "src-addr",
-							src_addr_str))
-				continue;
-			if (rd_check_is_filtered(rd, "src-port", src_port))
-				continue;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]) {
-			if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR],
-				    dst_addr_str, &dst_port))
-				continue;
-			if (rd_check_is_string_filtered(rd, "dst-addr",
-							dst_addr_str))
-				continue;
-			if (rd_check_is_filtered(rd, "dst-port", dst_port))
-				continue;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
-			pid = mnl_attr_get_u32(
-					nla_line[RDMA_NLDEV_ATTR_RES_PID]);
-			comm = get_task_name(pid);
-		}
-
-		if (rd_check_is_filtered(rd, "pid", pid)) {
-			free(comm);
-			continue;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])
-			cm_idn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]);
-		if (rd_check_is_filtered(rd, "cm-idn", cm_idn))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) {
-			/* discard const from mnl_attr_get_str */
-			comm = (char *)mnl_attr_get_str(
-				nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
-		}
-
-		if (rd->json_output)
-			jsonw_start_array(rd->jw);
-
-		print_link(rd, idx, name, port, nla_line);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN])
-			print_lqpn(rd, lqpn);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE])
-			print_qp_type(rd, type);
-		print_cm_id_state(rd, state);
-		print_ps(rd, ps);
-		print_pid(rd, pid);
-		print_comm(rd, comm, nla_line);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])
-			res_print_uint(rd, "cm-idn", cm_idn);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR])
-			print_ipaddr(rd, "src-addr", src_addr_str, src_port);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR])
-			print_ipaddr(rd, "dst-addr", dst_addr_str, dst_port);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
-			free(comm);
-
-		print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
-		newline(rd);
-	}
-	return MNL_CB_OK;
-}
-
 void print_users(struct rd *rd, uint64_t val)
 {
 	if (rd->json_output)
@@ -721,25 +477,6 @@ filters qp_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 
 RES_FUNC(res_qp,	RDMA_NLDEV_CMD_RES_QP_GET, qp_valid_filters, false);
 
-static const
-struct filters cm_id_valid_filters[MAX_NUMBER_OF_FILTERS] = {
-	{ .name = "link", .is_number = false },
-	{ .name = "lqpn", .is_number = true },
-	{ .name = "qp-type", .is_number = false },
-	{ .name = "state", .is_number = false },
-	{ .name = "ps", .is_number = false },
-	{ .name = "dev-type", .is_number = false },
-	{ .name = "transport-type", .is_number = false },
-	{ .name = "pid", .is_number = true },
-	{ .name = "src-addr", .is_number = false },
-	{ .name = "src-port", .is_number = true },
-	{ .name = "dst-addr", .is_number = false },
-	{ .name = "dst-port", .is_number = true },
-	{ .name = "cm-idn", .is_number = true }
-};
-
-RES_FUNC(res_cm_id, RDMA_NLDEV_CMD_RES_CM_ID_GET, cm_id_valid_filters, false);
-
 static int res_show(struct rd *rd)
 {
 	const struct rd_cmd cmds[] = {
diff --git a/rdma/res.h b/rdma/res.h
index 19f0d420..e9d0d12e 100644
--- a/rdma/res.h
+++ b/rdma/res.h
@@ -12,6 +12,7 @@ int _res_send_msg(struct rd *rd, uint32_t command, mnl_cb_t callback);
 int res_pd_parse_cb(const struct nlmsghdr *nlh, void *data);
 int res_mr_parse_cb(const struct nlmsghdr *nlh, void *data);
 int res_cq_parse_cb(const struct nlmsghdr *nlh, void *data);
+int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data);
 
 #define RES_FUNC(name, command, valid_filters, strict_port) \
 	static inline int _##name(struct rd *rd)\
@@ -71,12 +72,35 @@ struct filters cq_valid_filters[MAX_NUMBER_OF_FILTERS] = {
 
 RES_FUNC(res_cq, RDMA_NLDEV_CMD_RES_CQ_GET, cq_valid_filters, true);
 
+static const
+struct filters cm_id_valid_filters[MAX_NUMBER_OF_FILTERS] = {
+	{ .name = "link", .is_number = false },
+	{ .name = "lqpn", .is_number = true },
+	{ .name = "qp-type", .is_number = false },
+	{ .name = "state", .is_number = false },
+	{ .name = "ps", .is_number = false },
+	{ .name = "dev-type", .is_number = false },
+	{ .name = "transport-type", .is_number = false },
+	{ .name = "pid", .is_number = true },
+	{ .name = "src-addr", .is_number = false },
+	{ .name = "src-port", .is_number = true },
+	{ .name = "dst-addr", .is_number = false },
+	{ .name = "dst-port", .is_number = true },
+	{ .name = "cm-idn", .is_number = true }
+};
+
+RES_FUNC(res_cm_id, RDMA_NLDEV_CMD_RES_CM_ID_GET, cm_id_valid_filters, false);
+
 char *get_task_name(uint32_t pid);
 void print_dev(struct rd *rd, uint32_t idx, const char *name);
+void print_link(struct rd *rd, uint32_t idx, const char *name, uint32_t port,
+		struct nlattr **nla_line);
 void print_users(struct rd *rd, uint64_t val);
 void print_key(struct rd *rd, const char *name, uint64_t val);
 void res_print_uint(struct rd *rd, const char *name, uint64_t val);
 void print_pid(struct rd *rd, uint32_t val);
 void print_comm(struct rd *rd, const char *str, struct nlattr **nla_line);
+const char *qp_types_to_str(uint8_t idx);
+void print_lqpn(struct rd *rd, uint32_t val);
 
 #endif /* _RDMA_TOOL_RES_H_ */
-- 
2.19.1


^ permalink raw reply related

* [PATCH iproute2-next v1 14/19] rdma: Separate MR code
From: Leon Romanovsky @ 2019-02-20  7:21 UTC (permalink / raw)
  To: David Ahern; +Cc: Leon Romanovsky, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <20190220072136.3840-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/res-mr.c | 178 +++++++++++++++++++++++++-------------------------
 1 file changed, 90 insertions(+), 88 deletions(-)

diff --git a/rdma/res-mr.c b/rdma/res-mr.c
index e373035a..36993b5e 100644
--- a/rdma/res-mr.c
+++ b/rdma/res-mr.c
@@ -7,11 +7,96 @@
 #include "res.h"
 #include <inttypes.h>
 
+static int res_mr_line(struct rd *rd, const char *name, int idx,
+		       struct nlattr *nla_entry)
+{
+	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+	uint32_t rkey = 0, lkey = 0;
+	uint64_t iova = 0, mrlen;
+	char *comm = NULL;
+	uint32_t pdn = 0;
+	uint32_t mrn = 0;
+	uint32_t pid = 0;
+	int err;
+
+	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+	if (err != MNL_CB_OK)
+		return MNL_CB_ERROR;
+
+	if (!nla_line[RDMA_NLDEV_ATTR_RES_MRLEN] ||
+	    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
+	     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
+		return MNL_CB_ERROR;
+	}
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_RKEY])
+		rkey = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_RKEY]);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_LKEY])
+		lkey = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LKEY]);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_IOVA])
+		iova = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_IOVA]);
+
+	mrlen = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_MRLEN]);
+	if (rd_check_is_filtered(rd, "mrlen", mrlen))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
+		pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]);
+		comm = get_task_name(pid);
+	}
+
+	if (rd_check_is_filtered(rd, "pid", pid))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_MRN])
+		mrn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_MRN]);
+	if (rd_check_is_filtered(rd, "mrn", mrn))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
+		pdn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
+	if (rd_check_is_filtered(rd, "pdn", pdn))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
+		/* discard const from mnl_attr_get_str */
+		comm = (char *)mnl_attr_get_str(
+			nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
+
+	if (rd->json_output)
+		jsonw_start_array(rd->jw);
+
+	print_dev(rd, idx, name);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_RKEY])
+		print_key(rd, "rkey", rkey);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_LKEY])
+		print_key(rd, "lkey", lkey);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_IOVA])
+		print_key(rd, "iova", iova);
+	res_print_uint(rd, "mrlen", mrlen);
+	res_print_uint(rd, "pid", pid);
+	print_comm(rd, comm, nla_line);
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_MRN])
+		res_print_uint(rd, "mrn", mrn);
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
+		res_print_uint(rd, "pdn", pdn);
+
+	print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
+	newline(rd);
+
+out:
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
+		free(comm);
+	return MNL_CB_OK;
+}
 int res_mr_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
 	struct nlattr *nla_table, *nla_entry;
 	struct rd *rd = data;
+	int ret = MNL_CB_OK;
 	const char *name;
 	uint32_t idx;
 
@@ -25,93 +110,10 @@ int res_mr_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_MR];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
-		uint32_t rkey = 0, lkey = 0;
-		uint64_t iova = 0, mrlen;
-		char *comm = NULL;
-		uint32_t pdn = 0;
-		uint32_t mrn = 0;
-		uint32_t pid = 0;
-		int err;
-
-		err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-		if (err != MNL_CB_OK)
-			return MNL_CB_ERROR;
-
-		if (!nla_line[RDMA_NLDEV_ATTR_RES_MRLEN] ||
-		    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
-		     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
-			return MNL_CB_ERROR;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_RKEY])
-			rkey = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_RKEY]);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_LKEY])
-			lkey = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_LKEY]);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_IOVA])
-			iova = mnl_attr_get_u64(
-				nla_line[RDMA_NLDEV_ATTR_RES_IOVA]);
-
-		mrlen = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_MRLEN]);
-		if (rd_check_is_filtered(rd, "mrlen", mrlen))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
-			pid = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_PID]);
-			comm = get_task_name(pid);
-		}
-
-		if (rd_check_is_filtered(rd, "pid", pid)) {
-			free(comm);
-			continue;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_MRN])
-			mrn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_MRN]);
-		if (rd_check_is_filtered(rd, "mrn", mrn))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
-			pdn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_PDN]);
-		if (rd_check_is_filtered(rd, "pdn", pdn))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
-			/* discard const from mnl_attr_get_str */
-			comm = (char *)mnl_attr_get_str(
-				nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
-
-		if (rd->json_output)
-			jsonw_start_array(rd->jw);
-
-		print_dev(rd, idx, name);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_RKEY])
-			print_key(rd, "rkey", rkey);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_LKEY])
-			print_key(rd, "lkey", lkey);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_IOVA])
-			print_key(rd, "iova", iova);
-		res_print_uint(rd, "mrlen", mrlen);
-		res_print_uint(rd, "pid", pid);
-		print_comm(rd, comm, nla_line);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_MRN])
-			res_print_uint(rd, "mrn", mrn);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PDN])
-			res_print_uint(rd, "pdn", pdn);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
-			free(comm);
-
-		print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
-		newline(rd);
+		ret = res_mr_line(rd, name, idx, nla_entry);
+
+		if (ret != MNL_CB_OK)
+			break;
 	}
-	return MNL_CB_OK;
+	return ret;
 }
-
-- 
2.19.1


^ permalink raw reply related

* [PATCH iproute2-next v1 13/19] rdma: Refactor CQ prints
From: Leon Romanovsky @ 2019-02-20  7:21 UTC (permalink / raw)
  To: David Ahern; +Cc: Leon Romanovsky, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <20190220072136.3840-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/res-cq.c | 177 ++++++++++++++++++++++++++------------------------
 1 file changed, 91 insertions(+), 86 deletions(-)

diff --git a/rdma/res-cq.c b/rdma/res-cq.c
index 93c18251..e50d76ce 100644
--- a/rdma/res-cq.c
+++ b/rdma/res-cq.c
@@ -27,11 +27,97 @@ static void print_poll_ctx(struct rd *rd, uint8_t poll_ctx)
 	pr_out("poll-ctx %s ", poll_ctx_to_str(poll_ctx));
 }
 
+static int res_cq_line(struct rd *rd, const char *name, int idx,
+		       struct nlattr *nla_entry)
+{
+	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+	char *comm = NULL;
+	uint32_t pid = 0;
+	uint8_t poll_ctx = 0;
+	uint32_t ctxn = 0;
+	uint32_t cqn = 0;
+	uint64_t users;
+	uint32_t cqe;
+	int err;
+
+	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+	if (err != MNL_CB_OK)
+		return MNL_CB_ERROR;
+
+	if (!nla_line[RDMA_NLDEV_ATTR_RES_CQE] ||
+	    !nla_line[RDMA_NLDEV_ATTR_RES_USECNT] ||
+	    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
+	     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
+		return MNL_CB_ERROR;
+	}
+
+	cqe = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CQE]);
+
+	users = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_USECNT]);
+	if (rd_check_is_filtered(rd, "users", users))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX]) {
+		poll_ctx =
+			mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX]);
+		if (rd_check_is_string_filtered(rd, "poll-ctx",
+						poll_ctx_to_str(poll_ctx)))
+			goto out;
+	}
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
+		pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]);
+		comm = get_task_name(pid);
+	}
+
+	if (rd_check_is_filtered(rd, "pid", pid))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_CQN])
+		cqn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CQN]);
+	if (rd_check_is_filtered(rd, "cqn", cqn))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
+		ctxn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
+	if (rd_check_is_filtered(rd, "ctxn", ctxn))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
+		/* discard const from mnl_attr_get_str */
+		comm = (char *)mnl_attr_get_str(
+			nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
+
+	if (rd->json_output)
+		jsonw_start_array(rd->jw);
+
+	print_dev(rd, idx, name);
+	res_print_uint(rd, "cqe", cqe);
+	res_print_uint(rd, "users", users);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX])
+		print_poll_ctx(rd, poll_ctx);
+	res_print_uint(rd, "pid", pid);
+	print_comm(rd, comm, nla_line);
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_CQN])
+		res_print_uint(rd, "cqn", cqn);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
+		res_print_uint(rd, "ctxn", ctxn);
+
+	print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
+	newline(rd);
+
+out:	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
+		free(comm);
+	return MNL_CB_OK;
+}
+
 int res_cq_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
 	struct nlattr *nla_table, *nla_entry;
 	struct rd *rd = data;
+	int ret = MNL_CB_OK;
 	const char *name;
 	uint32_t idx;
 
@@ -45,91 +131,10 @@ int res_cq_parse_cb(const struct nlmsghdr *nlh, void *data)
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_CQ];
 
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
-		char *comm = NULL;
-		uint32_t pid = 0;
-		uint8_t poll_ctx = 0;
-		uint32_t ctxn = 0;
-		uint32_t cqn = 0;
-		uint64_t users;
-		uint32_t cqe;
-		int err;
-
-		err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-		if (err != MNL_CB_OK)
-			return MNL_CB_ERROR;
-
-		if (!nla_line[RDMA_NLDEV_ATTR_RES_CQE] ||
-		    !nla_line[RDMA_NLDEV_ATTR_RES_USECNT] ||
-		    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
-		     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
-			return MNL_CB_ERROR;
-		}
-
-		cqe = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CQE]);
-
-		users = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_USECNT]);
-		if (rd_check_is_filtered(rd, "users", users))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX]) {
-			poll_ctx = mnl_attr_get_u8(
-				nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX]);
-			if (rd_check_is_string_filtered(
-				    rd, "poll-ctx", poll_ctx_to_str(poll_ctx)))
-				continue;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
-			pid = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_PID]);
-			comm = get_task_name(pid);
-		}
-
-		if (rd_check_is_filtered(rd, "pid", pid)) {
-			free(comm);
-			continue;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_CQN])
-			cqn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_CQN]);
-		if (rd_check_is_filtered(rd, "cqn", cqn))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
-			ctxn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_CTXN]);
-		if (rd_check_is_filtered(rd, "ctxn", ctxn))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])
-			/* discard const from mnl_attr_get_str */
-			comm = (char *)mnl_attr_get_str(
-				nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
-
-		if (rd->json_output)
-			jsonw_start_array(rd->jw);
-
-		print_dev(rd, idx, name);
-		res_print_uint(rd, "cqe", cqe);
-		res_print_uint(rd, "users", users);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_POLL_CTX])
-			print_poll_ctx(rd, poll_ctx);
-		res_print_uint(rd, "pid", pid);
-		print_comm(rd, comm, nla_line);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_CQN])
-			res_print_uint(rd, "cqn", cqn);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_CTXN])
-			res_print_uint(rd, "ctxn", ctxn);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
-			free(comm);
-
-		print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
-		newline(rd);
+		ret = res_cq_line(rd, name, idx, nla_entry);
+
+		if (ret != MNL_CB_OK)
+			break;
 	}
-	return MNL_CB_OK;
+	return ret;
 }
-
-- 
2.19.1


^ permalink raw reply related

* [PATCH iproute2-next v1 12/19] rdma: Simplify CM_ID print code
From: Leon Romanovsky @ 2019-02-20  7:21 UTC (permalink / raw)
  To: David Ahern; +Cc: Leon Romanovsky, netdev, RDMA mailing list, Stephen Hemminger
In-Reply-To: <20190220072136.3840-1-leon@kernel.org>

From: Leon Romanovsky <leonro@mellanox.com>

Refactor our the CM_ID print code.

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 rdma/res-cmid.c | 246 ++++++++++++++++++++++++------------------------
 1 file changed, 124 insertions(+), 122 deletions(-)

diff --git a/rdma/res-cmid.c b/rdma/res-cmid.c
index 5eea7a6b..12d1acee 100644
--- a/rdma/res-cmid.c
+++ b/rdma/res-cmid.c
@@ -108,11 +108,130 @@ static int ss_ntop(struct nlattr *nla_line, char *addr_str, uint16_t *port)
 	return 0;
 }
 
+static int res_cm_id_line(struct rd *rd, const char *name, int idx,
+			  struct nlattr *nla_entry)
+{
+	struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
+	char src_addr_str[INET6_ADDRSTRLEN];
+	char dst_addr_str[INET6_ADDRSTRLEN];
+	uint16_t src_port, dst_port;
+	uint32_t port = 0, pid = 0;
+	uint8_t type = 0, state;
+	uint32_t lqpn = 0, ps;
+	uint32_t cm_idn = 0;
+	char *comm = NULL;
+	int err;
+
+	err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
+	if (err != MNL_CB_OK)
+		return MNL_CB_ERROR;
+
+	if (!nla_line[RDMA_NLDEV_ATTR_RES_STATE] ||
+	    !nla_line[RDMA_NLDEV_ATTR_RES_PS] ||
+	    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
+	     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
+		return MNL_CB_ERROR;
+	}
+
+	if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX])
+		port = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]);
+
+	if (port && port != rd->port_idx)
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN]) {
+		lqpn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
+		if (rd_check_is_filtered(rd, "lqpn", lqpn))
+			goto out;
+	}
+	if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE]) {
+		type = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_TYPE]);
+		if (rd_check_is_string_filtered(rd, "qp-type",
+						qp_types_to_str(type)))
+			goto out;
+	}
+
+	ps = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PS]);
+	if (rd_check_is_string_filtered(rd, "ps", cm_id_ps_to_str(ps)))
+		goto out;
+
+	state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]);
+	if (rd_check_is_string_filtered(rd, "state", cm_id_state_to_str(state)))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]) {
+		if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR],
+			    src_addr_str, &src_port))
+			goto out;
+		if (rd_check_is_string_filtered(rd, "src-addr", src_addr_str))
+			goto out;
+		if (rd_check_is_filtered(rd, "src-port", src_port))
+			goto out;
+	}
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]) {
+		if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR],
+			    dst_addr_str, &dst_port))
+			goto out;
+		if (rd_check_is_string_filtered(rd, "dst-addr", dst_addr_str))
+			goto out;
+		if (rd_check_is_filtered(rd, "dst-port", dst_port))
+			goto out;
+	}
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
+		pid = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PID]);
+		comm = get_task_name(pid);
+	}
+
+	if (rd_check_is_filtered(rd, "pid", pid))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])
+		cm_idn = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]);
+	if (rd_check_is_filtered(rd, "cm-idn", cm_idn))
+		goto out;
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) {
+		/* discard const from mnl_attr_get_str */
+		comm = (char *)mnl_attr_get_str(
+			nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
+	}
+
+	if (rd->json_output)
+		jsonw_start_array(rd->jw);
+
+	print_link(rd, idx, name, port, nla_line);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN])
+		res_print_uint(rd, "lqpn", lqpn);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE])
+		print_qp_type(rd, type);
+	print_cm_id_state(rd, state);
+	print_ps(rd, ps);
+	res_print_uint(rd, "pid", pid);
+	print_comm(rd, comm, nla_line);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])
+		res_print_uint(rd, "cm-idn", cm_idn);
+
+	if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR])
+		print_ipaddr(rd, "src-addr", src_addr_str, src_port);
+	if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR])
+		print_ipaddr(rd, "dst-addr", dst_addr_str, dst_port);
+
+	print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
+	newline(rd);
+
+out:	if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
+		free(comm);
+	return MNL_CB_OK;
+}
+
 int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
 	struct nlattr *nla_table, *nla_entry;
 	struct rd *rd = data;
+	int ret = MNL_CB_OK;
 	const char *name;
 	int idx;
 
@@ -124,129 +243,12 @@ int res_cm_id_parse_cb(const struct nlmsghdr *nlh, void *data)
 	name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
 	idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
 	nla_table = tb[RDMA_NLDEV_ATTR_RES_CM_ID];
+
 	mnl_attr_for_each_nested(nla_entry, nla_table) {
-		struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {};
-		char src_addr_str[INET6_ADDRSTRLEN];
-		char dst_addr_str[INET6_ADDRSTRLEN];
-		uint16_t src_port, dst_port;
-		uint32_t port = 0, pid = 0;
-		uint8_t type = 0, state;
-		uint32_t lqpn = 0, ps;
-		uint32_t cm_idn = 0;
-		char *comm = NULL;
-		int err;
-
-		err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line);
-		if (err != MNL_CB_OK)
-			return -EINVAL;
+		ret = res_cm_id_line(rd, name, idx, nla_entry);
 
-		if (!nla_line[RDMA_NLDEV_ATTR_RES_STATE] ||
-		    !nla_line[RDMA_NLDEV_ATTR_RES_PS] ||
-		    (!nla_line[RDMA_NLDEV_ATTR_RES_PID] &&
-		     !nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME])) {
-			return MNL_CB_ERROR;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_PORT_INDEX])
-			port = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_PORT_INDEX]);
-
-		if (port && port != rd->port_idx)
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN]) {
-			lqpn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_LQPN]);
-			if (rd_check_is_filtered(rd, "lqpn", lqpn))
-				continue;
-		}
-		if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE]) {
-			type = mnl_attr_get_u8(
-				nla_line[RDMA_NLDEV_ATTR_RES_TYPE]);
-			if (rd_check_is_string_filtered(rd, "qp-type",
-							qp_types_to_str(type)))
-				continue;
-		}
-
-		ps = mnl_attr_get_u32(nla_line[RDMA_NLDEV_ATTR_RES_PS]);
-		if (rd_check_is_string_filtered(rd, "ps", cm_id_ps_to_str(ps)))
-			continue;
-
-		state = mnl_attr_get_u8(nla_line[RDMA_NLDEV_ATTR_RES_STATE]);
-		if (rd_check_is_string_filtered(rd, "state",
-						cm_id_state_to_str(state)))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR]) {
-			if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR],
-				    src_addr_str, &src_port))
-				continue;
-			if (rd_check_is_string_filtered(rd, "src-addr",
-							src_addr_str))
-				continue;
-			if (rd_check_is_filtered(rd, "src-port", src_port))
-				continue;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR]) {
-			if (ss_ntop(nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR],
-				    dst_addr_str, &dst_port))
-				continue;
-			if (rd_check_is_string_filtered(rd, "dst-addr",
-							dst_addr_str))
-				continue;
-			if (rd_check_is_filtered(rd, "dst-port", dst_port))
-				continue;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID]) {
-			pid = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_PID]);
-			comm = get_task_name(pid);
-		}
-
-		if (rd_check_is_filtered(rd, "pid", pid)) {
-			free(comm);
-			continue;
-		}
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])
-			cm_idn = mnl_attr_get_u32(
-				nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN]);
-		if (rd_check_is_filtered(rd, "cm-idn", cm_idn))
-			continue;
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]) {
-			/* discard const from mnl_attr_get_str */
-			comm = (char *)mnl_attr_get_str(
-				nla_line[RDMA_NLDEV_ATTR_RES_KERN_NAME]);
-		}
-
-		if (rd->json_output)
-			jsonw_start_array(rd->jw);
-
-		print_link(rd, idx, name, port, nla_line);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_LQPN])
-			res_print_uint(rd, "lqpn", lqpn);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_TYPE])
-			print_qp_type(rd, type);
-		print_cm_id_state(rd, state);
-		print_ps(rd, ps);
-		res_print_uint(rd, "pid", pid);
-		print_comm(rd, comm, nla_line);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_CM_IDN])
-			res_print_uint(rd, "cm-idn", cm_idn);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_SRC_ADDR])
-			print_ipaddr(rd, "src-addr", src_addr_str, src_port);
-		if (nla_line[RDMA_NLDEV_ATTR_RES_DST_ADDR])
-			print_ipaddr(rd, "dst-addr", dst_addr_str, dst_port);
-
-		if (nla_line[RDMA_NLDEV_ATTR_RES_PID])
-			free(comm);
-
-		print_driver_table(rd, nla_line[RDMA_NLDEV_ATTR_DRIVER]);
-		newline(rd);
+		if (ret != MNL_CB_OK)
+			break;
 	}
-	return MNL_CB_OK;
+	return ret;
 }
-- 
2.19.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox