Changeset 1667

Show
Ignore:
Timestamp:
07/04/06 12:23:35 (3 years ago)
Author:
kelmo
Message:

This patch adds support for reporting statistics on the operation
of the rate control modules via /proc. Currently only the sample rate
module actually provides any statistics.

The statistics reported for the sample module were present in the
madwifi-old module but did not seem to make it into madwifi-ng. I
have made some minor changes to how these statistics are reported:

  1. Statistics are now reported via /proc entries instead of using
    sysctls. Sysctls are intended as a method for the user to
    configure parameters of the module and should not be misued for
    reporting statistics.
  2. A new symbol ath_rate_dynamic_proc_register is exported from each
    rate control module. This function is called by the driver just
    after a new VAP has been created to allow the rate control module
    to register the appropriate proc entries. As described in ticket
    #728, all further management of these entries will be handled by
    the VAP, which will call the functions supplied by the rate
    control module to retrieve data when necessary.

The information that this patch adds back into the driver is very
useful and is referred to in the documentation which currently causes
some confusion when the statistics is not found. The documentation
should be updated to reflect that the statistics will now live at
/proc/net/madwifi/<ifname>/ratestats_{250,1600,3000}.

Closes #729

Signed-off-by: Matt Brown <matt@mattb.net.nz>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ath/if_ath.c

    r1659 r1667  
    10561056        vap->iv_comp_set = ath_comp_set; 
    10571057#endif 
     1058 
     1059        /* Let rate control register proc entries for the vap */ 
     1060        ath_rate_dynamic_proc_register(vap); 
    10581061 
    10591062        /* 
  • trunk/ath/if_athrate.h

    r1456 r1667  
    8787void ath_rate_detach(struct ath_ratectrl *); 
    8888 
     89#ifdef CONFIG_SYSCTL 
     90/* 
     91 * Allow rate control module to register proc entries with a vap  
     92 * Deallocation of the entries will be dealt with when the vap is destroyed 
     93 */ 
     94void ath_rate_dynamic_proc_register(struct ieee80211vap *vap); 
     95#endif /* CONFIG_SYSCTL */ 
    8996 
    9097/* 
  • trunk/ath_rate/amrr/amrr.c

    r1590 r1667  
    482482EXPORT_SYMBOL(ath_rate_detach); 
    483483 
     484#ifdef CONFIG_SYSCTL 
     485void 
     486ath_rate_dynamic_proc_register(struct ieee80211vap *vap) 
     487{                
     488        /* Amrr rate module reports no statistics */ 
     489} 
     490EXPORT_SYMBOL(ath_rate_dynamic_proc_register); 
     491#endif /* CONFIG_SYSCTL */ 
     492 
    484493static int minrateinterval = 500;       /* 500ms */ 
    485494static int maxint = 0x7fffffff;         /* 32-bit big */ 
  • trunk/ath_rate/onoe/onoe.c

    r1590 r1667  
    430430EXPORT_SYMBOL(ath_rate_detach); 
    431431 
     432#ifdef CONFIG_SYSCTL 
     433void 
     434ath_rate_dynamic_proc_register(struct ieee80211vap *vap) 
     435{                
     436        /* Onoe rate module reports no statistics */ 
     437} 
     438EXPORT_SYMBOL(ath_rate_dynamic_proc_register); 
     439#endif /* CONFIG_SYSCTL */ 
     440 
    432441static int minrateinterval = 500;       /* 500ms */ 
    433442static int maxpercent = 100;            /* 100% */ 
  • trunk/ath_rate/sample/sample.c

    r1590 r1667  
    5151#include <linux/delay.h> 
    5252#include <linux/cache.h> 
    53 #include <linux/sysctl.h> 
    5453#include <linux/proc_fs.h> 
    5554#include <linux/if_arp.h> 
     55#include <linux/vmalloc.h> 
    5656 
    5757#include <asm/uaccess.h> 
     
    937937EXPORT_SYMBOL(ath_rate_detach); 
    938938 
     939#ifdef CONFIG_SYSCTL 
     940static int 
     941proc_read_nodes(struct ieee80211vap *vap, const int size, char *buf, int space) 
     942{ 
     943        char *p = buf; 
     944        struct ieee80211_node *ni; 
     945        struct ath_node *an; 
     946        struct sample_node *sn; 
     947        struct ieee80211_node_table *nt =  
     948                (struct ieee80211_node_table *) &vap->iv_ic->ic_sta; 
     949        int x = 0; 
     950        int size_bin = 0; 
     951 
     952        TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { 
     953                /* Assume each node needs 500 bytes */ 
     954                if (buf + space < p + 500) 
     955                        break; 
     956                an = ATH_NODE(ni); 
     957                sn = ATH_NODE_SAMPLE(an); 
     958                /* Skip ourself */ 
     959                if (memcmp(vap->iv_myaddr, ni->ni_macaddr,  
     960                                        IEEE80211_ADDR_LEN)==0) { 
     961                        continue; 
     962                } 
     963 
     964                size_bin = size_to_bin(size); 
     965                p += sprintf(p, "%s\n", ether_sprintf(ni->ni_macaddr)); 
     966                p += sprintf(p,  
     967                                "rate\ttt\tperfect\tfailed\tpkts\tavg_tries\tlast_tx\n"); 
     968                for (x = 0; x < sn->num_rates; x++) { 
     969                        int a = 1; 
     970                        int t = 1; 
     971 
     972                        p += sprintf(p, "%s",  
     973                                        (x == sn->current_rate[size_bin]) ? "*" : " "); 
     974 
     975                        p += sprintf(p, "%3d%s", 
     976                                        sn->rates[x].rate/2, 
     977                                        (sn->rates[x].rate & 0x1) != 0 ? ".5" : "  "); 
     978 
     979                        p += sprintf(p, "\t%4d\t%4d\t%2d\t%3d", 
     980                                        sn->stats[size_bin][x].average_tx_time, 
     981                                        sn->stats[size_bin][x].perfect_tx_time, 
     982                                        sn->stats[size_bin][x].successive_failures, 
     983                                        sn->stats[size_bin][x].total_packets); 
     984 
     985                        if (sn->stats[size_bin][x].total_packets) { 
     986                                a = sn->stats[size_bin][x].total_packets; 
     987                                t = sn->stats[size_bin][x].tries; 
     988                        } 
     989                        p += sprintf(p, "\t%d.%02d\t", t/a, (t*100/a) % 100); 
     990                        if (sn->stats[size_bin][x].last_tx) { 
     991                                unsigned d = jiffies -  
     992                                        sn->stats[size_bin][x].last_tx; 
     993                                p += sprintf(p, "%d.%02d", d / HZ, d % HZ); 
     994                        } else { 
     995                                p += sprintf(p, "-"); 
     996                        } 
     997                        p += sprintf(p, "\n"); 
     998                } 
     999                printk("\n"); 
     1000        } 
     1001 
     1002        return (p - buf); 
     1003} 
     1004 
     1005int 
     1006proc_ratesample_open(struct inode *inode, struct file *file) 
     1007{ 
     1008        struct proc_ieee80211_priv *pv = NULL; 
     1009        struct proc_dir_entry *dp = PDE(inode); 
     1010        struct ieee80211vap *vap = dp->data; 
     1011        int size = 0; 
     1012 
     1013        if (!(file->private_data = kmalloc(sizeof(struct proc_ieee80211_priv), 
     1014                                        GFP_KERNEL))) 
     1015                return -ENOMEM; 
     1016 
     1017        /* intially allocate both read and write buffers */ 
     1018        pv = (struct proc_ieee80211_priv *) file->private_data; 
     1019        memset(pv, 0, sizeof(struct proc_ieee80211_priv)); 
     1020        pv->rbuf = vmalloc(MAX_PROC_IEEE80211_SIZE); 
     1021        if (!pv->rbuf) { 
     1022                kfree(pv); 
     1023                return -ENOMEM; 
     1024        } 
     1025        pv->wbuf = vmalloc(MAX_PROC_IEEE80211_SIZE); 
     1026        if (!pv->wbuf) { 
     1027                vfree(pv->rbuf); 
     1028                kfree(pv); 
     1029                return -ENOMEM; 
     1030        } 
     1031        memset(pv->wbuf, 0, MAX_PROC_IEEE80211_SIZE); 
     1032        memset(pv->rbuf, 0, MAX_PROC_IEEE80211_SIZE); 
     1033        pv->max_wlen = MAX_PROC_IEEE80211_SIZE; 
     1034        pv->max_rlen = MAX_PROC_IEEE80211_SIZE; 
     1035 
     1036        /* Determine what size packets to get stats for based on proc filename */ 
     1037        size = (int)simple_strtol(dp->name + 10, NULL, 0); 
     1038 
     1039        /* now read the data into the buffer */ 
     1040        pv->rlen = proc_read_nodes(vap, size, pv->rbuf, MAX_PROC_IEEE80211_SIZE); 
     1041        return 0; 
     1042} 
     1043 
     1044static struct file_operations proc_ratesample_ops = { 
     1045        .read = NULL, 
     1046        .write = NULL, 
     1047        .open = proc_ratesample_open, 
     1048        .release = NULL, 
     1049}; 
     1050 
     1051void 
     1052ath_rate_dynamic_proc_register(struct ieee80211vap *vap) 
     1053{                
     1054        /* Create proc entries for the rate control algorithm */ 
     1055        ieee80211_proc_vcreate(vap, &proc_ratesample_ops, "ratestats_250"); 
     1056        ieee80211_proc_vcreate(vap, &proc_ratesample_ops, "ratestats_1600"); 
     1057        ieee80211_proc_vcreate(vap, &proc_ratesample_ops, "ratestats_3000");     
     1058} 
     1059EXPORT_SYMBOL(ath_rate_dynamic_proc_register); 
     1060#endif /* CONFIG_SYSCTL */ 
     1061 
    9391062MODULE_AUTHOR("John Bicket"); 
    9401063MODULE_DESCRIPTION("SampleRate bit-rate selection algorithm for Atheros devices"); 
  • trunk/ath_rate/sample/sample.h

    r1441 r1667  
    4848        int ath_smoothing_rate;                 /* ewma percentage (out of 100) */ 
    4949        int ath_sample_rate;            /* send a different bit-rate 1/X packets */ 
    50  
    51 #ifdef CONFIG_SYSCTL 
    52         struct ctl_table_header *sysctl_header; 
    53         struct ctl_table *sysctls; 
    54 #endif 
    55  
    5650}; 
    5751#define ATH_SOFTC_SAMPLE(sc)    ((struct sample_softc *)sc->sc_rc)