aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/devlink.c
diff options
context:
space:
mode:
authorJiri Pirko <jiri@mellanox.com>2016-04-14 12:19:14 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-14 16:22:03 -0400
commitdf38dafd255954ee7012785c62e615f595d5cb3c (patch)
tree493e781aa7b44ba00a23ea6162b04c93918d0732 /net/core/devlink.c
parentbf7974710a40aaeb69dee7f62d91048bdaf79c76 (diff)
devlink: implement shared buffer occupancy monitoring interface
User needs to monitor shared buffer occupancy. For that, he issues a snapshot command in order to instruct hardware to catch current and maximal occupancy values, and clear command in order to clear the historical maximal values. Also port-pool and tc-pool-bind command response messages are extended to carry occupancy values. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/devlink.c')
-rw-r--r--net/core/devlink.c98
1 files changed, 92 insertions, 6 deletions
diff --git a/net/core/devlink.c b/net/core/devlink.c
index aa0b9e1542e7..933e8d4d3968 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -280,6 +280,10 @@ devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
280#define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0) 280#define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
281#define DEVLINK_NL_FLAG_NEED_PORT BIT(1) 281#define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
282#define DEVLINK_NL_FLAG_NEED_SB BIT(2) 282#define DEVLINK_NL_FLAG_NEED_SB BIT(2)
283#define DEVLINK_NL_FLAG_LOCK_PORTS BIT(3)
284 /* port is not needed but we need to ensure they don't
285 * change in the middle of command
286 */
283 287
284static int devlink_nl_pre_doit(const struct genl_ops *ops, 288static int devlink_nl_pre_doit(const struct genl_ops *ops,
285 struct sk_buff *skb, struct genl_info *info) 289 struct sk_buff *skb, struct genl_info *info)
@@ -306,6 +310,9 @@ static int devlink_nl_pre_doit(const struct genl_ops *ops,
306 } 310 }
307 info->user_ptr[0] = devlink_port; 311 info->user_ptr[0] = devlink_port;
308 } 312 }
313 if (ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS) {
314 mutex_lock(&devlink_port_mutex);
315 }
309 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) { 316 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
310 struct devlink_sb *devlink_sb; 317 struct devlink_sb *devlink_sb;
311 318
@@ -324,7 +331,8 @@ static int devlink_nl_pre_doit(const struct genl_ops *ops,
324static void devlink_nl_post_doit(const struct genl_ops *ops, 331static void devlink_nl_post_doit(const struct genl_ops *ops,
325 struct sk_buff *skb, struct genl_info *info) 332 struct sk_buff *skb, struct genl_info *info)
326{ 333{
327 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) 334 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT ||
335 ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS)
328 mutex_unlock(&devlink_port_mutex); 336 mutex_unlock(&devlink_port_mutex);
329 mutex_unlock(&devlink_mutex); 337 mutex_unlock(&devlink_mutex);
330} 338}
@@ -942,12 +950,13 @@ static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
942 enum devlink_command cmd, 950 enum devlink_command cmd,
943 u32 portid, u32 seq, int flags) 951 u32 portid, u32 seq, int flags)
944{ 952{
953 const struct devlink_ops *ops = devlink->ops;
945 u32 threshold; 954 u32 threshold;
946 void *hdr; 955 void *hdr;
947 int err; 956 int err;
948 957
949 err = devlink->ops->sb_port_pool_get(devlink_port, devlink_sb->index, 958 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
950 pool_index, &threshold); 959 pool_index, &threshold);
951 if (err) 960 if (err)
952 return err; 961 return err;
953 962
@@ -966,6 +975,22 @@ static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
966 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) 975 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
967 goto nla_put_failure; 976 goto nla_put_failure;
968 977
978 if (ops->sb_occ_port_pool_get) {
979 u32 cur;
980 u32 max;
981
982 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
983 pool_index, &cur, &max);
984 if (err && err != -EOPNOTSUPP)
985 return err;
986 if (!err) {
987 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
988 goto nla_put_failure;
989 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
990 goto nla_put_failure;
991 }
992 }
993
969 genlmsg_end(msg, hdr); 994 genlmsg_end(msg, hdr);
970 return 0; 995 return 0;
971 996
@@ -1114,14 +1139,15 @@ devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1114 enum devlink_command cmd, 1139 enum devlink_command cmd,
1115 u32 portid, u32 seq, int flags) 1140 u32 portid, u32 seq, int flags)
1116{ 1141{
1142 const struct devlink_ops *ops = devlink->ops;
1117 u16 pool_index; 1143 u16 pool_index;
1118 u32 threshold; 1144 u32 threshold;
1119 void *hdr; 1145 void *hdr;
1120 int err; 1146 int err;
1121 1147
1122 err = devlink->ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index, 1148 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1123 tc_index, pool_type, 1149 tc_index, pool_type,
1124 &pool_index, &threshold); 1150 &pool_index, &threshold);
1125 if (err) 1151 if (err)
1126 return err; 1152 return err;
1127 1153
@@ -1144,6 +1170,24 @@ devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1144 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold)) 1170 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1145 goto nla_put_failure; 1171 goto nla_put_failure;
1146 1172
1173 if (ops->sb_occ_tc_port_bind_get) {
1174 u32 cur;
1175 u32 max;
1176
1177 err = ops->sb_occ_tc_port_bind_get(devlink_port,
1178 devlink_sb->index,
1179 tc_index, pool_type,
1180 &cur, &max);
1181 if (err && err != -EOPNOTSUPP)
1182 return err;
1183 if (!err) {
1184 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1185 goto nla_put_failure;
1186 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1187 goto nla_put_failure;
1188 }
1189 }
1190
1147 genlmsg_end(msg, hdr); 1191 genlmsg_end(msg, hdr);
1148 return 0; 1192 return 0;
1149 1193
@@ -1326,6 +1370,30 @@ static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1326 pool_index, threshold); 1370 pool_index, threshold);
1327} 1371}
1328 1372
1373static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1374 struct genl_info *info)
1375{
1376 struct devlink *devlink = info->user_ptr[0];
1377 struct devlink_sb *devlink_sb = info->user_ptr[1];
1378 const struct devlink_ops *ops = devlink->ops;
1379
1380 if (ops && ops->sb_occ_snapshot)
1381 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1382 return -EOPNOTSUPP;
1383}
1384
1385static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1386 struct genl_info *info)
1387{
1388 struct devlink *devlink = info->user_ptr[0];
1389 struct devlink_sb *devlink_sb = info->user_ptr[1];
1390 const struct devlink_ops *ops = devlink->ops;
1391
1392 if (ops && ops->sb_occ_max_clear)
1393 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1394 return -EOPNOTSUPP;
1395}
1396
1329static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { 1397static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
1330 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, 1398 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
1331 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, 1399 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
@@ -1439,6 +1507,24 @@ static const struct genl_ops devlink_nl_ops[] = {
1439 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT | 1507 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1440 DEVLINK_NL_FLAG_NEED_SB, 1508 DEVLINK_NL_FLAG_NEED_SB,
1441 }, 1509 },
1510 {
1511 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
1512 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
1513 .policy = devlink_nl_policy,
1514 .flags = GENL_ADMIN_PERM,
1515 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1516 DEVLINK_NL_FLAG_NEED_SB |
1517 DEVLINK_NL_FLAG_LOCK_PORTS,
1518 },
1519 {
1520 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
1521 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
1522 .policy = devlink_nl_policy,
1523 .flags = GENL_ADMIN_PERM,
1524 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1525 DEVLINK_NL_FLAG_NEED_SB |
1526 DEVLINK_NL_FLAG_LOCK_PORTS,
1527 },
1442}; 1528};
1443 1529
1444/** 1530/**