summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2008-07-15 11:07:33 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2008-07-15 11:07:33 -0300
commit824f72f88ead0a623ec844b65e58defb3f4d1231 (patch)
treecb7a7981561c6b66295df780839af33c9b33c503
parent0da7f23709e41c14dded246781dafdf663a24f36 (diff)
downloadpython-ethtool-824f72f88ead0a623ec844b65e58defb3f4d1231.tar.gz
python-ethtool-824f72f88ead0a623ec844b65e58defb3f4d1231.tar.xz
python-ethtool-824f72f88ead0a623ec844b65e58defb3f4d1231.zip
ethtool: binding for ETHTOOL_SCOALESCE
And support in pethtool (aka ethtool-cmd.py) for setting all the coalesce parameters, providing, as usual, an interface that mimics the one provided by the ethtool command. This cset also introduces struct_desc_from_dict, that will help with other dict based python bindings, not just in python-ethtool. Please let me know if I'm reinventing the wheel, i.e. if there are other Python dict to C struct facilities out there (I bet there is, but heck, this one was easy enough to implement and doesn't requires external support to get this done 8)). Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rwxr-xr-xethtool-cmd.py102
-rw-r--r--python-ethtool/ethtool.c62
2 files changed, 154 insertions, 10 deletions
diff --git a/ethtool-cmd.py b/ethtool-cmd.py
index f931efa..47ee6ac 100755
--- a/ethtool-cmd.py
+++ b/ethtool-cmd.py
@@ -18,6 +18,29 @@ def usage():
print '''Usage: ethtool [OPTIONS] [<interface>]
-h|--help Give this help list
-c|--show-coalesce Show coalesce options
+ -C|--coalesce Set coalesce options
+ [adaptive-rx on|off]
+ [adaptive-tx on|off]
+ [rx-usecs N]
+ [rx-frames N]
+ [rx-usecs-irq N]
+ [rx-frames-irq N]
+ [tx-usecs N]
+ [tx-frames N]
+ [tx-usecs-irq N]
+ [tx-frames-irq N]
+ [stats-block-usecs N]
+ [pkt-rate-low N]
+ [rx-usecs-low N]
+ [rx-frames-low N]
+ [tx-usecs-low N]
+ [tx-frames-low N]
+ [pkt-rate-high N]
+ [rx-usecs-high N]
+ [rx-frames-high N]
+ [tx-usecs-high N]
+ [tx-frames-high N]
+ [sample-interval N]
-i|--driver Show driver information
-k|--show-offload Get protocol offload information
-K|--offload Set protocol offload
@@ -28,6 +51,8 @@ tab = ""
def printtab(msg):
print tab + msg
+all_devices = []
+
ethtool_coalesce_msgs = (
( "stats-block-usecs",
"stats_block_coalesce_usecs" ),
@@ -75,6 +100,19 @@ ethtool_coalesce_msgs = (
"tx_max_coalesced_frames_high"),
)
+def get_coalesce_dict_entry(ethtool_name):
+ if ethtool_name == "adaptive-rx":
+ return "use_adaptive_rx_coalesce"
+
+ if ethtool_name == "adaptive-tx":
+ return "use_adaptive_tx_coalesce"
+
+ for name in ethtool_coalesce_msgs:
+ if name[0] == ethtool_name:
+ return name[1]
+
+ return None
+
def show_coalesce(interface, args = None):
printtab("Coalesce parameters for %s:" % interface)
try:
@@ -102,6 +140,36 @@ def show_coalesce(interface, args = None):
if tunable not in printed:
printtab("%s %s" % (tunable, coal[tunable]))
+def set_coalesce(interface, args):
+ try:
+ coal = ethtool.get_coalesce(interface)
+ except IOError:
+ printtab("Interrupt coalescing NOT supported on %s!" % interface)
+ return
+
+ changed = False
+ args = [a.lower() for a in args]
+ for arg, value in [ ( args[i], args[i + 1] ) for i in range(0, len(args), 2) ]:
+ real_arg = get_coalesce_dict_entry(arg)
+ if not real_arg:
+ continue
+ if value == "on":
+ value = 1
+ elif value == "off":
+ value = 0
+ else:
+ try:
+ value = int(value)
+ except:
+ continue
+ if coal[real_arg] != value:
+ coal[real_arg] = value
+ changed = True
+
+ if not changed:
+ return
+
+ ethtool.set_coalesce(interface, coal)
def show_offload(interface, args = None):
try:
@@ -154,12 +222,12 @@ def show_driver(interface, args = None):
printtab("bus-info: %s" % bus)
def run_cmd(cmd, interface, args):
- global tab
+ global tab, all_devices
active_devices = ethtool.get_active_devices()
if not interface:
tab = " "
- for interface in ethtool.get_devices():
+ for interface in all_devices:
inactive = " (not active)"
if interface in active_devices:
inactive = ""
@@ -172,14 +240,19 @@ def run_cmd_noargs(cmd, args):
if args:
run_cmd(cmd, args[0], None)
else:
+ global all_devices
+ all_devices = ethtool.get_devices()
run_cmd(cmd, None, None)
def main():
+ global all_devices
+
try:
opts, args = getopt.getopt(sys.argv[1:],
- "hcikK",
+ "hcCikK",
("help",
"show-coalesce",
+ "coalesce",
"driver",
"show-offload",
"offload"))
@@ -205,16 +278,25 @@ def main():
elif o in ("-k", "--show-offload"):
run_cmd_noargs(show_offload, args)
break
- elif o in ("-K", "--offload"):
- if len(args) == 2:
+ elif o in ("-K", "--offload",
+ "-C", "--coalesce"):
+ all_devices = ethtool.get_devices()
+ if len(args) < 2:
+ usage()
+ sys.exit(1)
+
+ if args[0] not in all_devices:
interface = None
- elif len(args) == 3:
+ else:
interface = args[0]
args = args[1:]
- else:
- usage()
- sys.exit(1)
- run_cmd(set_offload, interface, args)
+
+ if o in ("-K", "--offload"):
+ cmd = set_offload
+ elif o in ("-C", "--coalesce"):
+ cmd = set_coalesce
+
+ run_cmd(cmd, interface, args)
break
if __name__ == '__main__':
diff --git a/python-ethtool/ethtool.c b/python-ethtool/ethtool.c
index 4dd8fdf..6ce5208 100644
--- a/python-ethtool/ethtool.c
+++ b/python-ethtool/ethtool.c
@@ -603,6 +603,44 @@ free_dict:
#define struct_desc_create_dict(table, values) \
__struct_desc_create_dict(table, ARRAY_SIZE(table), values)
+static int __struct_desc_from_dict(struct struct_desc *table,
+ int nr_entries, void *to, PyObject *dict)
+{
+ char buf[2048];
+ int i;
+
+ for (i = 0; i < nr_entries; ++i) {
+ struct struct_desc *d = &table[i];
+ void *val = to + d->offset;
+ PyObject *obj;
+
+ switch (d->size) {
+ case sizeof(uint32_t):
+ obj = PyDict_GetItemString(dict, d->name);
+ if (obj == NULL) {
+ snprintf(buf, sizeof(buf),
+ "Missing dict entry for field %s",
+ d->name);
+ PyErr_SetString(PyExc_IOError, buf);
+ return -1;
+ }
+ *(uint32_t *)val = PyInt_AsLong(obj);
+ break;
+ default:
+ snprintf(buf, sizeof(buf),
+ "Invalid type size %d for field %s",
+ d->size, d->name);
+ PyErr_SetString(PyExc_IOError, buf);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+#define struct_desc_from_dict(table, to, dict) \
+ __struct_desc_from_dict(table, ARRAY_SIZE(table), to, dict)
+
static PyObject *get_coalesce(PyObject *self __unused, PyObject *args)
{
struct ethtool_coalesce coal;
@@ -613,6 +651,25 @@ static PyObject *get_coalesce(PyObject *self __unused, PyObject *args)
return struct_desc_create_dict(ethtool_coalesce_desc, &coal);
}
+static PyObject *set_coalesce(PyObject *self __unused, PyObject *args)
+{
+ struct ethtool_coalesce coal;
+ char *devname;
+ PyObject *dict;
+
+ if (!PyArg_ParseTuple(args, "sO", &devname, &dict))
+ return NULL;
+
+ if (struct_desc_from_dict(ethtool_coalesce_desc, &coal, dict) != 0)
+ return NULL;
+
+ if (send_command(ETHTOOL_SCOALESCE, devname, &coal))
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
static struct PyMethodDef PyEthModuleMethods[] = {
{
.ml_name = "get_module",
@@ -650,6 +707,11 @@ static struct PyMethodDef PyEthModuleMethods[] = {
.ml_flags = METH_VARARGS,
},
{
+ .ml_name = "set_coalesce",
+ .ml_meth = (PyCFunction)set_coalesce,
+ .ml_flags = METH_VARARGS,
+ },
+ {
.ml_name = "get_devices",
.ml_meth = (PyCFunction)get_devices,
.ml_flags = METH_VARARGS,