@@ -4518,6 +4518,35 @@ static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
4518
4518
return err ;
4519
4519
}
4520
4520
4521
+ static int devlink_fmsg_dumpit (struct devlink_fmsg * fmsg , struct sk_buff * skb ,
4522
+ struct netlink_callback * cb ,
4523
+ enum devlink_command cmd )
4524
+ {
4525
+ int index = cb -> args [0 ];
4526
+ int tmp_index = index ;
4527
+ void * hdr ;
4528
+ int err ;
4529
+
4530
+ hdr = genlmsg_put (skb , NETLINK_CB (cb -> skb ).portid , cb -> nlh -> nlmsg_seq ,
4531
+ & devlink_nl_family , NLM_F_ACK | NLM_F_MULTI , cmd );
4532
+ if (!hdr ) {
4533
+ err = - EMSGSIZE ;
4534
+ goto nla_put_failure ;
4535
+ }
4536
+
4537
+ err = devlink_fmsg_prepare_skb (fmsg , skb , & index );
4538
+ if ((err && err != - EMSGSIZE ) || tmp_index == index )
4539
+ goto nla_put_failure ;
4540
+
4541
+ cb -> args [0 ] = index ;
4542
+ genlmsg_end (skb , hdr );
4543
+ return skb -> len ;
4544
+
4545
+ nla_put_failure :
4546
+ genlmsg_cancel (skb , hdr );
4547
+ return err ;
4548
+ }
4549
+
4521
4550
struct devlink_health_reporter {
4522
4551
struct list_head list ;
4523
4552
void * priv ;
@@ -4750,17 +4779,16 @@ int devlink_health_report(struct devlink_health_reporter *reporter,
4750
4779
EXPORT_SYMBOL_GPL (devlink_health_report );
4751
4780
4752
4781
static struct devlink_health_reporter *
4753
- devlink_health_reporter_get_from_info (struct devlink * devlink ,
4754
- struct genl_info * info )
4782
+ devlink_health_reporter_get_from_attrs (struct devlink * devlink ,
4783
+ struct nlattr * * attrs )
4755
4784
{
4756
4785
struct devlink_health_reporter * reporter ;
4757
4786
char * reporter_name ;
4758
4787
4759
- if (!info -> attrs [DEVLINK_ATTR_HEALTH_REPORTER_NAME ])
4788
+ if (!attrs [DEVLINK_ATTR_HEALTH_REPORTER_NAME ])
4760
4789
return NULL ;
4761
4790
4762
- reporter_name =
4763
- nla_data (info -> attrs [DEVLINK_ATTR_HEALTH_REPORTER_NAME ]);
4791
+ reporter_name = nla_data (attrs [DEVLINK_ATTR_HEALTH_REPORTER_NAME ]);
4764
4792
mutex_lock (& devlink -> reporters_lock );
4765
4793
reporter = devlink_health_reporter_find_by_name (devlink , reporter_name );
4766
4794
if (reporter )
@@ -4769,6 +4797,48 @@ devlink_health_reporter_get_from_info(struct devlink *devlink,
4769
4797
return reporter ;
4770
4798
}
4771
4799
4800
+ static struct devlink_health_reporter *
4801
+ devlink_health_reporter_get_from_info (struct devlink * devlink ,
4802
+ struct genl_info * info )
4803
+ {
4804
+ return devlink_health_reporter_get_from_attrs (devlink , info -> attrs );
4805
+ }
4806
+
4807
+ static struct devlink_health_reporter *
4808
+ devlink_health_reporter_get_from_cb (struct netlink_callback * cb )
4809
+ {
4810
+ struct devlink_health_reporter * reporter ;
4811
+ struct devlink * devlink ;
4812
+ struct nlattr * * attrs ;
4813
+ int err ;
4814
+
4815
+ attrs = kmalloc_array (DEVLINK_ATTR_MAX + 1 , sizeof (* attrs ), GFP_KERNEL );
4816
+ if (!attrs )
4817
+ return NULL ;
4818
+
4819
+ err = nlmsg_parse_deprecated (cb -> nlh ,
4820
+ GENL_HDRLEN + devlink_nl_family .hdrsize ,
4821
+ attrs , DEVLINK_ATTR_MAX ,
4822
+ devlink_nl_family .policy , cb -> extack );
4823
+ if (err )
4824
+ goto free ;
4825
+
4826
+ mutex_lock (& devlink_mutex );
4827
+ devlink = devlink_get_from_attrs (sock_net (cb -> skb -> sk ), attrs );
4828
+ if (IS_ERR (devlink ))
4829
+ goto unlock ;
4830
+
4831
+ reporter = devlink_health_reporter_get_from_attrs (devlink , attrs );
4832
+ mutex_unlock (& devlink_mutex );
4833
+ kfree (attrs );
4834
+ return reporter ;
4835
+ unlock :
4836
+ mutex_unlock (& devlink_mutex );
4837
+ free :
4838
+ kfree (attrs );
4839
+ return NULL ;
4840
+ }
4841
+
4772
4842
static void
4773
4843
devlink_health_reporter_put (struct devlink_health_reporter * reporter )
4774
4844
{
@@ -5004,32 +5074,40 @@ static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
5004
5074
return err ;
5005
5075
}
5006
5076
5007
- static int devlink_nl_cmd_health_reporter_dump_get_doit (struct sk_buff * skb ,
5008
- struct genl_info * info )
5077
+ static int
5078
+ devlink_nl_cmd_health_reporter_dump_get_dumpit (struct sk_buff * skb ,
5079
+ struct netlink_callback * cb )
5009
5080
{
5010
- struct devlink * devlink = info -> user_ptr [0 ];
5011
5081
struct devlink_health_reporter * reporter ;
5082
+ u64 start = cb -> args [0 ];
5012
5083
int err ;
5013
5084
5014
- reporter = devlink_health_reporter_get_from_info ( devlink , info );
5085
+ reporter = devlink_health_reporter_get_from_cb ( cb );
5015
5086
if (!reporter )
5016
5087
return - EINVAL ;
5017
5088
5018
5089
if (!reporter -> ops -> dump ) {
5019
- devlink_health_reporter_put ( reporter ) ;
5020
- return - EOPNOTSUPP ;
5090
+ err = - EOPNOTSUPP ;
5091
+ goto out ;
5021
5092
}
5022
-
5023
5093
mutex_lock (& reporter -> dump_lock );
5024
- err = devlink_health_do_dump (reporter , NULL );
5025
- if (err )
5026
- goto out ;
5027
-
5028
- err = devlink_fmsg_snd (reporter -> dump_fmsg , info ,
5029
- DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET , 0 );
5094
+ if (!start ) {
5095
+ err = devlink_health_do_dump (reporter , NULL );
5096
+ if (err )
5097
+ goto unlock ;
5098
+ cb -> args [1 ] = reporter -> dump_ts ;
5099
+ }
5100
+ if (!reporter -> dump_fmsg || cb -> args [1 ] != reporter -> dump_ts ) {
5101
+ NL_SET_ERR_MSG_MOD (cb -> extack , "Dump trampled, please retry" );
5102
+ err = - EAGAIN ;
5103
+ goto unlock ;
5104
+ }
5030
5105
5031
- out :
5106
+ err = devlink_fmsg_dumpit (reporter -> dump_fmsg , skb , cb ,
5107
+ DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET );
5108
+ unlock :
5032
5109
mutex_unlock (& reporter -> dump_lock );
5110
+ out :
5033
5111
devlink_health_reporter_put (reporter );
5034
5112
return err ;
5035
5113
}
@@ -5366,7 +5444,7 @@ static const struct genl_ops devlink_nl_ops[] = {
5366
5444
{
5367
5445
.cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET ,
5368
5446
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP ,
5369
- .doit = devlink_nl_cmd_health_reporter_dump_get_doit ,
5447
+ .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit ,
5370
5448
.flags = GENL_ADMIN_PERM ,
5371
5449
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5372
5450
DEVLINK_NL_FLAG_NO_LOCK ,
0 commit comments