hamachi interrupt coalescing ioctl

Pete Wyckoff pw@dancer.ca.sandia.gov
Fri Feb 19 17:10:04 1999


I've added a few lines to the hamachi driver to enable changing the
parameters regarding interrupt coalescing by an ioctl.  It could be
made to work from a userspace program as there's no checks on suser(),
or you could decide to make sure only root can call it.

Attached is the diff, and a little program to call the ioctl.  See
the main yellowfin driver page at beowulf for more information on the
parameters themselves.  The default settings are good for the high
bandwidth regime, but not so for low latency.  Setting both values to
zero reduced the one-way userspace latency from 54 us to 14 us for my
setup.  Of course the bandwidth went down to under 100 Mb/s.  Ideally an
application program would make the ioctl() calls to set up different
phases of its communications patterns.

It has only been tested on linux-alpha v2.2.1.

		-- Pete
---------------------------------------------
Pete Wyckoff          | wyckoff@ca.sandia.gov
Sandia National Labs  | 925 294 3503 (voice)
MS 9011, P.O. Box 969 | 925 294 1225 (fax)
Livermore, CA  94551  |


--- stock-hamachi.c	Fri Feb 19 13:56:16 1999
+++ hamachi.c	Fri Feb 19 13:59:14 1999
@@ -50,6 +50,12 @@
 #define TX_RING_SIZE	16
 #define RX_RING_SIZE	32
 
+/*
+ * Enable mii_ioctl.  Added interrupt coalescing parameter adjustment.
+ * 2/19/99 Pete Wyckoff <wyckoff@ca.sandia.gov>
+ */
+#define HAVE_PRIVATE_IOCTL
+
 /* Operational parameters that usually are not changed. */
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  (2*HZ)
@@ -1251,6 +1257,15 @@
 			return -EPERM;
 		mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]);
 		return 0;
+	case SIOCDEVPRIVATE+3: { /* set rx,tx intr params */
+		u32 *d = (u32 *)&rq->ifr_data;
+		writel(d[0], dev->base_addr + TxIntrCtrl);
+		writel(d[1], dev->base_addr + RxIntrCtrl);
+		printk(KERN_NOTICE "%s: tx %08x, rx %08x intr\n", dev->name,
+		  (u32) readl(dev->base_addr + TxIntrCtrl),
+		  (u32) readl(dev->base_addr + RxIntrCtrl));
+		return 0;
+	    }
 	default:
 		return -EOPNOTSUPP;
 	}

----------------------- test program "setintr.c" ----------------------------
/*
 * Say ioctl to the hamachi.
 * 2/19/99 Pete Wyckoff <wyckoff@ca.sandia.gov>
 *
 * Watch out for the cheesy way I "detect" the card by looking at
 * IP numbers.  A better way would be to know in advance which device
 * it is, such as "eth1" and hardcode that into a comparison on the
 * name field, or supply it on the command line.
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <net/if.h>
#include <netinet/in.h>

typedef unsigned int u32;

static void
usage()
{
    fprintf(stderr, "Usage: setintr { -d | <tx> <rx> }  (values in hex)\n");
    exit(1);
}

int
main(int argc, char* argv[])
{
    int i, s;
    u32 tx, rx, *d;
    struct ifconf ifc;
    struct ifreq *ifr;
    struct sockaddr_in *sin;
    char buf[128];

    if (argc == 2 && !strcmp(argv[1], "-d")) {
	tx = 0x00080000;  /* "defaults" from the driver" */
	rx = 0x00000020;
    } else if (argc == 3) {
	tx = strtoul(argv[1], 0, 16);
	rx = strtoul(argv[2], 0, 16);
    } else
    usage();

    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
	perror("socket");
	return 1;
    }

    ifc.ifc_buf = buf;
    ifc.ifc_len = sizeof(buf);
    if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
	perror("ioctl SIOCGIFCONF");
	return 1;
    }

    ifc.ifc_len /= sizeof(struct ifreq);
    for (i=0; i<ifc.ifc_len; i++) {
	ifr = (struct ifreq *) &ifc.ifc_req[i];
	sin = (struct sockaddr_in *) &ifr->ifr_addr;
	if (sin->sin_family == AF_INET) {
	    if ((sin->sin_addr.s_addr & 0xffff) == 0x020a)
		break;  /* 10.2.something */
	}
    }
    if (i == ifc.ifc_len) {
	printf("not found\n");
	return 0;
    }

    d = (u32 *)&ifr->ifr_data;
    d[0] = tx;
    d[1] = rx;
    if (ioctl(s, SIOCDEVPRIVATE+3, ifr) < 0) {
	perror("ioctl SIOCDEVPRIVATE+3");
	return 1;
    }
    return 0;
}

 | To unsubscribe, send mail to Majordomo@cesdis.gsfc.nasa.gov, and within the
 |  body of the mail, include only the text:
 |   unsubscribe this-list-name youraddress@wherever.org
 | You will be unsubscribed as speedily as possible.