Skip to contentSkip to conversation

9p Virtualization Transports

RFC In review Eric Van Hensbergen 8 participants 17 messages Aug 28, 2007 – Sep 3, 2007

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

This patch set contains a set of virtualization transports for the 9p file system intended to provide a mechanism for guests to access a portion of the hosts name space without having to go through a virtualized network.

Shared memory based transports are provided for lguest using a variation of the lguest console code and for KVM using a synthetic PCI device. The patches to the qemu portion of the latter will be posted to the kvm-devel list later today.

Also provided is a much older hack implementation which was used on XenPPC to communicated between Dom0 and DomU as part of the PROSE
(http://www.research.ibm.com/prose) and Libra projects. It is not our intent to push the Xen shared memory transport into the kernel, but we are providing it in this patch-set for historical reference.

The lguest and kvm transports are functional, but we are still working out remaining bugs and need to spend some time focusing on performance issues. I wanted to send out this "preview" patch set to the community to solicit ideas on things we can do differently/better.

-eric

#1 lore raw

RFC 1/1 9p: Make transports dynamic

From: Eric Van Hensbergen <ericvh@opteron.(none)>

This patch abstracts out the interfaces to underlying transports so that new transports can be added as modules. This should also allow kernel configuration of transports without ifdef-hell.

---
 Documentation/filesystems/9p.txt |    8 +-
 fs/9p/v9fs.c                     |  149 +++++++-------
 fs/9p/v9fs.h                     |   15 +--
 fs/9p/vfs_super.c                |   19 +--
 include/net/9p/client.h          |    4 +-
 include/net/9p/conn.h            |    4 +-
 include/net/9p/transport.h       |   25 ++-
 net/9p/Kconfig                   |   10 +
 net/9p/Makefile                  |    5 +-
 net/9p/client.c                  |    2 +-
 net/9p/mux.c                     |    4 +-
 net/9p/trans_fd.c                |  419 ++++++++++++++++++++++++--------------
 12 files changed, 379 insertions(+), 285 deletions(-)
Documentation/filesystems/9p.txt +4 -4
index cda6905..1a5f50d 100644
@@ -35,12 +35,12 @@ For remote file server:
 
 For Plan 9 From User Space applications (http://swtch.com/plan9)
 
-	mount -t 9p `namespace`/acme /mnt/9 -o proto=unix,uname=$USER
+	mount -t 9p `namespace`/acme /mnt/9 -o trans=unix,uname=$USER
 
 OPTIONS
 =======
 
-  proto=name	select an alternative transport.  Valid options are
+  trans=name	select an alternative transport.  Valid options are
   		currently:
  			unix - specifying a named pipe mount point
  			tcp  - specifying a normal TCP/IP connection
@@ -68,9 +68,9 @@ OPTIONS
 			0x40 = display transport debug
 			0x80 = display allocation debug
 
-  rfdno=n	the file descriptor for reading with proto=fd
+  rfdno=n	the file descriptor for reading with trans=fd
 
-  wfdno=n	the file descriptor for writing with proto=fd
+  wfdno=n	the file descriptor for writing with trans=fd
 
   maxdata=n	the number of bytes to use for 9p packet payload (msize)
 
fs/9p/v9fs.c +72 -77

240 lines not on this page · raw message

fs/9p/v9fs.h +2 -13
index abc4b16..7eb135c 100644
@@ -31,31 +31,20 @@ struct v9fs_session_info {
 	unsigned int maxdata;
 	unsigned char extended;	/* set to 1 if we are using UNIX extensions */
 	unsigned char nodev;	/* set to 1 if no disable device mapping */
-	unsigned short port;	/* port to connect to */
 	unsigned short debug;	/* debug level */
-	unsigned short proto;	/* protocol to use */
 	unsigned int afid;	/* authentication fid */
-	unsigned int rfdno;	/* read file descriptor number */
-	unsigned int wfdno;	/* write file descriptor number */
 	unsigned int cache;	/* cache mode */
 
+	char *options;		/* copy of mount options */
 	char *name;		/* user name to mount as */
 	char *remotename;	/* name of remote hierarchy being mounted */
 	unsigned int uid;	/* default uid/muid for legacy support */
 	unsigned int gid;	/* default gid for legacy support */
-
+	struct p9_trans_module *trans; /* 9p transport */
 	struct p9_client *clnt;	/* 9p client */
 	struct dentry *debugfs_dir;
 };
 
-/* possible values of ->proto */
-enum {
-	PROTO_TCP,
-	PROTO_UNIX,
-	PROTO_FD,
-	PROTO_PCI,
-};
-
 /* possible values of ->cache */
 /* eventually support loose, tight, time, session, default always none */
 enum {
fs/9p/vfs_super.c +1 -18
index ba90437..bb0cef9 100644
@@ -216,24 +216,7 @@ static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt)
 {
 	struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info;
 
-	if (v9ses->debug != 0)
-		seq_printf(m, ",debug=%x", v9ses->debug);
-	if (v9ses->port != V9FS_PORT)
-		seq_printf(m, ",port=%u", v9ses->port);
-	if (v9ses->maxdata != 9000)
-		seq_printf(m, ",msize=%u", v9ses->maxdata);
-	if (v9ses->afid != ~0)
-		seq_printf(m, ",afid=%u", v9ses->afid);
-	if (v9ses->proto == PROTO_UNIX)
-		seq_puts(m, ",proto=unix");
-	if (v9ses->extended == 0)
-		seq_puts(m, ",noextend");
-	if (v9ses->nodev == 1)
-		seq_puts(m, ",nodevmap");
-	seq_printf(m, ",name=%s", v9ses->name);
-	seq_printf(m, ",aname=%s", v9ses->remotename);
-	seq_printf(m, ",uid=%u", v9ses->uid);
-	seq_printf(m, ",gid=%u", v9ses->gid);
+	seq_printf(m, "%s", v9ses->options);
 	return 0;
 }
 
include/net/9p/client.h +2 -2
index d65ed7c..0adafdb 100644
@@ -29,7 +29,7 @@ struct p9_client {
 	spinlock_t lock; /* protect client structure */
 	int msize;
 	unsigned char dotu;
-	struct p9_transport *trans;
+	struct p9_trans *trans;
 	struct p9_conn *conn;
 
 	struct p9_idpool *fidpool;
@@ -52,7 +52,7 @@ struct p9_fid {
 	struct list_head dlist;	/* list of all fids attached to a dentry */
 };
 
-struct p9_client *p9_client_create(struct p9_transport *trans, int msize,
+struct p9_client *p9_client_create(struct p9_trans *trans, int msize,
 								int dotu);
 void p9_client_destroy(struct p9_client *clnt);
 void p9_client_disconnect(struct p9_client *clnt);
include/net/9p/conn.h +2 -2
index 583b6a2..756d878 100644
@@ -42,8 +42,8 @@ struct p9_req;
  */
 typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a);
 
-struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize,
-	unsigned char *dotu);
+struct p9_conn *p9_conn_create(struct p9_trans *trans, int msize,
+							unsigned char *dotu);
 void p9_conn_destroy(struct p9_conn *);
 int p9_conn_rpc(struct p9_conn *m, struct p9_fcall *tc, struct p9_fcall **rc);
 
include/net/9p/transport.h +15 -10
index 462d422..7c68b3e 100644
@@ -26,24 +26,29 @@
 #ifndef NET_9P_TRANSPORT_H
 #define NET_9P_TRANSPORT_H
 
-enum p9_transport_status {
+enum p9_trans_status {
 	Connected,
 	Disconnected,
 	Hung,
 };
 
-struct p9_transport {
-	enum p9_transport_status status;
+struct p9_trans {
+	enum p9_trans_status status;
 	void *priv;
+	int (*write) (struct p9_trans *, void *, int);
+	int (*read) (struct p9_trans *, void *, int);
+	void (*close) (struct p9_trans *);
+	unsigned int (*poll)(struct p9_trans *, struct poll_table_struct *);
+};
 
-	int (*write) (struct p9_transport *, void *, int);
-	int (*read) (struct p9_transport *, void *, int);
-	void (*close) (struct p9_transport *);
-	unsigned int (*poll)(struct p9_transport *, struct poll_table_struct *);
+struct p9_trans_module {
+	struct list_head list;
+	char *name;		/* name of transport */
+	int maxsize;		/* max message size of transport */
+	int def;		/* this transport should be default */
+	struct p9_trans * (*create)(const char *devname, char *options);
 };
 
-struct p9_transport *p9_trans_create_tcp(const char *addr, int port);
-struct p9_transport *p9_trans_create_unix(const char *addr);
-struct p9_transport *p9_trans_create_fd(int rfd, int wfd);
+void v9fs_register_trans(struct p9_trans_module *m);
 
 #endif /* NET_9P_TRANSPORT_H */
net/9p/Kconfig +10 -0
index 66821cd..09566ae 100644
@@ -13,6 +13,16 @@ menuconfig NET_9P
 
 	  If unsure, say N.
 
+config NET_9P_FD
+	depends on NET_9P
+	default y if NET_9P
+	tristate "9P File Descriptor Transports (Experimental)"
+	help
+	  This builds support for file descriptor transports for 9p
+	  which includes support for TCP/IP, named pipes, or passed
+	  file descriptors.  TCP/IP is the default transport for 9p,
+	  so if you are going to use 9p, you'll likely want this.  
+
 config NET_9P_DEBUG
 	bool "Debug information"
 	depends on NET_9P
net/9p/Makefile +4 -1
index 85b3a78..7b2a67a 100644
@@ -1,8 +1,8 @@
 obj-$(CONFIG_NET_9P) := 9pnet.o
+obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
 
 9pnet-objs := \
 	mod.o \
-	trans_fd.o \
 	mux.o \
 	client.o \
 	conv.o \
@@ -11,3 +11,6 @@ obj-$(CONFIG_NET_9P) := 9pnet.o
 	util.o \
 
 9pnet-$(CONFIG_SYSCTL) += sysctl.o
+
+9pnet_fd-objs := \
+	trans_fd.o \
net/9p/client.c +1 -1
index cb17075..e161012 100644
@@ -38,7 +38,7 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt);
 static void p9_fid_destroy(struct p9_fid *fid);
 static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu);
 
-struct p9_client *p9_client_create(struct p9_transport *trans, int msize,
+struct p9_client *p9_client_create(struct p9_trans *trans, int msize,
 								   int dotu)
 {
 	int err, n;
net/9p/mux.c +2 -2
index 5d70558..934e2ea 100644
@@ -71,7 +71,7 @@ struct p9_conn {
 	struct p9_mux_poll_task *poll_task;
 	int msize;
 	unsigned char *extended;
-	struct p9_transport *trans;
+	struct p9_trans *trans;
 	struct p9_idpool *tagpool;
 	int err;
 	wait_queue_head_t equeue;
@@ -271,7 +271,7 @@ static void p9_mux_poll_stop(struct p9_conn *m)
  * @msize - maximum message size
  * @extended - pointer to the extended flag
  */
-struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize,
+struct p9_conn *p9_conn_create(struct p9_trans *trans, int msize,
 				    unsigned char *extended)
 {
 	int i, n;
net/9p/trans_fd.c +264 -155

492 lines not on this page · raw message

Signature · 1 line
1.5.0.2.gfbe3d-dirty
#2 lore raw

RFC 1/1 9p: add KVM/QEMU pci transport

From: Latchesar Ionkov <[email protected]>

This adds a shared memory transport for a synthetic 9p device for paravirtualized file system support under KVM/QEMU.

---
 Documentation/filesystems/9p.txt |    2 +
 net/9p/Kconfig                   |   10 ++-
 net/9p/Makefile                  |    4 +
 net/9p/trans_pci.c               |  295 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 310 insertions(+), 1 deletions(-)
 create mode 100644 net/9p/trans_pci.c
Documentation/filesystems/9p.txt +2 -0
index 1a5f50d..e1879bd 100644
@@ -46,6 +46,8 @@ OPTIONS
  			tcp  - specifying a normal TCP/IP connection
  			fd   - used passed file descriptors for connection
                                 (see rfdno and wfdno)
+			pci  - use a PCI pseudo device for 9p communication
+				over shared memory between a guest and host
 
   uname=name	user name to attempt mount as on the remote server.  The
   		server may override or ignore this value.  Certain user
net/9p/Kconfig +9 -1
index 09566ae..8517560 100644
@@ -16,13 +16,21 @@ menuconfig NET_9P
 config NET_9P_FD
 	depends on NET_9P
 	default y if NET_9P
-	tristate "9P File Descriptor Transports (Experimental)"
+	tristate "9p File Descriptor Transports (Experimental)"
 	help
 	  This builds support for file descriptor transports for 9p
 	  which includes support for TCP/IP, named pipes, or passed
 	  file descriptors.  TCP/IP is the default transport for 9p,
 	  so if you are going to use 9p, you'll likely want this.  
 
+config NET_9P_PCI
+	depends on NET_9P
+	tristate "9p PCI Shared Memory Transport (Experimental)"
+	help
+	  This builds support for a PCI psuedo-device currently available
+	  under KVM/QEMU which allows for 9p transactions over shared
+	  memory between the guest and the host.
+
 config NET_9P_DEBUG
 	bool "Debug information"
 	depends on NET_9P
net/9p/Makefile +4 -0
index 7b2a67a..26ce89d 100644
@@ -1,5 +1,6 @@
 obj-$(CONFIG_NET_9P) := 9pnet.o
 obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
+obj-$(CONFIG_NET_9P_PCI) += 9pnet_pci.o
 
 9pnet-objs := \
 	mod.o \
@@ -14,3 +15,6 @@ obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
 
 9pnet_fd-objs := \
 	trans_fd.o \
+
+9pnet_pci-objs := \
+	trans_pci.o \
net/9p/trans_pci.c new file +295 -0

295 lines not on this page · raw message

Signature · 1 line
1.5.0.2.gfbe3d-dirty
#3 lore raw

RFC 1/1 9p: add lguest transport

From: Eric Van Hensbergen <ericvh@opteron.(none)>

This adds a transport to 9p for communicating between guest and host domains on lguest. Currently, the host-side proxies the communication to a socket connected to the actual server. The transport is based heavily on the existing console code.

A better integrated server component which eliminates some of the copy overhead is in progress and will look less like the existing console code.

---
 Documentation/filesystems/9p.txt |    2 +
 Documentation/lguest/lguest.c    |  127 ++++++++++++++++
 fs/9p/v9fs.c                     |    2 +-
 include/linux/lguest_launcher.h  |    1 +
 net/9p/Kconfig                   |    7 +
 net/9p/Makefile                  |    4 +
 net/9p/trans_lg.c                |  303 ++++++++++++++++++++++++++++++++++++++
 7 files changed, 445 insertions(+), 1 deletions(-)
 create mode 100644 net/9p/trans_lg.c
Documentation/filesystems/9p.txt +2 -0
index e1879bd..1a3342f 100644
@@ -48,6 +48,8 @@ OPTIONS
                                 (see rfdno and wfdno)
 			pci  - use a PCI pseudo device for 9p communication
 				over shared memory between a guest and host
+ 			lg   - use a lguest 9p channel for communication
+				over shared memory between a guest and host
 
   uname=name	user name to attempt mount as on the remote server.  The
   		server may override or ignore this value.  Certain user
Documentation/lguest/lguest.c +127 -0

151 lines not on this page · raw message

fs/9p/v9fs.c +1 -1
index 08d880f..b39123b 100644
@@ -244,7 +244,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
 		v9ses->maxdata = v9ses->trans->maxsize-P9_IOHDRSZ;
 
 	v9ses->clnt = p9_client_create(trans, v9ses->maxdata+P9_IOHDRSZ,
-		v9ses->extended);
+							v9ses->extended);
 
 	if (IS_ERR(v9ses->clnt)) {
 		retval = PTR_ERR(v9ses->clnt);
include/linux/lguest_launcher.h +1 -0
index 6416705..9170046 100644
@@ -90,6 +90,7 @@ struct lguest_device_desc {
 #define LGUEST_DEVICE_T_CONSOLE	1
 #define LGUEST_DEVICE_T_NET	2
 #define LGUEST_DEVICE_T_BLOCK	3
+#define LGUEST_DEVICE_T_9P	9
 
 	/* The specific features of this device: these depends on device type
 	 * except for LGUEST_DEVICE_F_RANDOMNESS. */
net/9p/Kconfig +7 -0
index 8517560..fab7bb9 100644
@@ -31,6 +31,13 @@ config NET_9P_PCI
 	  under KVM/QEMU which allows for 9p transactions over shared
 	  memory between the guest and the host.
 
+config NET_9P_LG
+	depends on NET_9P
+	tristate "9p Lguest Transport (Experimental)"
+	help
+	  This builds support for a transport between an Lguest
+	  guest partition and the host partition.
+
 config NET_9P_DEBUG
 	bool "Debug information"
 	depends on NET_9P
net/9p/Makefile +4 -0
index 26ce89d..80a4227 100644
@@ -1,6 +1,7 @@
 obj-$(CONFIG_NET_9P) := 9pnet.o
 obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
 obj-$(CONFIG_NET_9P_PCI) += 9pnet_pci.o
+obj-$(CONFIG_NET_9P_LG) += 9pnet_lg.o
 
 9pnet-objs := \
 	mod.o \
@@ -18,3 +19,6 @@ obj-$(CONFIG_NET_9P_PCI) += 9pnet_pci.o
 
 9pnet_pci-objs := \
 	trans_pci.o \
+
+9pnet_lg-objs := \
+	trans_lg.o \
net/9p/trans_lg.c new file +303 -0

303 lines not on this page · raw message

Signature · 1 line
1.5.0.2.gfbe3d-dirty
#4 lore raw

[REFERENCE ONLY] 9p: add shared memory transport

From: Eric Van Hensbergen <ericvh@opteron.(none)>

This adds a 9p generic shared memory transport which has been used to communicate between Dom0 and DomU under Xen as part of the Libra and PROSE projects (http://www.research.ibm.com/prose).

Parts of the code are a horrible hack, but may be useful as reference for constructing (or how not to construct) a poll-driven shared-memory driver for Xen (or other purposes).

---
 net/9p/Kconfig     |    7 +
 net/9p/Makefile    |    4 +
 net/9p/trans_shm.c |  378 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 389 insertions(+), 0 deletions(-)
 create mode 100644 net/9p/trans_shm.c
net/9p/Kconfig +7 -0
index fab7bb9..a1b55e8 100644
@@ -38,6 +38,13 @@ config NET_9P_LG
 	  This builds support for a transport between an Lguest
 	  guest partition and the host partition.
 
+config NET_9P_SHM
+	depends on NET_9P
+	tristate "9p Shared Memory Transport (Experimental)"
+	help
+	  This builds support for a shared memory transport which
+	  can be used on XenPPC to mount 9p between DomU and Dom0.
+
 config NET_9P_DEBUG
 	bool "Debug information"
 	depends on NET_9P
net/9p/Makefile +4 -0
index 80a4227..e7a036a 100644
@@ -2,6 +2,7 @@ obj-$(CONFIG_NET_9P) := 9pnet.o
 obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
 obj-$(CONFIG_NET_9P_PCI) += 9pnet_pci.o
 obj-$(CONFIG_NET_9P_LG) += 9pnet_lg.o
+obj-$(CONFIG_NET_9P_SHM) += 9pnet_shm.o
 
 9pnet-objs := \
 	mod.o \
@@ -22,3 +23,6 @@ obj-$(CONFIG_NET_9P_LG) += 9pnet_lg.o
 
 9pnet_lg-objs := \
 	trans_lg.o \
+
+9pnet_shm-objs := \
+	trans_shm.o \
net/9p/trans_shm.c new file +378 -0

378 lines not on this page · raw message

Signature · 1 line
1.5.0.2.gfbe3d-dirty
#5 lore raw

Re: [RFC] 9p: add KVM/QEMU pci transport

In reply to Eric Van Hensbergen

net/9p/Kconfig menuconfig NET_9P · line 28

Quoted 3 lines · Eric Van Hensbergen
net/9p/Kconfig +3 -0
+config NET_9P_PCI
+	depends on NET_9P
+	tristate "9p PCI Shared Memory Transport (Experimental)"

shouldn't this depend on CONFIG_PCI?

#6 lore raw

Re: [kvm-devel] [RFC] 9p: add KVM/QEMU pci transport

In reply to Eric Van Hensbergen
Quoted 2 lines · Eric Van Hensbergen

This adds a shared memory transport for a synthetic 9p device for paravirtualized file system support under KVM/QEMU.

Nice driver. I'm hoping we can do a virtio driver using a similar concept.

net/9p/trans_pci.c line 44

Quoted 2 lines
net/9p/trans_pci.c new file +2 -0
+#define PCI_VENDOR_ID_9P	0x5002
+#define PCI_DEVICE_ID_9P	0x000D

Where do these numbers come from? Can we be sure they don't conflict with actual hardware?

net/9p/trans_pci.c line 57

Quoted 10 lines
net/9p/trans_pci.c new file +10 -0
+struct p9pci_trans {
+	struct pci_dev		*pdev;
+	void __iomem		*ioaddr;
+	void __iomem		*tx;
+	void __iomem		*rx;
+	int			irq;
+	int			pos;
+	int			len;
+	wait_queue_head_t	wait;
+};

I would expect the data structure to contain an embedded struct p9_trans, which is how most drivers work nowadays.

Quoted 1 line

+static struct p9pci_trans *p9pci_trans; /* single channel for now */

As a result, it should be easier to get rid of this global. My feeling is that it really should not be here.

net/9p/trans_pci.c line 67

Quoted 3 lines
net/9p/trans_pci.c new file +3 -0
+static irqreturn_t p9pci_interrupt(int irq, void *dev)
+{
+	p9pci_trans = dev;

This can simply use a local variable.

net/9p/trans_pci.c line 68

Quoted 1 line
net/9p/trans_pci.c new file +1 -0
+	p9pci_trans->len = le32_to_cpu(readl(p9pci_trans->rx));

readl implies le32_to_cpu. Doing it twice on a PCI device is broken on big-endian hardware.

net/9p/trans_pci.c line 71

Quoted 3 lines
net/9p/trans_pci.c new file +3 -0
+	P9_DPRINTK(P9_DEBUG_TRANS, "%p len %d\n", p9pci_trans->pdev,
+							p9pci_trans->len);
+	iowrite32(0, p9pci_trans->ioaddr + 4);

Also, you should not mix iowriteXX/ioreadXX and writeX/readX calls in one driver. Since you use pci_iomap, iowriteXX/ioreadXX are the correct functions.

Quoted 20 lines
net/9p/trans_pci.c new file +20 -0
+	wake_up_interruptible(&p9pci_trans->wait);
+	return IRQ_HANDLED;
+}
+
+static int p9pci_read(struct p9_trans *trans, void *v, int len)
+{
+	struct p9pci_trans *ts;
+
+	if (!trans || trans->status == Disconnected || !trans->priv)
+		return -EREMOTEIO;
+
+	ts = trans->priv;
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len %d\n",
+						trans, ts->rx, ts->tx, v, len);
+	if (len > ts->len)
+		len = ts->len;
+
+	if (len) {
+		memcpy_fromio(v, ts->rx, len);

net/9p/trans_pci.c line 101

Quoted 10 lines
net/9p/trans_pci.c new file +10 -0
+		ts->len = 0;
+		/* let the host knows the message is consumed */
+		writel(0, ts->rx);
+		iowrite32(0, p9pci_trans->ioaddr + 4);
+		P9_DPRINTK(P9_DEBUG_TRANS, "zero rxlen %d txlen %d\n",
+						readl(ts->rx), readl(ts->tx));
+	}
+
+	return len;
+}

I would expect memcpy_fromio and memcpy_toio to be relatively inefficient compared to virtual DMA, depending on the hypervisor. Do you have plans to change that, or did you have specific reasons to do the memcpy here?

net/9p/trans_pci.c line 118

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+	P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len %d\n",
+						trans, ts->rx, ts->tx, v, len);
+	P9_DPRINTK(P9_DEBUG_TRANS, "rxlen %d\n", readl(ts->rx));
+	if (readb(ts->tx) != 0)
+		return 0;
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "tx addr %p io addr %p\n", ts->tx,
+								ts->ioaddr);

All these P9_DPRINTK statements somewhat limit readability. I would suggest you kill them as soon as the driver is considered stable.

net/9p/trans_pci.c line 185

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+static int __devinit p9pci_probe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
+{
+	int err;
+	u8 pci_rev;
+
+	if (p9pci_trans)
+		return -1;

probe should return -EBUSY or similar, not -1.

net/9p/trans_pci.c line 192

Quoted 6 lines
net/9p/trans_pci.c new file +6 -0
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
+
+	if (pdev->vendor == PCI_VENDOR_ID_9P &&
+	    pdev->device == PCI_DEVICE_ID_9P)
+		printk(KERN_INFO "pci dev %s (id %04x:%04x rev %02x) is a 9P\n",
+		       pci_name(pdev), pdev->vendor, pdev->device, pci_rev);

You wouldn't be here for a different vendor/device code, so the check is bogus.

net/9p/trans_pci.c line 196

Quoted 3 lines
net/9p/trans_pci.c new file +3 -0
+	P9_DPRINTK(P9_DEBUG_TRANS, "%p\n", pdev);
+	p9pci_trans = kzalloc(sizeof(*p9pci_trans), GFP_KERNEL);
+	p9pci_trans->irq = -1;

Use NO_IRQ to signify an invalid irq.

Quoted 9 lines
net/9p/trans_pci.c new file +9 -0
+	init_waitqueue_head(&p9pci_trans->wait);
+	err = pci_enable_device(pdev);
+	if (err)
+		goto error;
+
+	p9pci_trans->pdev = pdev;
+	err = pci_request_regions(pdev, "9p");
+	if (err)
+		goto error;

net/9p/trans_pci.c line 215

Quoted 10 lines
net/9p/trans_pci.c new file +10 -0
+
+	p9pci_trans->ioaddr = pci_iomap(pdev, 0, 8);
+	if (!p9pci_trans->ioaddr) {
+		P9_DPRINTK(P9_DEBUG_ERROR, "Cannot remap MMIO, aborting\n");
+		err = -EIO;
+		goto error;
+	}
+
+	p9pci_trans->tx = pci_iomap(pdev, 1, 0x20000);
+	p9pci_trans->rx = pci_iomap(pdev, 2, 0x20000);

New code should use pcim_iomap, you don't need the unmapping code any more then.

Quoted 15 lines
net/9p/trans_pci.c new file +15 -0
+	pci_set_drvdata(pdev, p9pci_trans);
+	err = request_irq(pdev->irq, &p9pci_interrupt, 0, "p9pci", p9pci_trans);
+	if (err)
+		goto error;
+
+	p9pci_trans->irq = pdev->irq;
+	return 0;
+
+error:
+	P9_DPRINTK(P9_DEBUG_ERROR, "error %d\n", err);
+	if (p9pci_trans->irq >= 0) {
+		synchronize_irq(p9pci_trans->irq);
+		free_irq(p9pci_trans->irq, p9pci_trans);
+	}
+

net/9p/trans_pci.c line 240

Quoted 10 lines
net/9p/trans_pci.c new file +10 -0
+	if (p9pci_trans->pdev) {
+		pci_release_regions(pdev);
+		pci_iounmap(pdev, p9pci_trans->ioaddr);
+		pci_set_drvdata(pdev, NULL);
+		pci_disable_device(pdev);
+	}
+
+	kfree(p9pci_trans);
+	return -1;
+}

return err;

net/9p/trans_pci.c line 286

Quoted 6 lines
net/9p/trans_pci.c new file +6 -0
+static void __exit p9pci_cleanup_module(void)
+{
+	pci_unregister_driver(&p9pci_driver);
+	printk(KERN_ERR "Removal of 9p transports not implemented\n");
+	BUG();
+}

Not having a cleanup function at all is a much better way of preventing module unload.

	Arnd <><
maintainer
#7 lore raw

Re: [kvm-devel] [RFC] 9p: add KVM/QEMU pci transport

Quoted 5 lines · Arnd Bergmann
Quoted 2 lines · Eric Van Hensbergen

This adds a shared memory transport for a synthetic 9p device for paravirtualized file system support under KVM/QEMU.

Quoted 8 lines

Nice driver. I'm hoping we can do a virtio driver using a similar concept.

net/9p/trans_pci.c line 44

Quoted 2 lines
net/9p/trans_pci.c new file +2 -0
+#define PCI_VENDOR_ID_9P     0x5002
+#define PCI_DEVICE_ID_9P     0x000D

Where do these numbers come from? Can we be sure they don't conflict with actual hardware?

I stole the VENDOR_ID from kvm's hypercall driver. There are no any guarantees that it doesn't conflict with actual hardware. As it was discussed before, there is still no ID assigned for the virtual devices.

Quoted 63 lines

net/9p/trans_pci.c line 57

Quoted 10 lines
net/9p/trans_pci.c new file +10 -0
+struct p9pci_trans {
+     struct pci_dev          *pdev;
+     void __iomem            *ioaddr;
+     void __iomem            *tx;
+     void __iomem            *rx;
+     int                     irq;
+     int                     pos;
+     int                     len;
+     wait_queue_head_t       wait;
+};

I would expect the data structure to contain an embedded struct p9_trans, which is how most drivers work nowadays.

Quoted 1 line

+static struct p9pci_trans *p9pci_trans; /* single channel for now */

As a result, it should be easier to get rid of this global. My feeling is that it really should not be here.

net/9p/trans_pci.c line 67

Quoted 3 lines
net/9p/trans_pci.c new file +3 -0
+static irqreturn_t p9pci_interrupt(int irq, void *dev)
+{
+     p9pci_trans = dev;

This can simply use a local variable.

Quoted 1 line

+ p9pci_trans->len = le32_to_cpu(readl(p9pci_trans->rx));

readl implies le32_to_cpu. Doing it twice on a PCI device is broken on big-endian hardware.

net/9p/trans_pci.c line 71

Quoted 3 lines
net/9p/trans_pci.c new file +3 -0
+     P9_DPRINTK(P9_DEBUG_TRANS, "%p len %d\n", p9pci_trans->pdev,
+                                                     p9pci_trans->len);
+     iowrite32(0, p9pci_trans->ioaddr + 4);

Also, you should not mix iowriteXX/ioreadXX and writeX/readX calls in one driver. Since you use pci_iomap, iowriteXX/ioreadXX are the correct functions.

Quoted 26 lines
net/9p/trans_pci.c new file +26 -0
+     wake_up_interruptible(&p9pci_trans->wait);
+     return IRQ_HANDLED;
+}
+
+static int p9pci_read(struct p9_trans *trans, void *v, int len)
+{
+     struct p9pci_trans *ts;
+
+     if (!trans || trans->status == Disconnected || !trans->priv)
+             return -EREMOTEIO;
+
+     ts = trans->priv;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len %d\n",
+                                             trans, ts->rx, ts->tx, v, len);
+     if (len > ts->len)
+             len = ts->len;
+
+     if (len) {
+             memcpy_fromio(v, ts->rx, len);
+             ts->len = 0;
+             /* let the host knows the message is consumed */
+             writel(0, ts->rx);
+             iowrite32(0, p9pci_trans->ioaddr + 4);
+             P9_DPRINTK(P9_DEBUG_TRANS, "zero rxlen %d txlen %d\n",
+                                             readl(ts->rx), readl(ts->tx));
Quoted 8 lines

net/9p/trans_pci.c line 101

Quoted 4 lines
net/9p/trans_pci.c new file +4 -0
+     }
+
+     return len;
+}

I would expect memcpy_fromio and memcpy_toio to be relatively inefficient compared to virtual DMA, depending on the hypervisor. Do you have plans to change that, or did you have specific reasons to do the memcpy here?

No specific reasons. We wanted to start with simple and easy transport and make things work before we start optimizing it. There are many areas where the transport can be improved, using virtual DMA sounds like a good suggestion.

Quoted 91 lines

net/9p/trans_pci.c line 118

Quoted 9 lines
net/9p/trans_pci.c new file +8 -0
+     P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len %d\n",
+                                             trans, ts->rx, ts->tx, v, len);
+     P9_DPRINTK(P9_DEBUG_TRANS, "rxlen %d\n", readl(ts->rx));
+     if (readb(ts->tx) != 0)
+             return 0;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "tx addr %p io addr %p\n", ts->tx,
+                                                             ts->ioaddr);

All these P9_DPRINTK statements somewhat limit readability. I would suggest you kill them as soon as the driver is considered stable.

net/9p/trans_pci.c line 185

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+static int __devinit p9pci_probe(struct pci_dev *pdev,
+             const struct pci_device_id *ent)
+{
+     int err;
+     u8 pci_rev;
+
+     if (p9pci_trans)
+             return -1;

probe should return -EBUSY or similar, not -1.

net/9p/trans_pci.c line 192

Quoted 6 lines
net/9p/trans_pci.c new file +6 -0
+     pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
+
+     if (pdev->vendor == PCI_VENDOR_ID_9P &&
+         pdev->device == PCI_DEVICE_ID_9P)
+             printk(KERN_INFO "pci dev %s (id %04x:%04x rev %02x) is a 9P\n",
+                    pci_name(pdev), pdev->vendor, pdev->device, pci_rev);

You wouldn't be here for a different vendor/device code, so the check is bogus.

net/9p/trans_pci.c line 196

Quoted 3 lines
net/9p/trans_pci.c new file +3 -0
+     P9_DPRINTK(P9_DEBUG_TRANS, "%p\n", pdev);
+     p9pci_trans = kzalloc(sizeof(*p9pci_trans), GFP_KERNEL);
+     p9pci_trans->irq = -1;

Use NO_IRQ to signify an invalid irq.

Quoted 9 lines
net/9p/trans_pci.c new file +9 -0
+     init_waitqueue_head(&p9pci_trans->wait);
+     err = pci_enable_device(pdev);
+     if (err)
+             goto error;
+
+     p9pci_trans->pdev = pdev;
+     err = pci_request_regions(pdev, "9p");
+     if (err)
+             goto error;

net/9p/trans_pci.c line 215

Quoted 10 lines
net/9p/trans_pci.c new file +10 -0
+
+     p9pci_trans->ioaddr = pci_iomap(pdev, 0, 8);
+     if (!p9pci_trans->ioaddr) {
+             P9_DPRINTK(P9_DEBUG_ERROR, "Cannot remap MMIO, aborting\n");
+             err = -EIO;
+             goto error;
+     }
+
+     p9pci_trans->tx = pci_iomap(pdev, 1, 0x20000);
+     p9pci_trans->rx = pci_iomap(pdev, 2, 0x20000);

New code should use pcim_iomap, you don't need the unmapping code any more then.

Quoted 15 lines
net/9p/trans_pci.c new file +15 -0
+     pci_set_drvdata(pdev, p9pci_trans);
+     err = request_irq(pdev->irq, &p9pci_interrupt, 0, "p9pci", p9pci_trans);
+     if (err)
+             goto error;
+
+     p9pci_trans->irq = pdev->irq;
+     return 0;
+
+error:
+     P9_DPRINTK(P9_DEBUG_ERROR, "error %d\n", err);
+     if (p9pci_trans->irq >= 0) {
+             synchronize_irq(p9pci_trans->irq);
+             free_irq(p9pci_trans->irq, p9pci_trans);
+     }
+

net/9p/trans_pci.c line 240

Quoted 10 lines
net/9p/trans_pci.c new file +10 -0
+     if (p9pci_trans->pdev) {
+             pci_release_regions(pdev);
+             pci_iounmap(pdev, p9pci_trans->ioaddr);
+             pci_set_drvdata(pdev, NULL);
+             pci_disable_device(pdev);
+     }
+
+     kfree(p9pci_trans);
+     return -1;
+}

return err;

Quoted 9 lines

net/9p/trans_pci.c line 286

Quoted 6 lines
net/9p/trans_pci.c new file +6 -0
+static void __exit p9pci_cleanup_module(void)
+{
+     pci_unregister_driver(&p9pci_driver);
+     printk(KERN_ERR "Removal of 9p transports not implemented\n");
+     BUG();
+}

Not having a cleanup function at all is a much better way of preventing module unload.

Thanks for your comments.

Lucho

#8 lore raw

RE: [Lguest] [kvm-devel] [RFC] 9p: add KVM/QEMU pci transport

Quoted 8 lines
Quoted 8 lines

Nice driver. I'm hoping we can do a virtio driver using a similar concept.

net/9p/trans_pci.c line 44

Quoted 2 lines
net/9p/trans_pci.c new file +2 -0
+#define PCI_VENDOR_ID_9P     0x5002
+#define PCI_DEVICE_ID_9P     0x000D

Where do these numbers come from? Can we be sure they don't conflict

Quoted 7 lines

with

Quoted 1 line

actual hardware?

I stole the VENDOR_ID from kvm's hypercall driver. There are no any guarantees that it doesn't conflict with actual hardware. As it was discussed before, there is still no ID assigned for the virtual devices.

Currently 5002 does not registered to Qumranet nor KVM. We will do something about it pretty soon.

#9 lore raw

Re: [kvm-devel] [RFC] 9p: add KVM/QEMU pci transport

In reply to Arnd Bergmann
Quoted 8 lines · Arnd Bergmann
Quoted 2 lines · Eric Van Hensbergen

This adds a shared memory transport for a synthetic 9p device for paravirtualized file system support under KVM/QEMU.

Nice driver. I'm hoping we can do a virtio driver using a similar concept.

Yes. I'm looking at the patches from Dor now, it should be pretty straight forward. The PCI is interesting in its own right for other (non-virtual) projects we've been playing with....

-eric

#10 lore raw

RE: [kvm-devel] [RFC] 9p: add KVM/QEMU pci transport

Quoted 7 lines
Quoted 6 lines
Quoted 2 lines

This adds a shared memory transport for a synthetic 9p device for paravirtualized file system support under KVM/QEMU.

Nice driver. I'm hoping we can do a virtio driver using a similar concept.

Quoted 5 lines

Yes. I'm looking at the patches from Dor now, it should be pretty straight forward. The PCI is interesting in its own right for other (non-virtual) projects we've been playing with....

-eric

Great, we can add lots of pci bus shared functionality into the kvm_pci_bus.c
--Dor

#11 lore raw

Re: [kvm-devel] [RFC] 9p: add KVM/QEMU pci transport

In reply to Eric Van Hensbergen

I think that it would be nicer to implement the p9 transport on top of virtio instead of directly on top of PCI. I think your PCI transport would make a pretty nice start of a PCI virtio transport though.

Regards,

Anthony Liguori

Quoted 364 lines · Eric Van Hensbergen

From: Latchesar Ionkov <lucho-OnYtXJJ0/[email protected]>

This adds a shared memory transport for a synthetic 9p device for paravirtualized file system support under KVM/QEMU.

---
 Documentation/filesystems/9p.txt |    2 +
 net/9p/Kconfig                   |   10 ++-
 net/9p/Makefile                  |    4 +
 net/9p/trans_pci.c               |  295 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 310 insertions(+), 1 deletions(-)
 create mode 100644 net/9p/trans_pci.c
Documentation/filesystems/9p.txt +2 -0
index 1a5f50d..e1879bd 100644
@@ -46,6 +46,8 @@ OPTIONS
  			tcp  - specifying a normal TCP/IP connection
  			fd   - used passed file descriptors for connection
                                 (see rfdno and wfdno)
+			pci  - use a PCI pseudo device for 9p communication
+				over shared memory between a guest and host
 
   uname=name	user name to attempt mount as on the remote server.  The
   		server may override or ignore this value.  Certain user
net/9p/Kconfig +9 -1
index 09566ae..8517560 100644
@@ -16,13 +16,21 @@ menuconfig NET_9P
 config NET_9P_FD
 	depends on NET_9P
 	default y if NET_9P
-	tristate "9P File Descriptor Transports (Experimental)"
+	tristate "9p File Descriptor Transports (Experimental)"
 	help
 	  This builds support for file descriptor transports for 9p
 	  which includes support for TCP/IP, named pipes, or passed
 	  file descriptors.  TCP/IP is the default transport for 9p,
 	  so if you are going to use 9p, you'll likely want this.  
 
+config NET_9P_PCI
+	depends on NET_9P
+	tristate "9p PCI Shared Memory Transport (Experimental)"
+	help
+	  This builds support for a PCI psuedo-device currently available
+	  under KVM/QEMU which allows for 9p transactions over shared
+	  memory between the guest and the host.
+
 config NET_9P_DEBUG
 	bool "Debug information"
 	depends on NET_9P
net/9p/Makefile +4 -0
index 7b2a67a..26ce89d 100644
@@ -1,5 +1,6 @@
 obj-$(CONFIG_NET_9P) := 9pnet.o
 obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
+obj-$(CONFIG_NET_9P_PCI) += 9pnet_pci.o
 
 9pnet-objs := \
 	mod.o \
@@ -14,3 +15,6 @@ obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
 
 9pnet_fd-objs := \
 	trans_fd.o \
+
+9pnet_pci-objs := \
+	trans_pci.o \
net/9p/trans_pci.c new file +285 -0
new file mode 100644
index 0000000..36ddc5f
@@ -0,0 +1,295 @@
+/*
+ * net/9p/trans_pci.c
+ *
+ * 9P over PCI transport layer. For use with KVM/QEMU.
+ *
+ *  Copyright (C) 2007 by Latchesar Ionkov <lucho-OnYtXJJ0/[email protected]>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to:
+ *  Free Software Foundation
+ *  51 Franklin Street, Fifth Floor
+ *  Boston, MA  02111-1301  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/irq.h>
+#include <linux/poll.h>
+#include <net/9p/9p.h>
+#include <net/9p/transport.h>
+
+#define P9PCI_DRIVER_NAME "9P PCI Device"
+#define P9PCI_DRIVER_VERSION "1"
+
+#define PCI_VENDOR_ID_9P	0x5002
+#define PCI_DEVICE_ID_9P	0x000D
+
+#define MAX_PCI_BUF		(4*1024) /* TODO: Get a number from lucho */
+
+struct p9pci_trans {
+	struct pci_dev		*pdev;
+	void __iomem		*ioaddr;
+	void __iomem		*tx;
+	void __iomem		*rx;
+	int			irq;
+	int			pos;
+	int			len;
+	wait_queue_head_t	wait;
+};
+static struct p9pci_trans *p9pci_trans; /* single channel for now */
+
+static struct pci_device_id p9pci_tbl[] = {
+	{PCI_VENDOR_ID_9P, PCI_DEVICE_ID_9P, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{0,}
+};
+
+static irqreturn_t p9pci_interrupt(int irq, void *dev)
+{
+	p9pci_trans = dev;
+	p9pci_trans->len = le32_to_cpu(readl(p9pci_trans->rx));
+	P9_DPRINTK(P9_DEBUG_TRANS, "%p len %d\n", p9pci_trans->pdev,
+							p9pci_trans->len);
+	iowrite32(0, p9pci_trans->ioaddr + 4);
+	wake_up_interruptible(&p9pci_trans->wait);
+	return IRQ_HANDLED;
+}
+
+static int p9pci_read(struct p9_trans *trans, void *v, int len)
+{
+	struct p9pci_trans *ts;
+
+	if (!trans || trans->status == Disconnected || !trans->priv)
+		return -EREMOTEIO;
+
+	ts = trans->priv;
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len %d\n",
+						trans, ts->rx, ts->tx, v, len);
+	if (len > ts->len)
+		len = ts->len;
+
+	if (len) {
+		memcpy_fromio(v, ts->rx, len);
+		ts->len = 0;
+		/* let the host knows the message is consumed */
+		writel(0, ts->rx);
+		iowrite32(0, p9pci_trans->ioaddr + 4);
+		P9_DPRINTK(P9_DEBUG_TRANS, "zero rxlen %d txlen %d\n",
+						readl(ts->rx), readl(ts->tx));
+	}
+
+	return len;
+}
+
+static int p9pci_write(struct p9_trans *trans, void *v, int len)
+{
+	struct p9pci_trans *ts;
+
+	if (!trans || trans->status == Disconnected || !trans->priv)
+		return -EREMOTEIO;
+
+	ts = trans->priv;
+	P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len %d\n",
+						trans, ts->rx, ts->tx, v, len);
+	P9_DPRINTK(P9_DEBUG_TRANS, "rxlen %d\n", readl(ts->rx));
+	if (readb(ts->tx) != 0)
+		return 0;
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "tx addr %p io addr %p\n", ts->tx,
+								ts->ioaddr);
+	memcpy_toio(ts->tx, v, len);
+	iowrite32(len, ts->ioaddr);
+	return len;
+}
+
+static unsigned int
+p9pci_poll(struct p9_trans *trans, struct poll_table_struct *pt)
+{
+	int ret;
+	struct p9pci_trans *ts;
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "trans %p\n", trans);
+	if (!trans || trans->status != Connected || !trans->priv)
+		return -EREMOTEIO;
+
+	ts = trans->priv;
+	poll_wait(NULL, &ts->wait, pt);
+	ret = 0;
+	if (!readl(ts->tx))
+		ret |= POLLOUT;
+	if (readl(ts->rx))
+		ret |= POLLIN;
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "txlen %d rxlen %d\n", readl(ts->tx),
+								readl(ts->rx));
+	return ret;
+}
+
+/**
+ * p9_sock_close - shutdown socket
+ * @trans: private socket structure
+ *
+ */
+static void p9pci_close(struct p9_trans *trans)
+{
+	P9_DPRINTK(P9_DEBUG_TRANS, "trans %p\n", trans);
+}
+
+static struct p9_trans *p9pci_trans_create(const char *name, char *arg)
+{
+	struct p9_trans *trans;
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "\n");
+	trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
+	if (!trans)
+		return ERR_PTR(-ENOMEM);
+
+	trans->status = Connected;
+	trans->write = p9pci_write;
+	trans->read = p9pci_read;
+	trans->close = p9pci_close;
+	trans->poll = p9pci_poll;
+	trans->priv = p9pci_trans;
+	writel(0, p9pci_trans->tx);
+	writel(0, p9pci_trans->rx);
+
+	return trans;
+}
+
+static int __devinit p9pci_probe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
+{
+	int err;
+	u8 pci_rev;
+
+	if (p9pci_trans)
+		return -1;
+
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
+
+	if (pdev->vendor == PCI_VENDOR_ID_9P &&
+	    pdev->device == PCI_DEVICE_ID_9P)
+		printk(KERN_INFO "pci dev %s (id %04x:%04x rev %02x) is a 9P\n",
+		       pci_name(pdev), pdev->vendor, pdev->device, pci_rev);
+
+	P9_DPRINTK(P9_DEBUG_TRANS, "%p\n", pdev);
+	p9pci_trans = kzalloc(sizeof(*p9pci_trans), GFP_KERNEL);
+	p9pci_trans->irq = -1;
+	init_waitqueue_head(&p9pci_trans->wait);
+	err = pci_enable_device(pdev);
+	if (err)
+		goto error;
+
+	p9pci_trans->pdev = pdev;
+	err = pci_request_regions(pdev, "9p");
+	if (err)
+		goto error;
+
+	p9pci_trans->ioaddr = pci_iomap(pdev, 0, 8);
+	if (!p9pci_trans->ioaddr) {
+		P9_DPRINTK(P9_DEBUG_ERROR, "Cannot remap MMIO, aborting\n");
+		err = -EIO;
+		goto error;
+	}
+
+	p9pci_trans->tx = pci_iomap(pdev, 1, 0x20000);
+	p9pci_trans->rx = pci_iomap(pdev, 2, 0x20000);
+	pci_set_drvdata(pdev, p9pci_trans);
+	err = request_irq(pdev->irq, &p9pci_interrupt, 0, "p9pci", p9pci_trans);
+	if (err)
+		goto error;
+
+	p9pci_trans->irq = pdev->irq;
+	return 0;
+
+error:
+	P9_DPRINTK(P9_DEBUG_ERROR, "error %d\n", err);
+	if (p9pci_trans->irq >= 0) {
+		synchronize_irq(p9pci_trans->irq);
+		free_irq(p9pci_trans->irq, p9pci_trans);
+	}
+
+	if (p9pci_trans->pdev) {
+		pci_release_regions(pdev);
+		pci_iounmap(pdev, p9pci_trans->ioaddr);
+		pci_set_drvdata(pdev, NULL);
+		pci_disable_device(pdev);
+	}
+
+	kfree(p9pci_trans);
+	return -1;
+}
+
+static void __devexit p9pci_remove(struct pci_dev *pdev)
+{
+	P9_DPRINTK(P9_DEBUG_TRANS, "%p\n", pdev);
+	p9pci_trans = pci_get_drvdata(pdev);
+	if (!p9pci_trans)
+		return;
+
+	if (p9pci_trans->irq) {
+		synchronize_irq(p9pci_trans->irq);
+		free_irq(p9pci_trans->irq, p9pci_trans);
+	}
+
+	pci_release_regions(pdev);
+	pci_iounmap(pdev, p9pci_trans->ioaddr);
+	pci_set_drvdata(pdev, NULL);
+	kfree(p9pci_trans);
+	pci_disable_device(pdev);
+}
+
+static struct pci_driver p9pci_driver = {
+	.name		= P9PCI_DRIVER_NAME,
+	.id_table	= p9pci_tbl,
+	.probe		= p9pci_probe,
+	.remove		= __devexit_p(p9pci_remove),
+};
+
+static struct p9_trans_module p9_pci_trans = {
+	.name = "pci",
+	.maxsize = MAX_PCI_BUF,
+	.def = 0,
+	.create = p9pci_trans_create,
+};
+
+static int __init p9pci_init_module(void)
+{
+	v9fs_register_trans(&p9_pci_trans);
+	return pci_register_driver(&p9pci_driver);
+}
+
+static void __exit p9pci_cleanup_module(void)
+{
+	pci_unregister_driver(&p9pci_driver);
+	printk(KERN_ERR "Removal of 9p transports not implemented\n");
+	BUG();

net/9p/trans_pci.c line 295

Quoted 10 lines
net/9p/trans_pci.c new file +10 -0
+}
+
+module_init(p9pci_init_module);
+module_exit(p9pci_cleanup_module);
+
+MODULE_DEVICE_TABLE(pci, p9pci_tbl);
+MODULE_AUTHOR("Latchesar Ionkov <lucho-OnYtXJJ0/[email protected]>");
+MODULE_DESCRIPTION(P9PCI_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(P9PCI_DRIVER_VERSION);

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

maintainer
#12 lore raw

Re: [V9fs-developer] [kvm-devel] [RFC] 9p: add KVM/QEMU pci transport

That's also in our plans. There was no virtio support in KVM when I started working in the transport.

Thanks,
Lucho

Quoted 386 lines · Anthony Liguori

I think that it would be nicer to implement the p9 transport on top of virtio instead of directly on top of PCI. I think your PCI transport would make a pretty nice start of a PCI virtio transport though.

Regards,

Anthony Liguori

Quoted 364 lines · Eric Van Hensbergen

From: Latchesar Ionkov <lucho-OnYtXJJ0/[email protected]>

This adds a shared memory transport for a synthetic 9p device for paravirtualized file system support under KVM/QEMU.

---
 Documentation/filesystems/9p.txt |    2 +
 net/9p/Kconfig                   |   10 ++-
 net/9p/Makefile                  |    4 +
 net/9p/trans_pci.c               |  295 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 310 insertions(+), 1 deletions(-)
 create mode 100644 net/9p/trans_pci.c
Documentation/filesystems/9p.txt +2 -0
index 1a5f50d..e1879bd 100644
@@ -46,6 +46,8 @@ OPTIONS
                      tcp  - specifying a normal TCP/IP connection
                      fd   - used passed file descriptors for connection
                                 (see rfdno and wfdno)
+                     pci  - use a PCI pseudo device for 9p communication
+                             over shared memory between a guest and host
 
   uname=name user name to attempt mount as on the remote server.  The
              server may override or ignore this value.  Certain user
net/9p/Kconfig +9 -1
index 09566ae..8517560 100644
@@ -16,13 +16,21 @@ menuconfig NET_9P
 config NET_9P_FD
      depends on NET_9P
      default y if NET_9P
-     tristate "9P File Descriptor Transports (Experimental)"
+     tristate "9p File Descriptor Transports (Experimental)"
      help
        This builds support for file descriptor transports for 9p
        which includes support for TCP/IP, named pipes, or passed
        file descriptors.  TCP/IP is the default transport for 9p,
        so if you are going to use 9p, you'll likely want this.
 
+config NET_9P_PCI
+     depends on NET_9P
+     tristate "9p PCI Shared Memory Transport (Experimental)"
+     help
+       This builds support for a PCI psuedo-device currently available
+       under KVM/QEMU which allows for 9p transactions over shared
+       memory between the guest and the host.
+
 config NET_9P_DEBUG
      bool "Debug information"
      depends on NET_9P
net/9p/Makefile +4 -0
index 7b2a67a..26ce89d 100644
@@ -1,5 +1,6 @@
 obj-$(CONFIG_NET_9P) := 9pnet.o
 obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
+obj-$(CONFIG_NET_9P_PCI) += 9pnet_pci.o
 
 9pnet-objs := \
      mod.o \
@@ -14,3 +15,6 @@ obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
 
 9pnet_fd-objs := \
      trans_fd.o \
+
+9pnet_pci-objs := \
+     trans_pci.o \
net/9p/trans_pci.c new file +285 -0
new file mode 100644
index 0000000..36ddc5f
@@ -0,0 +1,295 @@
+/*
+ * net/9p/trans_pci.c
+ *
+ * 9P over PCI transport layer. For use with KVM/QEMU.
+ *
+ *  Copyright (C) 2007 by Latchesar Ionkov <lucho-OnYtXJJ0/[email protected]>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to:
+ *  Free Software Foundation
+ *  51 Franklin Street, Fifth Floor
+ *  Boston, MA  02111-1301  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/irq.h>
+#include <linux/poll.h>
+#include <net/9p/9p.h>
+#include <net/9p/transport.h>
+
+#define P9PCI_DRIVER_NAME "9P PCI Device"
+#define P9PCI_DRIVER_VERSION "1"
+
+#define PCI_VENDOR_ID_9P     0x5002
+#define PCI_DEVICE_ID_9P     0x000D
+
+#define MAX_PCI_BUF          (4*1024) /* TODO: Get a number from lucho */
+
+struct p9pci_trans {
+     struct pci_dev          *pdev;
+     void __iomem            *ioaddr;
+     void __iomem            *tx;
+     void __iomem            *rx;
+     int                     irq;
+     int                     pos;
+     int                     len;
+     wait_queue_head_t       wait;
+};
+static struct p9pci_trans *p9pci_trans; /* single channel for now */
+
+static struct pci_device_id p9pci_tbl[] = {
+     {PCI_VENDOR_ID_9P, PCI_DEVICE_ID_9P, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+     {0,}
+};
+
+static irqreturn_t p9pci_interrupt(int irq, void *dev)
+{
+     p9pci_trans = dev;
+     p9pci_trans->len = le32_to_cpu(readl(p9pci_trans->rx));
+     P9_DPRINTK(P9_DEBUG_TRANS, "%p len %d\n", p9pci_trans->pdev,
+                                                     p9pci_trans->len);
+     iowrite32(0, p9pci_trans->ioaddr + 4);
+     wake_up_interruptible(&p9pci_trans->wait);
+     return IRQ_HANDLED;
+}
+
+static int p9pci_read(struct p9_trans *trans, void *v, int len)
+{
+     struct p9pci_trans *ts;
+
+     if (!trans || trans->status == Disconnected || !trans->priv)
+             return -EREMOTEIO;
+
+     ts = trans->priv;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len %d\n",
+                                             trans, ts->rx, ts->tx, v, len);
+     if (len > ts->len)
+             len = ts->len;
+
+     if (len) {
+             memcpy_fromio(v, ts->rx, len);
+             ts->len = 0;
+             /* let the host knows the message is consumed */
+             writel(0, ts->rx);
+             iowrite32(0, p9pci_trans->ioaddr + 4);
+             P9_DPRINTK(P9_DEBUG_TRANS, "zero rxlen %d txlen %d\n",
+                                             readl(ts->rx), readl(ts->tx));
+     }
+
+     return len;
+}
+
+static int p9pci_write(struct p9_trans *trans, void *v, int len)
+{
+     struct p9pci_trans *ts;
+
+     if (!trans || trans->status == Disconnected || !trans->priv)
+             return -EREMOTEIO;
+
+     ts = trans->priv;
+     P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len %d\n",
+                                             trans, ts->rx, ts->tx, v, len);
+     P9_DPRINTK(P9_DEBUG_TRANS, "rxlen %d\n", readl(ts->rx));
+     if (readb(ts->tx) != 0)
+             return 0;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "tx addr %p io addr %p\n", ts->tx,
+                                                             ts->ioaddr);
+     memcpy_toio(ts->tx, v, len);
+     iowrite32(len, ts->ioaddr);
+     return len;
+}
+
+static unsigned int
+p9pci_poll(struct p9_trans *trans, struct poll_table_struct *pt)
+{
+     int ret;
+     struct p9pci_trans *ts;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "trans %p\n", trans);
+     if (!trans || trans->status != Connected || !trans->priv)
+             return -EREMOTEIO;
+
+     ts = trans->priv;
+     poll_wait(NULL, &ts->wait, pt);
+     ret = 0;
+     if (!readl(ts->tx))
+             ret |= POLLOUT;
+     if (readl(ts->rx))
+             ret |= POLLIN;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "txlen %d rxlen %d\n", readl(ts->tx),
+                                                             readl(ts->rx));
+     return ret;
+}
+
+/**
+ * p9_sock_close - shutdown socket
+ * @trans: private socket structure
+ *
+ */
+static void p9pci_close(struct p9_trans *trans)
+{
+     P9_DPRINTK(P9_DEBUG_TRANS, "trans %p\n", trans);
+}
+
+static struct p9_trans *p9pci_trans_create(const char *name, char *arg)
+{
+     struct p9_trans *trans;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "\n");
+     trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
+     if (!trans)
+             return ERR_PTR(-ENOMEM);
+
+     trans->status = Connected;
+     trans->write = p9pci_write;
+     trans->read = p9pci_read;
+     trans->close = p9pci_close;
+     trans->poll = p9pci_poll;
+     trans->priv = p9pci_trans;
+     writel(0, p9pci_trans->tx);
+     writel(0, p9pci_trans->rx);
+
+     return trans;
+}
+
+static int __devinit p9pci_probe(struct pci_dev *pdev,
+             const struct pci_device_id *ent)
+{
+     int err;
+     u8 pci_rev;
+
+     if (p9pci_trans)
+             return -1;
+
+     pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
+
+     if (pdev->vendor == PCI_VENDOR_ID_9P &&
+         pdev->device == PCI_DEVICE_ID_9P)
+             printk(KERN_INFO "pci dev %s (id %04x:%04x rev %02x) is a 9P\n",
+                    pci_name(pdev), pdev->vendor, pdev->device, pci_rev);
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "%p\n", pdev);
+     p9pci_trans = kzalloc(sizeof(*p9pci_trans), GFP_KERNEL);
+     p9pci_trans->irq = -1;
+     init_waitqueue_head(&p9pci_trans->wait);
+     err = pci_enable_device(pdev);
+     if (err)
+             goto error;
+
+     p9pci_trans->pdev = pdev;
+     err = pci_request_regions(pdev, "9p");
+     if (err)
+             goto error;
+
+     p9pci_trans->ioaddr = pci_iomap(pdev, 0, 8);
+     if (!p9pci_trans->ioaddr) {
+             P9_DPRINTK(P9_DEBUG_ERROR, "Cannot remap MMIO, aborting\n");
+             err = -EIO;
+             goto error;
+     }
+
+     p9pci_trans->tx = pci_iomap(pdev, 1, 0x20000);
+     p9pci_trans->rx = pci_iomap(pdev, 2, 0x20000);
+     pci_set_drvdata(pdev, p9pci_trans);
+     err = request_irq(pdev->irq, &p9pci_interrupt, 0, "p9pci", p9pci_trans);
+     if (err)
+             goto error;
+
+     p9pci_trans->irq = pdev->irq;
+     return 0;
+
+error:
+     P9_DPRINTK(P9_DEBUG_ERROR, "error %d\n", err);
+     if (p9pci_trans->irq >= 0) {
+             synchronize_irq(p9pci_trans->irq);
+             free_irq(p9pci_trans->irq, p9pci_trans);
+     }
+
+     if (p9pci_trans->pdev) {
+             pci_release_regions(pdev);
+             pci_iounmap(pdev, p9pci_trans->ioaddr);
+             pci_set_drvdata(pdev, NULL);
+             pci_disable_device(pdev);
+     }
+
+     kfree(p9pci_trans);
+     return -1;
+}
+
+static void __devexit p9pci_remove(struct pci_dev *pdev)
+{
+     P9_DPRINTK(P9_DEBUG_TRANS, "%p\n", pdev);
+     p9pci_trans = pci_get_drvdata(pdev);
+     if (!p9pci_trans)
+             return;
+
+     if (p9pci_trans->irq) {
+             synchronize_irq(p9pci_trans->irq);
+             free_irq(p9pci_trans->irq, p9pci_trans);
+     }
+
+     pci_release_regions(pdev);
+     pci_iounmap(pdev, p9pci_trans->ioaddr);
+     pci_set_drvdata(pdev, NULL);
+     kfree(p9pci_trans);
+     pci_disable_device(pdev);
+}
+
+static struct pci_driver p9pci_driver = {
+     .name           = P9PCI_DRIVER_NAME,
+     .id_table       = p9pci_tbl,
+     .probe          = p9pci_probe,
+     .remove         = __devexit_p(p9pci_remove),
+};
+
+static struct p9_trans_module p9_pci_trans = {
+     .name = "pci",
+     .maxsize = MAX_PCI_BUF,
+     .def = 0,
+     .create = p9pci_trans_create,
+};
+
+static int __init p9pci_init_module(void)
+{
+     v9fs_register_trans(&p9_pci_trans);
+     return pci_register_driver(&p9pci_driver);
+}
+
+static void __exit p9pci_cleanup_module(void)
+{
+     pci_unregister_driver(&p9pci_driver);
+     printk(KERN_ERR "Removal of 9p transports not implemented\n");
+     BUG();

net/9p/trans_pci.c line 295

Quoted 10 lines
net/9p/trans_pci.c new file +10 -0
+}
+
+module_init(p9pci_init_module);
+module_exit(p9pci_cleanup_module);
+
+MODULE_DEVICE_TABLE(pci, p9pci_tbl);
+MODULE_AUTHOR("Latchesar Ionkov <lucho-OnYtXJJ0/[email protected]>");
+MODULE_DESCRIPTION(P9PCI_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(P9PCI_DRIVER_VERSION);

-------------------------------------------------------------------------

Quoted 9 lines

This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
V9fs-developer mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/v9fs-developer

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

#13 lore raw

RE: [Lguest] [V9fs-developer] [kvm-devel] [RFC] 9p: add KVM/QEMUpci transport

My current view of the IO stack is the following:

        -------------- --------------  ------------    ----------
----------   ---------
        |NET_PCI_BACK| |BLK_PCI_BACK|  |9P_PCI_BACK|   |NET_FRONT|
|BLK_FRONT| |9P_FRONT|
        -------------- --------------  ------------    ----------
----------   ---------
               -------------      ---------------
-------------------
               |KVM_PCI_BUS|      |hypercall_ops|
|shared_mem_virtio|
               -------------      ---------------

-------------------

So the 9P implementation should add the front end logic and the p9_pci_backend that glues the shared_memory, pci_bus and hypercalls together.

Quoted 8 lines

That's also in our plans. There was no virtio support in KVM when I started working in the transport.

Thanks,
Lucho

Quoted 1 line · Anthony Liguori

I think that it would be nicer to implement the p9 transport on top

of

Quoted 33 lines
Quoted 20 lines

virtio instead of directly on top of PCI. I think your PCI transport would make a pretty nice start of a PCI virtio transport though.

Regards,

Anthony Liguori

Quoted 12 lines · Eric Van Hensbergen

From: Latchesar Ionkov <lucho-OnYtXJJ0/[email protected]>

This adds a shared memory transport for a synthetic 9p device for paravirtualized file system support under KVM/QEMU.

---
 Documentation/filesystems/9p.txt |    2 +
 net/9p/Kconfig                   |   10 ++-
 net/9p/Makefile                  |    4 +
 net/9p/trans_pci.c               |  295

++++++++++++++++++++++++++++++++++++++

Quoted 4 lines

Review

Quoted 4 lines
 4 files changed, 310 insertions(+), 1 deletions(-)
 create mode 100644 net/9p/trans_pci.c
(quoted diff) +0 -0

b/Documentation/filesystems/9p.txt

Quoted 6 lines

Documentation/filesystems/9p.txt OPTIONS · line 47

Quoted 6 lines

index 1a5f50d..e1879bd 100644

Documentation/filesystems/9p.txt +0 -0
@@ -46,6 +46,8 @@ OPTIONS
                      tcp  - specifying a normal TCP/IP connection
                      fd   - used passed file descriptors for

connection

Quoted 4 lines
Quoted 2 lines

Documentation/filesystems/9p.txt OPTIONS · line 49

Quoted 2 lines
Documentation/filesystems/9p.txt +1 -0
                                 (see rfdno and wfdno)
+                     pci  - use a PCI pseudo device for 9p

communication

Quoted 1 line
Quoted 1 line
Documentation/filesystems/9p.txt +1 -0
+                             over shared memory between a guest

and

Quoted 59 lines

host

Quoted 2 lines

Documentation/filesystems/9p.txt OPTIONS · line 51

Quoted 2 lines
Documentation/filesystems/9p.txt +0 -0
   uname=name user name to attempt mount as on the remote server.

The

Quoted 1 line

Documentation/filesystems/9p.txt OPTIONS · line 52

Quoted 1 line
Documentation/filesystems/9p.txt +0 -0
              server may override or ignore this value.  Certain

user

Quoted 16 lines
Quoted 16 lines
net/9p/Kconfig +1 -1
index 09566ae..8517560 100644
@@ -16,13 +16,21 @@ menuconfig NET_9P
 config NET_9P_FD
      depends on NET_9P
      default y if NET_9P
-     tristate "9P File Descriptor Transports (Experimental)"
+     tristate "9p File Descriptor Transports (Experimental)"
      help
        This builds support for file descriptor transports for 9p
        which includes support for TCP/IP, named pipes, or passed
        file descriptors.  TCP/IP is the default transport for 9p,
        so if you are going to use 9p, you'll likely want this.
 
Quoted 5 lines

net/9p/Kconfig menuconfig NET_9P

Quoted 5 lines
net/9p/Kconfig +5 -0
+config NET_9P_PCI
+     depends on NET_9P
+     tristate "9p PCI Shared Memory Transport (Experimental)"
+     help
+       This builds support for a PCI psuedo-device currently

available

Quoted 31 lines
Quoted 31 lines
net/9p/Kconfig +3 -0
+       under KVM/QEMU which allows for 9p transactions over shared
+       memory between the guest and the host.
+
 config NET_9P_DEBUG
      bool "Debug information"
      depends on NET_9P
net/9p/Makefile +4 -0
index 7b2a67a..26ce89d 100644
@@ -1,5 +1,6 @@
 obj-$(CONFIG_NET_9P) := 9pnet.o
 obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
+obj-$(CONFIG_NET_9P_PCI) += 9pnet_pci.o
 
 9pnet-objs := \
      mod.o \
@@ -14,3 +15,6 @@ obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
 
 9pnet_fd-objs := \
      trans_fd.o \
+
+9pnet_pci-objs := \
+     trans_pci.o \
net/9p/trans_pci.c new file +1 -0
new file mode 100644
index 0000000..36ddc5f
@@ -0,0 +1,295 @@
+/*
Quoted 12 lines
Quoted 7 lines

net/9p/trans_pci.c

Quoted 7 lines
net/9p/trans_pci.c new file +7 -0
+ * net/9p/trans_pci.c
+ *
+ * 9P over PCI transport layer. For use with KVM/QEMU.
+ *
+ *  Copyright (C) 2007 by Latchesar Ionkov <lucho-OnYtXJJ0/[email protected]>
+ *
+ *  This program is free software; you can redistribute it and/or

modify

Quoted 4 lines
Quoted 4 lines
net/9p/trans_pci.c new file +4 -0
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be

useful,

Quoted 63 lines
Quoted 5 lines

net/9p/trans_pci.c

Quoted 5 lines
net/9p/trans_pci.c new file +5 -0
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public

License

Quoted 21 lines
Quoted 21 lines
net/9p/trans_pci.c new file +21 -0
+ *  along with this program; if not, write to:
+ *  Free Software Foundation
+ *  51 Franklin Street, Fifth Floor
+ *  Boston, MA  02111-1301  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/irq.h>
+#include <linux/poll.h>
+#include <net/9p/9p.h>
+#include <net/9p/transport.h>
Quoted 8 lines

net/9p/trans_pci.c

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+
+#define P9PCI_DRIVER_NAME "9P PCI Device"
+#define P9PCI_DRIVER_VERSION "1"
+
+#define PCI_VENDOR_ID_9P     0x5002
+#define PCI_DEVICE_ID_9P     0x000D
+
+#define MAX_PCI_BUF          (4*1024) /* TODO: Get a number from

lucho */

Quoted 4 lines
Quoted 4 lines
net/9p/trans_pci.c new file +4 -0
+
+struct p9pci_trans {
+     struct pci_dev          *pdev;
+     void __iomem            *ioaddr;
Quoted 8 lines

net/9p/trans_pci.c

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+     void __iomem            *tx;
+     void __iomem            *rx;
+     int                     irq;
+     int                     pos;
+     int                     len;
+     wait_queue_head_t       wait;
+};
+static struct p9pci_trans *p9pci_trans; /* single channel for now

*/

Quoted 3 lines

net/9p/trans_pci.c

Quoted 3 lines
net/9p/trans_pci.c new file +3 -0
+
+static struct pci_device_id p9pci_tbl[] = {
+     {PCI_VENDOR_ID_9P, PCI_DEVICE_ID_9P, PCI_ANY_ID, PCI_ANY_ID,

0, 0, 0 },

Quoted 10 lines

net/9p/trans_pci.c

Quoted 9 lines
net/9p/trans_pci.c new file +9 -0
+     {0,}
+};
+
+static irqreturn_t p9pci_interrupt(int irq, void *dev)
+{
+     p9pci_trans = dev;
+     p9pci_trans->len = le32_to_cpu(readl(p9pci_trans->rx));
+     P9_DPRINTK(P9_DEBUG_TRANS, "%p len %d\n", p9pci_trans->pdev,
+                                                     p9pci_trans-

len);

Quoted 17 lines
Quoted 7 lines
Quoted 7 lines
net/9p/trans_pci.c new file +7 -0
+     iowrite32(0, p9pci_trans->ioaddr + 4);
+     wake_up_interruptible(&p9pci_trans->wait);
+     return IRQ_HANDLED;
+}
+
+static int p9pci_read(struct p9_trans *trans, void *v, int len)
+{
Quoted 8 lines

net/9p/trans_pci.c

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+     struct p9pci_trans *ts;
+
+     if (!trans || trans->status == Disconnected || !trans->priv)
+             return -EREMOTEIO;
+
+     ts = trans->priv;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len

%d\n",

Quoted 1 line
Quoted 1 line
net/9p/trans_pci.c new file +1 -0
+                                             trans, ts->rx,

ts->tx,

Quoted 11 lines

v, len);

Quoted 10 lines
Quoted 10 lines
net/9p/trans_pci.c new file +10 -0
+     if (len > ts->len)
+             len = ts->len;
+
+     if (len) {
+             memcpy_fromio(v, ts->rx, len);
+             ts->len = 0;
+             /* let the host knows the message is consumed */
+             writel(0, ts->rx);
+             iowrite32(0, p9pci_trans->ioaddr + 4);
+             P9_DPRINTK(P9_DEBUG_TRANS, "zero rxlen %d txlen

%d\n",

Quoted 18 lines
Quoted 1 line

net/9p/trans_pci.c line 97

Quoted 1 line
net/9p/trans_pci.c new file +1 -0
+                                             readl(ts->rx),

readl(ts->tx));

Quoted 6 lines
Quoted 6 lines
net/9p/trans_pci.c new file +6 -0
+     }
+
+     return len;
+}
+
+static int p9pci_write(struct p9_trans *trans, void *v, int len)
Quoted 8 lines

net/9p/trans_pci.c

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+{
+     struct p9pci_trans *ts;
+
+     if (!trans || trans->status == Disconnected || !trans->priv)
+             return -EREMOTEIO;
+
+     ts = trans->priv;
+     P9_DPRINTK(P9_DEBUG_TRANS, "trans %p rx %p tx %p buf %p len

%d\n",

Quoted 1 line
Quoted 1 line
net/9p/trans_pci.c new file +1 -0
+                                             trans, ts->rx,

ts->tx,

Quoted 173 lines

v, len);

Quoted 24 lines

net/9p/trans_pci.c

Quoted 6 lines
net/9p/trans_pci.c new file +6 -0
+     P9_DPRINTK(P9_DEBUG_TRANS, "rxlen %d\n", readl(ts->rx));
+     if (readb(ts->tx) != 0)
+             return 0;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "tx addr %p io addr %p\n", ts->tx,
+                                                             ts-

ioaddr);

Quoted 17 lines
net/9p/trans_pci.c new file +17 -0
+     memcpy_toio(ts->tx, v, len);
+     iowrite32(len, ts->ioaddr);
+     return len;
+}
+
+static unsigned int
+p9pci_poll(struct p9_trans *trans, struct poll_table_struct *pt)
+{
+     int ret;
+     struct p9pci_trans *ts;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "trans %p\n", trans);
+     if (!trans || trans->status != Connected || !trans->priv)
+             return -EREMOTEIO;
+
+     ts = trans->priv;
+     poll_wait(NULL, &ts->wait, pt);
Quoted 9 lines

net/9p/trans_pci.c

Quoted 7 lines
net/9p/trans_pci.c new file +7 -0
+     ret = 0;
+     if (!readl(ts->tx))
+             ret |= POLLOUT;
+     if (readl(ts->rx))
+             ret |= POLLIN;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "txlen %d rxlen %d\n", readl(ts-

tx),

Quoted 1 line
net/9p/trans_pci.c new file +1 -0
+

readl(ts->rx));

Quoted 6 lines
Quoted 6 lines
net/9p/trans_pci.c new file +6 -0
+     return ret;
+}
+
+/**
+ * p9_sock_close - shutdown socket
+ * @trans: private socket structure
Quoted 8 lines

net/9p/trans_pci.c

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+ *
+ */
+static void p9pci_close(struct p9_trans *trans)
+{
+     P9_DPRINTK(P9_DEBUG_TRANS, "trans %p\n", trans);
+}
+
+static struct p9_trans *p9pci_trans_create(const char *name, char

*arg)

Quoted 26 lines
Quoted 26 lines
net/9p/trans_pci.c new file +26 -0
+{
+     struct p9_trans *trans;
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "\n");
+     trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
+     if (!trans)
+             return ERR_PTR(-ENOMEM);
+
+     trans->status = Connected;
+     trans->write = p9pci_write;
+     trans->read = p9pci_read;
+     trans->close = p9pci_close;
+     trans->poll = p9pci_poll;
+     trans->priv = p9pci_trans;
+     writel(0, p9pci_trans->tx);
+     writel(0, p9pci_trans->rx);
+
+     return trans;
+}
+
+static int __devinit p9pci_probe(struct pci_dev *pdev,
+             const struct pci_device_id *ent)
+{
+     int err;
+     u8 pci_rev;
+
Quoted 8 lines

net/9p/trans_pci.c

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+     if (p9pci_trans)
+             return -1;
+
+     pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
+
+     if (pdev->vendor == PCI_VENDOR_ID_9P &&
+         pdev->device == PCI_DEVICE_ID_9P)
+             printk(KERN_INFO "pci dev %s (id %04x:%04x rev %02x)

is a 9P\n",

Quoted 1 line

net/9p/trans_pci.c line 192

Quoted 1 line
net/9p/trans_pci.c new file +1 -0
+                    pci_name(pdev), pdev->vendor, pdev->device,

pci_rev);

Quoted 9 lines
Quoted 9 lines
net/9p/trans_pci.c new file +9 -0
+
+     P9_DPRINTK(P9_DEBUG_TRANS, "%p\n", pdev);
+     p9pci_trans = kzalloc(sizeof(*p9pci_trans), GFP_KERNEL);
+     p9pci_trans->irq = -1;
+     init_waitqueue_head(&p9pci_trans->wait);
+     err = pci_enable_device(pdev);
+     if (err)
+             goto error;
+
Quoted 8 lines

net/9p/trans_pci.c

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+     p9pci_trans->pdev = pdev;
+     err = pci_request_regions(pdev, "9p");
+     if (err)
+             goto error;
+
+     p9pci_trans->ioaddr = pci_iomap(pdev, 0, 8);
+     if (!p9pci_trans->ioaddr) {
+             P9_DPRINTK(P9_DEBUG_ERROR, "Cannot remap MMIO,

aborting\n");

Quoted 8 lines

net/9p/trans_pci.c

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+             err = -EIO;
+             goto error;
+     }
+
+     p9pci_trans->tx = pci_iomap(pdev, 1, 0x20000);
+     p9pci_trans->rx = pci_iomap(pdev, 2, 0x20000);
+     pci_set_drvdata(pdev, p9pci_trans);
+     err = request_irq(pdev->irq, &p9pci_interrupt, 0, "p9pci",

p9pci_trans);

Quoted 59 lines
Quoted 59 lines
net/9p/trans_pci.c new file +59 -0
+     if (err)
+             goto error;
+
+     p9pci_trans->irq = pdev->irq;
+     return 0;
+
+error:
+     P9_DPRINTK(P9_DEBUG_ERROR, "error %d\n", err);
+     if (p9pci_trans->irq >= 0) {
+             synchronize_irq(p9pci_trans->irq);
+             free_irq(p9pci_trans->irq, p9pci_trans);
+     }
+
+     if (p9pci_trans->pdev) {
+             pci_release_regions(pdev);
+             pci_iounmap(pdev, p9pci_trans->ioaddr);
+             pci_set_drvdata(pdev, NULL);
+             pci_disable_device(pdev);
+     }
+
+     kfree(p9pci_trans);
+     return -1;
+}
+
+static void __devexit p9pci_remove(struct pci_dev *pdev)
+{
+     P9_DPRINTK(P9_DEBUG_TRANS, "%p\n", pdev);
+     p9pci_trans = pci_get_drvdata(pdev);
+     if (!p9pci_trans)
+             return;
+
+     if (p9pci_trans->irq) {
+             synchronize_irq(p9pci_trans->irq);
+             free_irq(p9pci_trans->irq, p9pci_trans);
+     }
+
+     pci_release_regions(pdev);
+     pci_iounmap(pdev, p9pci_trans->ioaddr);
+     pci_set_drvdata(pdev, NULL);
+     kfree(p9pci_trans);
+     pci_disable_device(pdev);
+}
+
+static struct pci_driver p9pci_driver = {
+     .name           = P9PCI_DRIVER_NAME,
+     .id_table       = p9pci_tbl,
+     .probe          = p9pci_probe,
+     .remove         = __devexit_p(p9pci_remove),
+};
+
+static struct p9_trans_module p9_pci_trans = {
+     .name = "pci",
+     .maxsize = MAX_PCI_BUF,
+     .def = 0,
+     .create = p9pci_trans_create,
+};
+
+static int __init p9pci_init_module(void)
+{
Quoted 8 lines
Quoted 8 lines

net/9p/trans_pci.c

Quoted 8 lines
net/9p/trans_pci.c new file +8 -0
+     v9fs_register_trans(&p9_pci_trans);
+     return pci_register_driver(&p9pci_driver);
+}
+
+static void __exit p9pci_cleanup_module(void)
+{
+     pci_unregister_driver(&p9pci_driver);
+     printk(KERN_ERR "Removal of 9p transports not

implemented\n");

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
net/9p/trans_pci.c new file +6 -0
+     BUG();
+}
+
+module_init(p9pci_init_module);
+module_exit(p9pci_cleanup_module);
+
Quoted 8 lines
Quoted 8 lines

net/9p/trans_pci.c line 295

Quoted 5 lines
net/9p/trans_pci.c new file +5 -0
+MODULE_DEVICE_TABLE(pci, p9pci_tbl);
+MODULE_AUTHOR("Latchesar Ionkov <lucho-OnYtXJJ0/[email protected]>");
+MODULE_DESCRIPTION(P9PCI_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(P9PCI_DRIVER_VERSION);

----------------------------------------------------------------------

Quoted 11 lines

---

Quoted 3 lines

This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a

browser.

Quoted 6 lines

Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
V9fs-developer mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/v9fs-developer

Quoted 4 lines

_______________________________________________
Lguest mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/lguest

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

#14 lore raw
In reply to Eric Van Hensbergen
Quoted 3 lines · On Tuesday 28 August 2007 20:52:36 Eric Van Hensbergen wrote:

This patch set contains a set of virtualization transports for the 9p file system intended to provide a mechanism for guests to access a portion of the hosts name space without having to go through a virtualized network.

It might be useful to convert UML's hostfs to something like this. It's essentially the same.

-Andi

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

#15 lore raw
In reply to Eric Van Hensbergen
Quoted 4 lines · Eric Van Hensbergen

The lguest and kvm transports are functional, but we are still working out remaining bugs and need to spend some time focusing on performance issues. I wanted to send out this "preview" patch set to the community to solicit ideas on things we can do differently/better.

Hi Eric,

Patches look reasonable, but just a heads-up: lguest will be moving to
virtio, as will kvm. That means a single implementation for both (yay!), but it does complicate your life in the short term 8(

Dor has published a kvm virtio implementation, and we've already
discussed a couple of modifications. I expect that to be nailed in the next 2 weeks tho, and lguest will follow.

Thanks!
Rusty.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/

#16 lore raw
Quoted 6 lines · Rusty Russell
Quoted 4 lines · Eric Van Hensbergen

The lguest and kvm transports are functional, but we are still working out remaining bugs and need to spend some time focusing on performance issues. I wanted to send out this "preview" patch set to the community to solicit ideas on things we can do differently/better.

Quoted 8 lines

Patches look reasonable, but just a heads-up: lguest will be moving to
virtio, as will kvm. That means a single implementation for both (yay!), but it does complicate your life in the short term 8(

Dor has published a kvm virtio implementation, and we've already
discussed a couple of modifications. I expect that to be nailed in the next 2 weeks tho, and lguest will follow.

yeah, I've been emailing Dor -- it sounds like he'll have stuff ready for the 2.6.24 merge window -- that being the case, I'll write a virtio transport and mothball the PCI and lguest transports. They were straightforward to write (a couple hours for the lguest transport) and the lguest transport was a good learning experience -- so I'm not shedding tears over wasted effort.

-eric

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/