aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
authorErik Hugne <erik.hugne@ericsson.com>2012-06-29 00:50:23 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2012-07-13 19:33:28 -0400
commitdc1aed37d17b4fe4f28a74d804c065b877bc7bed (patch)
tree83907b44c25a9a10c84106d17eecfceff00864ce /net/tipc/link.c
parente2dbd601346aeb64b1b387168b217fd5c301644e (diff)
tipc: phase out most of the struct print_buf usage
The tipc_printf is renamed to tipc_snprintf, as the new name describes more what the function actually does. It is also changed to take a buffer and length parameter and return number of characters written to the buffer. All callers of this function that used to pass a print_buf are updated. Final removal of the struct print_buf itself will be done synchronously with the pending removal of the deprecated logging code that also was using it. Functions that build up a response message with a list of ports, nametable contents etc. are changed to return the number of characters written to the output buffer. This information was previously hidden in a field of the print_buf struct, and the number of chars written was fetched with a call to tipc_printbuf_validate. This function is removed since it is no longer referenced nor needed. A generic max size ULTRA_STRING_MAX_LEN is defined, named in keeping with the existing TIPC_TLV_ULTRA_STRING, and the various definitions in port, link and nametable code that largely duplicated this information are removed. This means that amount of link statistics that can be returned is now increased from 2k to 32k. The buffer overflow check is now done just before the reply message is passed over netlink or TIPC to a remote node and the message indicating a truncated buffer is changed to a less dramatic one (less CAPS), placed at the end of the message. Signed-off-by: Erik Hugne <erik.hugne@ericsson.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c130
1 files changed, 66 insertions, 64 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index a9a8b866d30a..1c1e6151875e 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2866,112 +2866,114 @@ static u32 percent(u32 count, u32 total)
2866 */ 2866 */
2867static int tipc_link_stats(const char *name, char *buf, const u32 buf_size) 2867static int tipc_link_stats(const char *name, char *buf, const u32 buf_size)
2868{ 2868{
2869 struct print_buf pb; 2869 struct tipc_link *l;
2870 struct tipc_link *l_ptr; 2870 struct tipc_stats *s;
2871 struct tipc_node *node; 2871 struct tipc_node *node;
2872 char *status; 2872 char *status;
2873 u32 profile_total = 0; 2873 u32 profile_total = 0;
2874 int ret;
2874 2875
2875 if (!strcmp(name, tipc_bclink_name)) 2876 if (!strcmp(name, tipc_bclink_name))
2876 return tipc_bclink_stats(buf, buf_size); 2877 return tipc_bclink_stats(buf, buf_size);
2877 2878
2878 tipc_printbuf_init(&pb, buf, buf_size);
2879
2880 read_lock_bh(&tipc_net_lock); 2879 read_lock_bh(&tipc_net_lock);
2881 l_ptr = link_find_link(name, &node); 2880 l = link_find_link(name, &node);
2882 if (!l_ptr) { 2881 if (!l) {
2883 read_unlock_bh(&tipc_net_lock); 2882 read_unlock_bh(&tipc_net_lock);
2884 return 0; 2883 return 0;
2885 } 2884 }
2886 tipc_node_lock(node); 2885 tipc_node_lock(node);
2886 s = &l->stats;
2887 2887
2888 if (tipc_link_is_active(l_ptr)) 2888 if (tipc_link_is_active(l))
2889 status = "ACTIVE"; 2889 status = "ACTIVE";
2890 else if (tipc_link_is_up(l_ptr)) 2890 else if (tipc_link_is_up(l))
2891 status = "STANDBY"; 2891 status = "STANDBY";
2892 else 2892 else
2893 status = "DEFUNCT"; 2893 status = "DEFUNCT";
2894 tipc_printf(&pb, "Link <%s>\n" 2894
2895 " %s MTU:%u Priority:%u Tolerance:%u ms" 2895 ret = tipc_snprintf(buf, buf_size, "Link <%s>\n"
2896 " Window:%u packets\n", 2896 " %s MTU:%u Priority:%u Tolerance:%u ms"
2897 l_ptr->name, status, l_ptr->max_pkt, 2897 " Window:%u packets\n",
2898 l_ptr->priority, l_ptr->tolerance, l_ptr->queue_limit[0]); 2898 l->name, status, l->max_pkt, l->priority,
2899 tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", 2899 l->tolerance, l->queue_limit[0]);
2900 l_ptr->next_in_no - l_ptr->stats.recv_info, 2900
2901 l_ptr->stats.recv_fragments, 2901 ret += tipc_snprintf(buf + ret, buf_size - ret,
2902 l_ptr->stats.recv_fragmented, 2902 " RX packets:%u fragments:%u/%u bundles:%u/%u\n",
2903 l_ptr->stats.recv_bundles, 2903 l->next_in_no - s->recv_info, s->recv_fragments,
2904 l_ptr->stats.recv_bundled); 2904 s->recv_fragmented, s->recv_bundles,
2905 tipc_printf(&pb, " TX packets:%u fragments:%u/%u bundles:%u/%u\n", 2905 s->recv_bundled);
2906 l_ptr->next_out_no - l_ptr->stats.sent_info, 2906
2907 l_ptr->stats.sent_fragments, 2907 ret += tipc_snprintf(buf + ret, buf_size - ret,
2908 l_ptr->stats.sent_fragmented, 2908 " TX packets:%u fragments:%u/%u bundles:%u/%u\n",
2909 l_ptr->stats.sent_bundles, 2909 l->next_out_no - s->sent_info, s->sent_fragments,
2910 l_ptr->stats.sent_bundled); 2910 s->sent_fragmented, s->sent_bundles,
2911 profile_total = l_ptr->stats.msg_length_counts; 2911 s->sent_bundled);
2912
2913 profile_total = s->msg_length_counts;
2912 if (!profile_total) 2914 if (!profile_total)
2913 profile_total = 1; 2915 profile_total = 1;
2914 tipc_printf(&pb, " TX profile sample:%u packets average:%u octets\n" 2916
2915 " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " 2917 ret += tipc_snprintf(buf + ret, buf_size - ret,
2916 "-16384:%u%% -32768:%u%% -66000:%u%%\n", 2918 " TX profile sample:%u packets average:%u octets\n"
2917 l_ptr->stats.msg_length_counts, 2919 " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% "
2918 l_ptr->stats.msg_lengths_total / profile_total, 2920 "-16384:%u%% -32768:%u%% -66000:%u%%\n",
2919 percent(l_ptr->stats.msg_length_profile[0], profile_total), 2921 s->msg_length_counts,
2920 percent(l_ptr->stats.msg_length_profile[1], profile_total), 2922 s->msg_lengths_total / profile_total,
2921 percent(l_ptr->stats.msg_length_profile[2], profile_total), 2923 percent(s->msg_length_profile[0], profile_total),
2922 percent(l_ptr->stats.msg_length_profile[3], profile_total), 2924 percent(s->msg_length_profile[1], profile_total),
2923 percent(l_ptr->stats.msg_length_profile[4], profile_total), 2925 percent(s->msg_length_profile[2], profile_total),
2924 percent(l_ptr->stats.msg_length_profile[5], profile_total), 2926 percent(s->msg_length_profile[3], profile_total),
2925 percent(l_ptr->stats.msg_length_profile[6], profile_total)); 2927 percent(s->msg_length_profile[4], profile_total),
2926 tipc_printf(&pb, " RX states:%u probes:%u naks:%u defs:%u dups:%u\n", 2928 percent(s->msg_length_profile[5], profile_total),
2927 l_ptr->stats.recv_states, 2929 percent(s->msg_length_profile[6], profile_total));
2928 l_ptr->stats.recv_probes, 2930
2929 l_ptr->stats.recv_nacks, 2931 ret += tipc_snprintf(buf + ret, buf_size - ret,
2930 l_ptr->stats.deferred_recv, 2932 " RX states:%u probes:%u naks:%u defs:%u"
2931 l_ptr->stats.duplicates); 2933 " dups:%u\n", s->recv_states, s->recv_probes,
2932 tipc_printf(&pb, " TX states:%u probes:%u naks:%u acks:%u dups:%u\n", 2934 s->recv_nacks, s->deferred_recv, s->duplicates);
2933 l_ptr->stats.sent_states, 2935
2934 l_ptr->stats.sent_probes, 2936 ret += tipc_snprintf(buf + ret, buf_size - ret,
2935 l_ptr->stats.sent_nacks, 2937 " TX states:%u probes:%u naks:%u acks:%u"
2936 l_ptr->stats.sent_acks, 2938 " dups:%u\n", s->sent_states, s->sent_probes,
2937 l_ptr->stats.retransmitted); 2939 s->sent_nacks, s->sent_acks, s->retransmitted);
2938 tipc_printf(&pb, " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", 2940
2939 l_ptr->stats.bearer_congs, 2941 ret += tipc_snprintf(buf + ret, buf_size - ret,
2940 l_ptr->stats.link_congs, 2942 " Congestion bearer:%u link:%u Send queue"
2941 l_ptr->stats.max_queue_sz, 2943 " max:%u avg:%u\n", s->bearer_congs, s->link_congs,
2942 l_ptr->stats.queue_sz_counts 2944 s->max_queue_sz, s->queue_sz_counts ?
2943 ? (l_ptr->stats.accu_queue_sz / l_ptr->stats.queue_sz_counts) 2945 (s->accu_queue_sz / s->queue_sz_counts) : 0);
2944 : 0);
2945 2946
2946 tipc_node_unlock(node); 2947 tipc_node_unlock(node);
2947 read_unlock_bh(&tipc_net_lock); 2948 read_unlock_bh(&tipc_net_lock);
2948 return tipc_printbuf_validate(&pb); 2949 return ret;
2949} 2950}
2950 2951
2951#define MAX_LINK_STATS_INFO 2000
2952
2953struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space) 2952struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space)
2954{ 2953{
2955 struct sk_buff *buf; 2954 struct sk_buff *buf;
2956 struct tlv_desc *rep_tlv; 2955 struct tlv_desc *rep_tlv;
2957 int str_len; 2956 int str_len;
2957 int pb_len;
2958 char *pb;
2958 2959
2959 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) 2960 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
2960 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 2961 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
2961 2962
2962 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_LINK_STATS_INFO)); 2963 buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
2963 if (!buf) 2964 if (!buf)
2964 return NULL; 2965 return NULL;
2965 2966
2966 rep_tlv = (struct tlv_desc *)buf->data; 2967 rep_tlv = (struct tlv_desc *)buf->data;
2967 2968 pb = TLV_DATA(rep_tlv);
2969 pb_len = ULTRA_STRING_MAX_LEN;
2968 str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area), 2970 str_len = tipc_link_stats((char *)TLV_DATA(req_tlv_area),
2969 (char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO); 2971 pb, pb_len);
2970 if (!str_len) { 2972 if (!str_len) {
2971 kfree_skb(buf); 2973 kfree_skb(buf);
2972 return tipc_cfg_reply_error_string("link not found"); 2974 return tipc_cfg_reply_error_string("link not found");
2973 } 2975 }
2974 2976 str_len += 1; /* for "\0" */
2975 skb_put(buf, TLV_SPACE(str_len)); 2977 skb_put(buf, TLV_SPACE(str_len));
2976 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); 2978 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
2977 2979