2005-04-17 02:20:36 +04:00
/*
* net / core / gen_stats . c
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*
* Authors : Thomas Graf < tgraf @ suug . ch >
* Jamal Hadi Salim
* Alexey Kuznetsov , < kuznet @ ms2 . inr . ac . ru >
*
* See Documentation / networking / gen_stats . txt
*/
# include <linux/types.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/interrupt.h>
# include <linux/socket.h>
# include <linux/rtnetlink.h>
# include <linux/gen_stats.h>
2008-01-23 09:11:17 +03:00
# include <net/netlink.h>
2005-04-17 02:20:36 +04:00
# include <net/gen_stats.h>
static inline int
gnet_stats_copy ( struct gnet_dump * d , int type , void * buf , int size )
{
2012-04-02 04:47:35 +04:00
if ( nla_put ( d - > skb , type , size , buf ) )
goto nla_put_failure ;
2005-04-17 02:20:36 +04:00
return 0 ;
2008-01-23 09:11:17 +03:00
nla_put_failure :
2005-04-17 02:20:36 +04:00
spin_unlock_bh ( d - > lock ) ;
return - 1 ;
}
/**
* gnet_stats_start_copy_compat - start dumping procedure in compatibility mode
* @ skb : socket buffer to put statistics TLVs into
* @ type : TLV type for top level statistic TLV
* @ tc_stats_type : TLV type for backward compatibility struct tc_stats TLV
* @ xstats_type : TLV type for backward compatibility xstats TLV
* @ lock : statistics lock
* @ d : dumping handle
*
* Initializes the dumping handle , grabs the statistic lock and appends
* an empty TLV header to the socket buffer for use a container for all
* other statistic TLVS .
*
* The dumping handle is marked to be in backward compatibility mode telling
* all gnet_stats_copy_XXX ( ) functions to fill a local copy of struct tc_stats .
*
* Returns 0 on success or - 1 if the room in the socket buffer was not sufficient .
*/
int
gnet_stats_start_copy_compat ( struct sk_buff * skb , int type , int tc_stats_type ,
int xstats_type , spinlock_t * lock , struct gnet_dump * d )
2008-01-02 08:58:02 +03:00
__acquires ( lock )
2005-04-17 02:20:36 +04:00
{
memset ( d , 0 , sizeof ( * d ) ) ;
2007-02-09 17:24:36 +03:00
2005-04-17 02:20:36 +04:00
spin_lock_bh ( lock ) ;
d - > lock = lock ;
if ( type )
2008-01-23 09:11:17 +03:00
d - > tail = ( struct nlattr * ) skb_tail_pointer ( skb ) ;
2005-04-17 02:20:36 +04:00
d - > skb = skb ;
d - > compat_tc_stats = tc_stats_type ;
d - > compat_xstats = xstats_type ;
if ( d - > tail )
return gnet_stats_copy ( d , type , NULL , 0 ) ;
return 0 ;
}
2010-07-10 01:22:04 +04:00
EXPORT_SYMBOL ( gnet_stats_start_copy_compat ) ;
2005-04-17 02:20:36 +04:00
/**
* gnet_stats_start_copy_compat - start dumping procedure in compatibility mode
* @ skb : socket buffer to put statistics TLVs into
* @ type : TLV type for top level statistic TLV
* @ lock : statistics lock
* @ d : dumping handle
*
* Initializes the dumping handle , grabs the statistic lock and appends
* an empty TLV header to the socket buffer for use a container for all
* other statistic TLVS .
*
* Returns 0 on success or - 1 if the room in the socket buffer was not sufficient .
*/
int
gnet_stats_start_copy ( struct sk_buff * skb , int type , spinlock_t * lock ,
struct gnet_dump * d )
{
return gnet_stats_start_copy_compat ( skb , type , 0 , 0 , lock , d ) ;
}
2010-07-10 01:22:04 +04:00
EXPORT_SYMBOL ( gnet_stats_start_copy ) ;
2005-04-17 02:20:36 +04:00
/**
* gnet_stats_copy_basic - copy basic statistics into statistic TLV
* @ d : dumping handle
* @ b : basic statistics
*
* Appends the basic statistics to the top level TLV created by
* gnet_stats_start_copy ( ) .
*
* Returns 0 on success or - 1 with the statistic lock released
* if the room in the socket buffer was not sufficient .
*/
int
2009-08-16 13:36:49 +04:00
gnet_stats_copy_basic ( struct gnet_dump * d , struct gnet_stats_basic_packed * b )
2005-04-17 02:20:36 +04:00
{
if ( d - > compat_tc_stats ) {
d - > tc_stats . bytes = b - > bytes ;
d - > tc_stats . packets = b - > packets ;
}
2009-08-16 13:36:49 +04:00
if ( d - > tail ) {
struct gnet_stats_basic sb ;
2005-04-17 02:20:36 +04:00
2009-08-16 13:36:49 +04:00
memset ( & sb , 0 , sizeof ( sb ) ) ;
sb . bytes = b - > bytes ;
sb . packets = b - > packets ;
return gnet_stats_copy ( d , TCA_STATS_BASIC , & sb , sizeof ( sb ) ) ;
}
2005-04-17 02:20:36 +04:00
return 0 ;
}
2010-07-10 01:22:04 +04:00
EXPORT_SYMBOL ( gnet_stats_copy_basic ) ;
2005-04-17 02:20:36 +04:00
/**
* gnet_stats_copy_rate_est - copy rate estimator statistics into statistics TLV
* @ d : dumping handle
pkt_sched: gen_estimator: Dont report fake rate estimators
Jarek Poplawski a écrit :
>
>
> Hmm... So you made me to do some "real" work here, and guess what?:
> there is one serious checkpatch warning! ;-) Plus, this new parameter
> should be added to the function description. Otherwise:
> Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
>
> Thanks,
> Jarek P.
>
> PS: I guess full "Don't" would show we really mean it...
Okay :) Here is the last round, before the night !
Thanks again
[RFC] pkt_sched: gen_estimator: Don't report fake rate estimators
We currently send TCA_STATS_RATE_EST elements to netlink users, even if no estimator
is running.
# tc -s -d qdisc
qdisc pfifo_fast 0: dev eth0 root bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 112833764978 bytes 1495081739 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
User has no way to tell if the "rate 0bit 0pps" is a real estimation, or a fake
one (because no estimator is active)
After this patch, tc command output is :
$ tc -s -d qdisc
qdisc pfifo_fast 0: dev eth0 root bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 561075 bytes 1196 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
We add a parameter to gnet_stats_copy_rate_est() function so that
it can use gen_estimator_active(bstats, r), as suggested by Jarek.
This parameter can be NULL if check is not necessary, (htb for
example has a mandatory rate estimator)
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2009-10-02 14:32:18 +04:00
* @ b : basic statistics
2005-04-17 02:20:36 +04:00
* @ r : rate estimator statistics
*
* Appends the rate estimator statistics to the top level TLV created by
* gnet_stats_start_copy ( ) .
*
* Returns 0 on success or - 1 with the statistic lock released
* if the room in the socket buffer was not sufficient .
*/
int
pkt_sched: gen_estimator: Dont report fake rate estimators
Jarek Poplawski a écrit :
>
>
> Hmm... So you made me to do some "real" work here, and guess what?:
> there is one serious checkpatch warning! ;-) Plus, this new parameter
> should be added to the function description. Otherwise:
> Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
>
> Thanks,
> Jarek P.
>
> PS: I guess full "Don't" would show we really mean it...
Okay :) Here is the last round, before the night !
Thanks again
[RFC] pkt_sched: gen_estimator: Don't report fake rate estimators
We currently send TCA_STATS_RATE_EST elements to netlink users, even if no estimator
is running.
# tc -s -d qdisc
qdisc pfifo_fast 0: dev eth0 root bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 112833764978 bytes 1495081739 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
User has no way to tell if the "rate 0bit 0pps" is a real estimation, or a fake
one (because no estimator is active)
After this patch, tc command output is :
$ tc -s -d qdisc
qdisc pfifo_fast 0: dev eth0 root bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 561075 bytes 1196 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
We add a parameter to gnet_stats_copy_rate_est() function so that
it can use gen_estimator_active(bstats, r), as suggested by Jarek.
This parameter can be NULL if check is not necessary, (htb for
example has a mandatory rate estimator)
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2009-10-02 14:32:18 +04:00
gnet_stats_copy_rate_est ( struct gnet_dump * d ,
const struct gnet_stats_basic_packed * b ,
struct gnet_stats_rate_est * r )
2005-04-17 02:20:36 +04:00
{
pkt_sched: gen_estimator: Dont report fake rate estimators
Jarek Poplawski a écrit :
>
>
> Hmm... So you made me to do some "real" work here, and guess what?:
> there is one serious checkpatch warning! ;-) Plus, this new parameter
> should be added to the function description. Otherwise:
> Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
>
> Thanks,
> Jarek P.
>
> PS: I guess full "Don't" would show we really mean it...
Okay :) Here is the last round, before the night !
Thanks again
[RFC] pkt_sched: gen_estimator: Don't report fake rate estimators
We currently send TCA_STATS_RATE_EST elements to netlink users, even if no estimator
is running.
# tc -s -d qdisc
qdisc pfifo_fast 0: dev eth0 root bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 112833764978 bytes 1495081739 pkt (dropped 0, overlimits 0 requeues 0)
rate 0bit 0pps backlog 0b 0p requeues 0
User has no way to tell if the "rate 0bit 0pps" is a real estimation, or a fake
one (because no estimator is active)
After this patch, tc command output is :
$ tc -s -d qdisc
qdisc pfifo_fast 0: dev eth0 root bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 561075 bytes 1196 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
We add a parameter to gnet_stats_copy_rate_est() function so that
it can use gen_estimator_active(bstats, r), as suggested by Jarek.
This parameter can be NULL if check is not necessary, (htb for
example has a mandatory rate estimator)
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2009-10-02 14:32:18 +04:00
if ( b & & ! gen_estimator_active ( b , r ) )
return 0 ;
2005-04-17 02:20:36 +04:00
if ( d - > compat_tc_stats ) {
d - > tc_stats . bps = r - > bps ;
d - > tc_stats . pps = r - > pps ;
}
if ( d - > tail )
return gnet_stats_copy ( d , TCA_STATS_RATE_EST , r , sizeof ( * r ) ) ;
return 0 ;
}
2010-07-10 01:22:04 +04:00
EXPORT_SYMBOL ( gnet_stats_copy_rate_est ) ;
2005-04-17 02:20:36 +04:00
/**
* gnet_stats_copy_queue - copy queue statistics into statistics TLV
* @ d : dumping handle
* @ q : queue statistics
*
* Appends the queue statistics to the top level TLV created by
* gnet_stats_start_copy ( ) .
*
* Returns 0 on success or - 1 with the statistic lock released
* if the room in the socket buffer was not sufficient .
*/
int
gnet_stats_copy_queue ( struct gnet_dump * d , struct gnet_stats_queue * q )
{
if ( d - > compat_tc_stats ) {
d - > tc_stats . drops = q - > drops ;
d - > tc_stats . qlen = q - > qlen ;
d - > tc_stats . backlog = q - > backlog ;
d - > tc_stats . overlimits = q - > overlimits ;
}
if ( d - > tail )
return gnet_stats_copy ( d , TCA_STATS_QUEUE , q , sizeof ( * q ) ) ;
return 0 ;
}
2010-07-10 01:22:04 +04:00
EXPORT_SYMBOL ( gnet_stats_copy_queue ) ;
2005-04-17 02:20:36 +04:00
/**
* gnet_stats_copy_app - copy application specific statistics into statistics TLV
* @ d : dumping handle
* @ st : application specific statistics data
* @ len : length of data
*
* Appends the application sepecific statistics to the top level TLV created by
* gnet_stats_start_copy ( ) and remembers the data for XSTATS if the dumping
* handle is in backward compatibility mode .
*
* Returns 0 on success or - 1 with the statistic lock released
* if the room in the socket buffer was not sufficient .
*/
int
gnet_stats_copy_app ( struct gnet_dump * d , void * st , int len )
{
if ( d - > compat_xstats ) {
d - > xstats = st ;
d - > xstats_len = len ;
}
if ( d - > tail )
return gnet_stats_copy ( d , TCA_STATS_APP , st , len ) ;
return 0 ;
}
2010-07-10 01:22:04 +04:00
EXPORT_SYMBOL ( gnet_stats_copy_app ) ;
2005-04-17 02:20:36 +04:00
/**
* gnet_stats_finish_copy - finish dumping procedure
* @ d : dumping handle
*
* Corrects the length of the top level TLV to include all TLVs added
* by gnet_stats_copy_XXX ( ) calls . Adds the backward compatibility TLVs
* if gnet_stats_start_copy_compat ( ) was used and releases the statistics
* lock .
*
* Returns 0 on success or - 1 with the statistic lock released
* if the room in the socket buffer was not sufficient .
*/
int
gnet_stats_finish_copy ( struct gnet_dump * d )
{
if ( d - > tail )
2008-01-23 09:11:17 +03:00
d - > tail - > nla_len = skb_tail_pointer ( d - > skb ) - ( u8 * ) d - > tail ;
2005-04-17 02:20:36 +04:00
if ( d - > compat_tc_stats )
if ( gnet_stats_copy ( d , d - > compat_tc_stats , & d - > tc_stats ,
sizeof ( d - > tc_stats ) ) < 0 )
return - 1 ;
if ( d - > compat_xstats & & d - > xstats ) {
if ( gnet_stats_copy ( d , d - > compat_xstats , d - > xstats ,
d - > xstats_len ) < 0 )
return - 1 ;
}
spin_unlock_bh ( d - > lock ) ;
return 0 ;
}
EXPORT_SYMBOL ( gnet_stats_finish_copy ) ;