All of lore.kernel.org
 help / color / mirror / Atom feed
From: Asias He <asias.hejun@gmail.com>
To: Sasha Levin <levinsasha928@gmail.com>
Cc: penberg@cs.helsinki.fi, kvm@vger.kernel.org, mingo@elte.hu,
	gorcunov@gmail.com
Subject: Re: [PATCH v2] kvm tools: Support multiple net devices
Date: Mon, 26 Sep 2011 19:57:59 +0800	[thread overview]
Message-ID: <4E8068C7.7080009@gmail.com> (raw)
In-Reply-To: <1316949085-22598-1-git-send-email-levinsasha928@gmail.com>

On 09/25/2011 07:11 PM, Sasha Levin wrote:
> This patch adds support for multiple network devices. The command line syntax
> changes to the following:
> 
> 	--network/-n [mode=[tap/user/none]] [guest_ip=[guest ip]] [host_ip=
> [host_ip]] [guest_mac=[guest_mac]] [script=[script]]

This syntax is actually, no?

   --network/-n mode=tap,guest_ip=x.x.x.x

not

   --network/-n mode=tag guest_ip=x.x.x.x


This works for me:
$ sudo ./kvm run -d sid.img -p root=/dev/vda1 -k bzImage  \
-n mode=tap,host_ip=192.168.100.1 -n mode=tap,host_ip=192.168.200.1

This does not work for me:
$ sudo ./kvm run -d sid.img -p root=/dev/vda1 -k bzImage \
-n mode=tap host_ip=192.168.100.1 -n mode=tap host_ip=192.168.200.1


> 
> Each of the parameters is optional, and the config defaults to a TAP based
> networking with a sequential MAC.
> 
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
>  tools/kvm/builtin-run.c |  146 ++++++++++++++++++++++++++++++++------------
>  tools/kvm/virtio/net.c  |  155 +++++++++++++++++++++++++---------------------
>  2 files changed, 191 insertions(+), 110 deletions(-)
> 
> diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
> index 28dc95a..070b1b6 100644
> --- a/tools/kvm/builtin-run.c
> +++ b/tools/kvm/builtin-run.c
> @@ -87,9 +87,12 @@ static bool sdl;
>  static bool balloon;
>  static bool using_rootfs;
>  static bool custom_rootfs;
> +static bool no_net;
>  extern bool ioport_debug;
>  extern int  active_console;
>  extern int  debug_iodelay;
> +struct virtio_net_parameters *net_params;
> +int num_net_devices;
>  
>  bool do_debug_print = false;
>  
> @@ -182,6 +185,89 @@ static int tty_parser(const struct option *opt, const char *arg, int unset)
>  	return 0;
>  }
>  
> +static inline void str_to_mac(const char *str, char *mac)
> +{
> +	sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
> +		mac, mac+1, mac+2, mac+3, mac+4, mac+5);
> +}
> +static int set_net_param(struct virtio_net_parameters *p, const char *param,
> +				const char *val)
> +{
> +	if (strcmp(param, "guest_mac") == 0) {
> +		str_to_mac(val, p->guest_mac);
> +	} else if (strcmp(param, "mode") == 0) {
> +		if (!strncmp(val, "user", 4)) {
> +			int i;
> +
> +			for (i = 0; i < num_net_devices; i++)
> +				if (net_params[i].mode == NET_MODE_USER)
> +					die("Only one usermode network device allowed at a time");
> +			p->mode = NET_MODE_USER;
> +		} else if (!strncmp(val, "tap", 3)) {
> +			p->mode = NET_MODE_TAP;
> +		} else if (!strncmp(val, "none", 4)) {
> +			no_net = 1;
> +			return -1;
> +		} else
> +			die("Unkown network mode %s, please use user, tap or none", network);
> +	} else if (strcmp(param, "script") == 0) {
> +		p->script = val;
> +	} else if (strcmp(param, "guest_ip") == 0) {
> +		p->guest_ip = val;
> +	} else if (strcmp(param, "host_ip") == 0) {
> +		p->host_ip = val;
> +	}
> +
> +	return 0;
> +}
> +
> +static int netdev_parser(const struct option *opt, const char *arg, int unset)
> +{
> +	struct virtio_net_parameters p;
> +	char *buf, *cmd = NULL, *cur = NULL;
> +	bool on_cmd = true;
> +
> +	if (arg) {
> +		buf = strdup(arg);
> +		if (buf == NULL)
> +			die("Failed allocating new net buffer");
> +		cur = strtok(buf, ",=");
> +	}
> +
> +	p = (struct virtio_net_parameters) {
> +		.guest_ip	= DEFAULT_GUEST_ADDR,
> +		.host_ip	= DEFAULT_HOST_ADDR,
> +		.script		= DEFAULT_SCRIPT,
> +		.mode		= NET_MODE_TAP,
> +	};
> +
> +	str_to_mac(DEFAULT_GUEST_MAC, p.guest_mac);
> +	p.guest_mac[5] += num_net_devices;
> +
> +	while (cur) {
> +		if (on_cmd) {
> +			cmd = cur;
> +		} else {
> +			if (set_net_param(&p, cmd, cur) < 0)
> +				goto done;
> +		}
> +		on_cmd = !on_cmd;
> +
> +		cur = strtok(NULL, ",=");
> +	};
> +
> +	num_net_devices++;
> +
> +	net_params = realloc(net_params, num_net_devices * sizeof(*net_params));
> +	if (net_params == NULL)
> +		die("Failed adding new network device");
> +
> +	net_params[num_net_devices - 1] = p;
> +
> +done:
> +	return 0;
> +}
> +
>  static int shmem_parser(const struct option *opt, const char *arg, int unset)
>  {
>  	const u64 default_size = SHMEM_DEFAULT_SIZE;
> @@ -339,18 +425,9 @@ static const struct option options[] = {
>  			"Kernel command line arguments"),
>  
>  	OPT_GROUP("Networking options:"),
> -	OPT_STRING('n', "network", &network, "user, tap, none",
> -			"Network to use"),
> -	OPT_STRING('\0', "host-ip", &host_ip, "a.b.c.d",
> -			"Assign this address to the host side networking"),
> -	OPT_STRING('\0', "guest-ip", &guest_ip, "a.b.c.d",
> -			"Assign this address to the guest side networking"),
> -	OPT_STRING('\0', "host-mac", &host_mac, "aa:bb:cc:dd:ee:ff",
> -			"Assign this address to the host side NIC"),
> -	OPT_STRING('\0', "guest-mac", &guest_mac, "aa:bb:cc:dd:ee:ff",
> -			"Assign this address to the guest side NIC"),
> -	OPT_STRING('\0', "tapscript", &script, "Script path",
> -			 "Assign a script to process created tap device"),
> +	OPT_CALLBACK_DEFAULT('n', "network", NULL, "network params",
> +		     "Create a new guest NIC",
> +		     netdev_parser, NULL),
>  
>  	OPT_GROUP("BIOS options:"),
>  	OPT_INTEGER('\0', "vidmode", &vidmode,
> @@ -615,7 +692,6 @@ void kvm_run_help(void)
>  
>  int kvm_cmd_run(int argc, const char **argv, const char *prefix)
>  {
> -	struct virtio_net_parameters net_params;
>  	static char real_cmdline[2048], default_name[20];
>  	struct framebuffer *fb = NULL;
>  	unsigned int nr_online_cpus;
> @@ -823,32 +899,24 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
>  
>  	virtio_9p__init(kvm);
>  
> -	if (strncmp(network, "none", 4)) {
> -		net_params.guest_ip = guest_ip;
> -		net_params.host_ip = host_ip;
> -		net_params.kvm = kvm;
> -		net_params.script = script;
> -		sscanf(guest_mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
> -			net_params.guest_mac,
> -			net_params.guest_mac+1,
> -			net_params.guest_mac+2,
> -			net_params.guest_mac+3,
> -			net_params.guest_mac+4,
> -			net_params.guest_mac+5);
> -		sscanf(host_mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
> -			net_params.host_mac,
> -			net_params.host_mac+1,
> -			net_params.host_mac+2,
> -			net_params.host_mac+3,
> -			net_params.host_mac+4,
> -			net_params.host_mac+5);
> -
> -		if (!strncmp(network, "user", 4))
> -			net_params.mode = NET_MODE_USER;
> -		else if (!strncmp(network, "tap", 3))
> -			net_params.mode = NET_MODE_TAP;
> -		else
> -			die("Unkown network mode %s, please use -network user, tap, none", network);
> +	for (i = 0; i < num_net_devices; i++) {
> +		net_params[i].kvm = kvm;
> +		virtio_net__init(&net_params[i]);
> +	}
> +
> +	if (num_net_devices == 0 && no_net == 0) {
> +		struct virtio_net_parameters net_params;
> +
> +		net_params = (struct virtio_net_parameters) {
> +			.guest_ip	= guest_ip,
> +			.host_ip	= host_ip,
> +			.kvm		= kvm,
> +			.script		= script,
> +			.mode		= NET_MODE_USER,
> +		};
> +		str_to_mac(guest_mac, net_params.guest_mac);
> +		str_to_mac(host_mac, net_params.host_mac);
> +
>  		virtio_net__init(&net_params);
>  	}
>  
> diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
> index 4700483..1e33891 100644
> --- a/tools/kvm/virtio/net.c
> +++ b/tools/kvm/virtio/net.c
> @@ -43,6 +43,7 @@ struct net_dev_operations {
>  struct net_dev {
>  	pthread_mutex_t			mutex;
>  	struct virtio_pci		vpci;
> +	struct list_head		list;
>  
>  	struct virt_queue		vqs[VIRTIO_NET_NUM_QUEUES];
>  	struct virtio_net_config	config;
> @@ -64,48 +65,41 @@ struct net_dev {
>  
>  	struct uip_info			info;
>  	struct net_dev_operations	*ops;
> +	struct kvm			*kvm;
>  };
>  
> -static struct net_dev ndev = {
> -	.mutex	= PTHREAD_MUTEX_INITIALIZER,
> -
> -	.config = {
> -		.status			= VIRTIO_NET_S_LINK_UP,
> -	},
> -	.info = {
> -		.buf_nr			= 20,
> -	}
> -};
> +static LIST_HEAD(ndevs);
>  
>  static void *virtio_net_rx_thread(void *p)
>  {
>  	struct iovec iov[VIRTIO_NET_QUEUE_SIZE];
>  	struct virt_queue *vq;
>  	struct kvm *kvm;
> +	struct net_dev *ndev = p;
>  	u16 out, in;
>  	u16 head;
>  	int len;
>  
> -	kvm	= p;
> -	vq	= &ndev.vqs[VIRTIO_NET_RX_QUEUE];
> +	kvm	= ndev->kvm;
> +	vq	= &ndev->vqs[VIRTIO_NET_RX_QUEUE];
>  
>  	while (1) {
>  
> -		mutex_lock(&ndev.io_rx_lock);
> +		mutex_lock(&ndev->io_rx_lock);
>  		if (!virt_queue__available(vq))
> -			pthread_cond_wait(&ndev.io_rx_cond, &ndev.io_rx_lock);
> -		mutex_unlock(&ndev.io_rx_lock);
> +			pthread_cond_wait(&ndev->io_rx_cond, &ndev->io_rx_lock);
> +		mutex_unlock(&ndev->io_rx_lock);
>  
>  		while (virt_queue__available(vq)) {
>  
>  			head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
>  
> -			len = ndev.ops->rx(iov, in, &ndev);
> +			len = ndev->ops->rx(iov, in, ndev);
>  
>  			virt_queue__set_used_elem(vq, head, len);
>  
>  			/* We should interrupt guest right now, otherwise latency is huge. */
> -			virtio_pci__signal_vq(kvm, &ndev.vpci, VIRTIO_NET_RX_QUEUE);
> +			virtio_pci__signal_vq(kvm, &ndev->vpci, VIRTIO_NET_RX_QUEUE);
>  		}
>  
>  	}
> @@ -120,29 +114,30 @@ static void *virtio_net_tx_thread(void *p)
>  	struct iovec iov[VIRTIO_NET_QUEUE_SIZE];
>  	struct virt_queue *vq;
>  	struct kvm *kvm;
> +	struct net_dev *ndev = p;
>  	u16 out, in;
>  	u16 head;
>  	int len;
>  
> -	kvm	= p;
> -	vq	= &ndev.vqs[VIRTIO_NET_TX_QUEUE];
> +	kvm	= ndev->kvm;
> +	vq	= &ndev->vqs[VIRTIO_NET_TX_QUEUE];
>  
>  	while (1) {
> -		mutex_lock(&ndev.io_tx_lock);
> +		mutex_lock(&ndev->io_tx_lock);
>  		if (!virt_queue__available(vq))
> -			pthread_cond_wait(&ndev.io_tx_cond, &ndev.io_tx_lock);
> -		mutex_unlock(&ndev.io_tx_lock);
> +			pthread_cond_wait(&ndev->io_tx_cond, &ndev->io_tx_lock);
> +		mutex_unlock(&ndev->io_tx_lock);
>  
>  		while (virt_queue__available(vq)) {
>  
>  			head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
>  
> -			len = ndev.ops->tx(iov, out, &ndev);
> +			len = ndev->ops->tx(iov, out, ndev);
>  
>  			virt_queue__set_used_elem(vq, head, len);
>  		}
>  
> -		virtio_pci__signal_vq(kvm, &ndev.vpci, VIRTIO_NET_TX_QUEUE);
> +		virtio_pci__signal_vq(kvm, &ndev->vpci, VIRTIO_NET_TX_QUEUE);
>  	}
>  
>  	pthread_exit(NULL);
> @@ -151,58 +146,58 @@ static void *virtio_net_tx_thread(void *p)
>  
>  }
>  
> -static void virtio_net_handle_callback(struct kvm *kvm, u16 queue_index)
> +static void virtio_net_handle_callback(struct kvm *kvm, struct net_dev *ndev, int queue)
>  {
> -	switch (queue_index) {
> +	switch (queue) {
>  	case VIRTIO_NET_TX_QUEUE:
> -		mutex_lock(&ndev.io_tx_lock);
> -		pthread_cond_signal(&ndev.io_tx_cond);
> -		mutex_unlock(&ndev.io_tx_lock);
> +		mutex_lock(&ndev->io_tx_lock);
> +		pthread_cond_signal(&ndev->io_tx_cond);
> +		mutex_unlock(&ndev->io_tx_lock);
>  		break;
>  	case VIRTIO_NET_RX_QUEUE:
> -		mutex_lock(&ndev.io_rx_lock);
> -		pthread_cond_signal(&ndev.io_rx_cond);
> -		mutex_unlock(&ndev.io_rx_lock);
> +		mutex_lock(&ndev->io_rx_lock);
> +		pthread_cond_signal(&ndev->io_rx_cond);
> +		mutex_unlock(&ndev->io_rx_lock);
>  		break;
>  	default:
> -		pr_warning("Unknown queue index %u", queue_index);
> +		pr_warning("Unknown queue index %u", queue);
>  	}
>  }
>  
> -static bool virtio_net__tap_init(const struct virtio_net_parameters *params)
> +static bool virtio_net__tap_init(const struct virtio_net_parameters *params,
> +					struct net_dev *ndev)
>  {
>  	int sock = socket(AF_INET, SOCK_STREAM, 0);
>  	int pid, status, offload, hdr_len;
>  	struct sockaddr_in sin = {0};
>  	struct ifreq ifr;
>  
> -	ndev.tap_fd = open("/dev/net/tun", O_RDWR);
> -	if (ndev.tap_fd < 0) {
> +	ndev->tap_fd = open("/dev/net/tun", O_RDWR);
> +	if (ndev->tap_fd < 0) {
>  		pr_warning("Unable to open /dev/net/tun");
>  		goto fail;
>  	}
>  
>  	memset(&ifr, 0, sizeof(ifr));
>  	ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
> -	if (ioctl(ndev.tap_fd, TUNSETIFF, &ifr) < 0) {
> +	if (ioctl(ndev->tap_fd, TUNSETIFF, &ifr) < 0) {
>  		pr_warning("Config tap device error. Are you root?");
>  		goto fail;
>  	}
>  
> -	strncpy(ndev.tap_name, ifr.ifr_name, sizeof(ndev.tap_name));
> +	strncpy(ndev->tap_name, ifr.ifr_name, sizeof(ndev->tap_name));
>  
> -	if (ioctl(ndev.tap_fd, TUNSETNOCSUM, 1) < 0) {
> +	if (ioctl(ndev->tap_fd, TUNSETNOCSUM, 1) < 0) {
>  		pr_warning("Config tap device TUNSETNOCSUM error");
>  		goto fail;
>  	}
>  
>  	hdr_len = sizeof(struct virtio_net_hdr);
> -	if (ioctl(ndev.tap_fd, TUNSETVNETHDRSZ, &hdr_len) < 0) {
> +	if (ioctl(ndev->tap_fd, TUNSETVNETHDRSZ, &hdr_len) < 0)
>  		pr_warning("Config tap device TUNSETVNETHDRSZ error");
> -	}
>  
>  	offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_UFO;
> -	if (ioctl(ndev.tap_fd, TUNSETOFFLOAD, offload) < 0) {
> +	if (ioctl(ndev->tap_fd, TUNSETOFFLOAD, offload) < 0) {
>  		pr_warning("Config tap device TUNSETOFFLOAD error");
>  		goto fail;
>  	}
> @@ -210,7 +205,7 @@ static bool virtio_net__tap_init(const struct virtio_net_parameters *params)
>  	if (strcmp(params->script, "none")) {
>  		pid = fork();
>  		if (pid == 0) {
> -			execl(params->script, params->script, ndev.tap_name, NULL);
> +			execl(params->script, params->script, ndev->tap_name, NULL);
>  			_exit(1);
>  		} else {
>  			waitpid(pid, &status, 0);
> @@ -221,7 +216,7 @@ static bool virtio_net__tap_init(const struct virtio_net_parameters *params)
>  		}
>  	} else {
>  		memset(&ifr, 0, sizeof(ifr));
> -		strncpy(ifr.ifr_name, ndev.tap_name, sizeof(ndev.tap_name));
> +		strncpy(ifr.ifr_name, ndev->tap_name, sizeof(ndev->tap_name));
>  		sin.sin_addr.s_addr = inet_addr(params->host_ip);
>  		memcpy(&(ifr.ifr_addr), &sin, sizeof(ifr.ifr_addr));
>  		ifr.ifr_addr.sa_family = AF_INET;
> @@ -232,7 +227,7 @@ static bool virtio_net__tap_init(const struct virtio_net_parameters *params)
>  	}
>  
>  	memset(&ifr, 0, sizeof(ifr));
> -	strncpy(ifr.ifr_name, ndev.tap_name, sizeof(ndev.tap_name));
> +	strncpy(ifr.ifr_name, ndev->tap_name, sizeof(ndev->tap_name));
>  	ioctl(sock, SIOCGIFFLAGS, &ifr);
>  	ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
>  	if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0)
> @@ -245,22 +240,22 @@ static bool virtio_net__tap_init(const struct virtio_net_parameters *params)
>  fail:
>  	if (sock >= 0)
>  		close(sock);
> -	if (ndev.tap_fd >= 0)
> -		close(ndev.tap_fd);
> +	if (ndev->tap_fd >= 0)
> +		close(ndev->tap_fd);
>  
>  	return 0;
>  }
>  
> -static void virtio_net__io_thread_init(struct kvm *kvm)
> +static void virtio_net__io_thread_init(struct kvm *kvm, struct net_dev *ndev)
>  {
> -	pthread_mutex_init(&ndev.io_rx_lock, NULL);
> -	pthread_cond_init(&ndev.io_tx_cond, NULL);
> +	pthread_mutex_init(&ndev->io_rx_lock, NULL);
> +	pthread_cond_init(&ndev->io_tx_cond, NULL);
>  
> -	pthread_mutex_init(&ndev.io_rx_lock, NULL);
> -	pthread_cond_init(&ndev.io_tx_cond, NULL);
> +	pthread_mutex_init(&ndev->io_rx_lock, NULL);
> +	pthread_cond_init(&ndev->io_tx_cond, NULL);
>  
> -	pthread_create(&ndev.io_rx_thread, NULL, virtio_net_rx_thread, (void *)kvm);
> -	pthread_create(&ndev.io_tx_thread, NULL, virtio_net_tx_thread, (void *)kvm);
> +	pthread_create(&ndev->io_rx_thread, NULL, virtio_net_rx_thread, ndev);
> +	pthread_create(&ndev->io_tx_thread, NULL, virtio_net_tx_thread, ndev);
>  }
>  
>  static inline int tap_ops_tx(struct iovec *iov, u16 out, struct net_dev *ndev)
> @@ -345,7 +340,9 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn)
>  
>  static int notify_vq(struct kvm *kvm, void *dev, u32 vq)
>  {
> -	virtio_net_handle_callback(kvm, vq);
> +	struct net_dev *ndev = dev;
> +
> +	virtio_net_handle_callback(kvm, ndev, vq);
>  
>  	return 0;
>  }
> @@ -365,27 +362,43 @@ static int get_size_vq(struct kvm *kvm, void *dev, u32 vq)
>  void virtio_net__init(const struct virtio_net_parameters *params)
>  {
>  	int i;
> +	struct net_dev *ndev;
> +
> +	if (!params)
> +		return;
> +
> +	ndev = calloc(1, sizeof(struct net_dev));
> +	if (ndev == NULL)
> +		die("Failed allocating ndev");
> +
> +	list_add_tail(&ndev->list, &ndevs);
> +
> +	ndev->kvm = params->kvm;
> +
> +	mutex_init(&ndev->mutex);
> +	ndev->config.status = VIRTIO_NET_S_LINK_UP;
>  
>  	for (i = 0 ; i < 6 ; i++) {
> -		ndev.config.mac[i]		= params->guest_mac[i];
> -		ndev.info.guest_mac.addr[i]	= params->guest_mac[i];
> -		ndev.info.host_mac.addr[i]	= params->host_mac[i];
> +		ndev->config.mac[i]		= params->guest_mac[i];
> +		ndev->info.guest_mac.addr[i]	= params->guest_mac[i];
> +		ndev->info.host_mac.addr[i]	= params->host_mac[i];
>  	}
>  
> -	ndev.mode = params->mode;
> -	if (ndev.mode == NET_MODE_TAP) {
> -		virtio_net__tap_init(params);

we need to check if virtio_net__tap_init is successful. if it fails, for
example lack of permission, we should exit and give up this net device.
Otherwise, we will have this:

$ ./kvm run -n mode=tap


[    1.490781] registered taskstats version 1
[    1.492781] BUG: unable to handle kernel NULL pointer dereference at
0000001c
[    1.493781] IP: [<c14f3236>] virtnet_poll+0x16e/0x408
[    1.493781] *pde = 00000000
[    1.493781] Oops: 0000 [#1] PREEMPT SMP
[    1.493781] Modules linked in:
[    1.493781]
[    1.493781] Pid: 1, comm: swapper Tainted: G        W   3.1.0-rc3+ #77
[    1.493781] EIP: 0060:[<c14f3236>] EFLAGS: 00010286 CPU: 1
[    1.493781] EIP is at virtnet_poll+0x16e/0x408
[    1.493781] EAX: 00001000 EBX: db4bb0c0 ECX: db7cd778 EDX: 00001000
[    1.493781] ESI: 00000000 EDI: db7cd6c0 EBP: db487fa8 ESP: db487f64
[    1.493781]  DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
[    1.493781] Process swapper (pid: 1, ti=db486000 task=db450000
task.ti=db458000)
[    1.493781] Stack:
[    1.493781]  db487f98 19dfb000 db5e1400 00000080 c1b0df60 db6ff000
00000000 00000010
[    1.493781]  00000080 dbcebfe0 db5e1414 db5e1000 ffffffff fffec005
db5e1414 db906dc0
[    1.493781]  c1a39a0c db487fd4 c15e4869 fffb71f7 db906dc8 00000080
0000012c 00000000
[    1.493781] Call Trace:
[    1.493781]  [<c15e4869>] net_rx_action+0x8e/0x177
[    1.493781]  [<c1066128>] __do_softirq+0xa7/0x158
[    1.493781]  [<c1066081>] ? __tasklet_hi_schedule_first+0x2b/0x2b
[    1.493781]  <IRQ>
[    1.493781]  [<c1065e82>] ? _local_bh_enable_ip.isra.9+0x65/0x86
[    1.493781]  [<c1065eab>] ? local_bh_enable_ip+0x8/0xa
[    1.493781]  [<c16a7a78>] ? _raw_spin_unlock_bh+0x18/0x1a
[    1.493781]  [<c15e59c5>] ? dev_set_rx_mode+0x22/0x26
[    1.493781]  [<c15e5a5f>] ? __dev_open+0x96/0xa6
[    1.493781]  [<c15e5c23>] ? __dev_change_flags+0x97/0x10e
[    1.493781]  [<c15e5cfe>] ? dev_change_flags+0x13/0x3f
[    1.493781]  [<c1acfe6f>] ? ip_auto_config+0x160/0xcf8
[    1.493781]  [<c1393c86>] ? extract_entropy+0x45/0x71
[    1.493781]  [<c1059e35>] ? get_parent_ip+0xb/0x31
[    1.493781]  [<c16aa6b7>] ? sub_preempt_count+0x7c/0x89
[    1.493781]  [<c16a7d24>] ? _raw_spin_unlock+0x1c/0x27
[    1.493781]  [<c1629173>] ? tcp_set_default_congestion_control+0x8c/0x95
[    1.493781]  [<c1001159>] ? do_one_initcall+0x71/0x114
[    1.493781]  [<c1acfd0f>] ? root_nfs_parse_addr+0x91/0x91
[    1.493781]  [<c1a9c7ab>] ? kernel_init+0xab/0x11d
[    1.493781]  [<c1a9c700>] ? start_kernel+0x301/0x301
[    1.493781]  [<c16acfb6>] ? kernel_thread_helper+0x6/0xd
[    1.493781] Code: 89 d8 e8 23 94 0e 00 8b 4d dc 89 c7 f3 a4 8b 55 dc
8b 4d d8 29 55 f0 8b 75 e0 01 d1 eb 13 8d 45 f0 89 f2 50 89 d8 e8 ae f2
ff ff <8b> 76 1c 31 c9 58 83 7d f0 00 75 e7 85 f6 89 75 e0 0f 84 6e 02
[    1.493781] EIP: [<c14f3236>] virtnet_poll+0x16e/0x408 SS:ESP
0068:db487f64
[    1.493781] CR2: 000000000000001c
[    1.549772] ---[ end trace 4eaa2a86a8e2da27 ]---
[    1.550772] Kernel panic - not syncing: Fatal exception in interrupt
[    1.551772] Pid: 1, comm: swapper Tainted: G      D W   3.1.0-rc3+ #77
[    1.553771] Call Trace:
[    1.553771]  [<c169ca33>] panic+0x58/0x156
[    1.554771]  [<c16a921a>] oops_end+0x8c/0x9b
[    1.555771]  [<c169c4e7>] no_context+0x116/0x120
[    1.555771]  [<c169c5e1>] __bad_area_nosemaphore+0xf0/0xf8
[    1.557771]  [<c169c5f6>] bad_area_nosemaphore+0xd/0x10
[    1.558771]  [<c16aa4b5>] do_page_fault+0x174/0x2fa
[    1.559770]  [<c107bad0>] ? sched_clock_local+0x10/0x14b
[    1.560770]  [<c15db33f>] ? __netdev_alloc_skb+0x17/0x34
[    1.561770]  [<c10e9b84>] ? __kmalloc_track_caller+0xb7/0xc7
[    1.563770]  [<c15db33f>] ? __netdev_alloc_skb+0x17/0x34
[    1.564770]  [<c16aa341>] ? spurious_fault+0xa8/0xa8
[    1.565770]  [<c16a89d6>] error_code+0x5a/0x60
[    1.566769]  [<c16aa341>] ? spurious_fault+0xa8/0xa8
[    1.567769]  [<c14f3236>] ? virtnet_poll+0x16e/0x408
[    1.567769]  [<c15e4869>] net_rx_action+0x8e/0x177
[    1.568769]  [<c1066128>] __do_softirq+0xa7/0x158
[    1.569769]  [<c1066081>] ? __tasklet_hi_schedule_first+0x2b/0x2b
[    1.569769]  <IRQ>  [<c1065e82>] ? _local_bh_enable_ip.isra.9+0x65/0x86
[    1.570769]  [<c1065eab>] ? local_bh_enable_ip+0x8/0xa
[    1.571769]  [<c16a7a78>] ? _raw_spin_unlock_bh+0x18/0x1a
[    1.571769]  [<c15e59c5>] ? dev_set_rx_mode+0x22/0x26
[    1.572768]  [<c15e5a5f>] ? __dev_open+0x96/0xa6
[    1.573768]  [<c15e5c23>] ? __dev_change_flags+0x97/0x10e
[    1.573768]  [<c15e5cfe>] ? dev_change_flags+0x13/0x3f
[    1.574768]  [<c1acfe6f>] ? ip_auto_config+0x160/0xcf8
[    1.574768]  [<c1393c86>] ? extract_entropy+0x45/0x71
[    1.575768]  [<c1059e35>] ? get_parent_ip+0xb/0x31
[    1.576768]  [<c16aa6b7>] ? sub_preempt_count+0x7c/0x89
[    1.576768]  [<c16a7d24>] ? _raw_spin_unlock+0x1c/0x27
[    1.577768]  [<c1629173>] ? tcp_set_default_congestion_control+0x8c/0x95
[    1.578768]  [<c1001159>] ? do_one_initcall+0x71/0x114
[    1.578768]  [<c1acfd0f>] ? root_nfs_parse_addr+0x91/0x91
[    1.579767]  [<c1a9c7ab>] ? kernel_init+0xab/0x11d
[    1.580767]  [<c1a9c700>] ? start_kernel+0x301/0x301
[    1.581767]  [<c16acfb6>] ? kernel_thread_helper+0x6/0xd
[    1.582767] Rebooting in 1 seconds..
  # KVM session ended normally.


> -		ndev.ops = &tap_ops;
> +	ndev->mode = params->mode;
> +	if (ndev->mode == NET_MODE_TAP) {
> +		virtio_net__tap_init(params, ndev);
> +		ndev->ops = &tap_ops;
>  	} else {
> -		ndev.info.host_ip		= ntohl(inet_addr(params->host_ip));
> -		ndev.info.guest_ip		= ntohl(inet_addr(params->guest_ip));
> -		ndev.info.guest_netmask		= ntohl(inet_addr("255.255.255.0"));
> -		uip_init(&ndev.info);
> -		ndev.ops = &uip_ops;
> +		ndev->info.host_ip		= ntohl(inet_addr(params->host_ip));
> +		ndev->info.guest_ip		= ntohl(inet_addr(params->guest_ip));
> +		ndev->info.guest_netmask	= ntohl(inet_addr("255.255.255.0"));
> +		ndev->info.buf_nr		= 20,
> +		uip_init(&ndev->info);
> +		ndev->ops = &uip_ops;
>  	}
>  
> -	virtio_pci__init(kvm, &ndev.vpci, &ndev, PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET);
> -	ndev.vpci.ops = (struct virtio_pci_ops) {
> +	virtio_pci__init(kvm, &ndev->vpci, ndev, PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET);
> +	ndev->vpci.ops = (struct virtio_pci_ops) {
>  		.set_config		= set_config,
>  		.get_config		= get_config,
>  		.get_host_features	= get_host_features,
> @@ -396,9 +409,9 @@ void virtio_net__init(const struct virtio_net_parameters *params)
>  		.get_size_vq		= get_size_vq,
>  	};
>  
> -	virtio_net__io_thread_init(params->kvm);
> +	virtio_net__io_thread_init(params->kvm, ndev);
>  
> -	ndev.compat_id = compat__add_message("virtio-net device was not detected",
> +	ndev->compat_id = compat__add_message("virtio-net device was not detected",
>  						"While you have requested a virtio-net device, "
>  						"the guest kernel didn't seem to detect it.\n"
>  						"Please make sure that the kernel was compiled "


-- 
Asias He

  parent reply	other threads:[~2011-09-26 11:58 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-25 11:11 [PATCH v2] kvm tools: Support multiple net devices Sasha Levin
2011-09-26  6:10 ` Pekka Enberg
2011-09-26 11:57 ` Asias He [this message]
2011-09-26 11:59   ` Sasha Levin
2011-09-26 12:11     ` Asias He
2011-09-26 12:14       ` Sasha Levin
2011-09-26 12:22         ` Asias He
2011-09-26 14:54   ` Pekka Enberg
2011-09-26 15:05     ` Asias He
2011-09-26 16:21     ` Avi Kivity
2011-09-26 16:37       ` Sasha Levin
2011-09-26 16:46         ` Pekka Enberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E8068C7.7080009@gmail.com \
    --to=asias.hejun@gmail.com \
    --cc=gorcunov@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=levinsasha928@gmail.com \
    --cc=mingo@elte.hu \
    --cc=penberg@cs.helsinki.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.