From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Anthony PERARD <anthony.perard@citrix.com>
Cc: Xen Devel <xen-devel@lists.xensource.com>,
"Michael S . Tsirkin" <mst@redhat.com>,
QEMU-devel <qemu-devel@nongnu.org>,
Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: Re: [Qemu-devel] [Xen-devel] [PATCH V10 3/8] Introduce XenHostPCIDevice to access a pci device on the host.
Date: Fri, 30 Mar 2012 10:39:09 -0400 [thread overview]
Message-ID: <20120330143909.GC22274@phenom.dumpdata.com> (raw)
In-Reply-To: <CAJJyHjKjgpOrt2kYs_uJPvjoEfo-cCvouA8HaZpxfwv=bQp9QQ@mail.gmail.com>
On Fri, Mar 30, 2012 at 03:21:07PM +0100, Anthony PERARD wrote:
> On Wed, Mar 28, 2012 at 19:52, Konrad Rzeszutek Wilk
> <konrad.wilk@oracle.com> wrote:
> >> +static int xen_host_pci_sysfs_path(const XenHostPCIDevice *d,
> >> + const char *name, char *buf, ssize_t size)
> >> +{
> >> + int rc;
> >> +
> >> + rc = snprintf(buf, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%x/%s",
> >
> > The format is actually " %04x:%02x:%02x.%d"
> >
> >> + d->domain, d->bus, d->dev, d->func, name);
> >> +
> >> + if (rc >= size || rc < 0) {
> >> + /* The ouput is truncated or an other error is encountered */
> >> + return -1;
> >
> > -ENODEV
> >
> >> + }
> >> + return 0;
> >> +}
> >> +
> >> +static int xen_host_pci_get_resource(XenHostPCIDevice *d)
> >> +{
> >> + int i, rc, fd;
> >> + char path[PATH_MAX];
> >> + char buf[512];
> >
> > You should have a #define for the 512.
> >
> >> + unsigned long long start, end, flags, size;
> >> + char *endptr, *s;
> >> +
> >> + if (xen_host_pci_sysfs_path(d, "resource", path, sizeof (path))) {
> >> + return -1;
> >
> > -ENODEV
>
> I still does not understand why return ENODEV (No such device) when an
> error occure. Is it the better way to say that a device does not
> behave like it should, or that a "module" using a device encounter any
> kind of error that prevent it to use the device ?
That is fine too - there is probably a -Exxx that is exactly for that.
Perhaps ENOSPC?
>
>
> >> + }
> >> + fd = open(path, O_RDONLY);
> >> + if (fd == -1) {
> >> + XEN_HOST_PCI_LOG("Error: Can't open %s: %s\n", path, strerror(errno));
> >> + return -errno;
> >> + }
> >> +
> >> + do {
> >> + rc = read(fd, &buf, sizeof (buf));
> >> + if (rc < 0 && errno != EINTR) {
> >> + rc = -errno;
> >
> > So you are using the errnor types, so you should use them throughout
> > this function.
> >
> >> + goto out;
> >> + }
> >> + } while (rc < 0);
> >> + buf[rc] = 0;
> >> + rc = 0;
> >> +
> >> + s = buf;
> >> + for (i = 0; i < PCI_NUM_REGIONS; i++) {
> >> + start = strtoll(s, &endptr, 16);
> >> + if (*endptr != ' ' || s == endptr) {
> >> + break;
> >> + }
> >> + s = endptr + 1;
> >> + end = strtoll(s, &endptr, 16);
> >> + if (*endptr != ' ' || s == endptr) {
> >> + break;
> >> + }
> >> + s = endptr + 1;
> >> + flags = strtoll(s, &endptr, 16);
> >> + if (*endptr != '\n' || s == endptr) {
> >> + break;
> >> + }
> >> + s = endptr + 1;
> >> +
> >> + if (start) {
> >> + size = end - start + 1;
> >> + } else {
> >> + size = 0;
> >> + }
> >> +
> >> + if (i < PCI_ROM_SLOT) {
> >> + d->io_regions[i].base_addr = start;
> >> + d->io_regions[i].size = size;
> >> + d->io_regions[i].flags = flags;
> >> + } else {
> >> + d->rom.base_addr = start;
> >> + d->rom.size = size;
> >> + d->rom.flags = flags;
> >> + }
> >> + }
> >> + if (i != PCI_NUM_REGIONS) {
> >> + rc = -1;
> >
> > -ENODEV
> >
> >
> >> + }
> >> +
> >> +out:
> >> + close(fd);
> >> + return rc;
> >> +}
> >> +
> >> +static int xen_host_pci_get_value(XenHostPCIDevice *d, const char *name,
> >> + unsigned int *pvalue, int base)
> >> +{
> >> + char path[PATH_MAX];
> >> + char buf[42];
> >
> > You should use a #define
> >
> >> + int fd, rc;
> >> + unsigned long value;
> >> + char *endptr;
> >> +
> >> + if (xen_host_pci_sysfs_path(d, name, path, sizeof (path))) {
> >> + return -1;
> >
> > -ENODEV
> >
> >> + }
> >> + fd = open(path, O_RDONLY);
> >> + if (fd == -1) {
> >> + XEN_HOST_PCI_LOG("Error: Can't open %s: %s\n", path, strerror(errno));
> >> + return -errno;
> >> + }
> >> + do {
> >> + rc = read(fd, &buf, sizeof (buf) - 1);
> >
> > Here you have sizeof(buf) - 1, but in the function xen_host_pci_get_resource(..)
> > you didn't do that. Any particular reason?
>
> Nop, it's just a mistake.
>
> >> + if (rc < 0 && errno != EINTR) {
> >> + rc = -errno;
> >> + goto out;
> >> + }
> >> + } while (rc < 0);
> >> + buf[rc] = 0;
> >> + value = strtol(buf, &endptr, base);
> >> + if (endptr == buf || *endptr != '\n') {
> >> + rc = -1;
> >
> > ??? -Exx something I think
> >
> >> + } else if ((value == LONG_MIN || value == LONG_MAX) && errno == ERANGE) {
> >> + rc = -errno;
> >> + } else {
> >> + rc = 0;
> >> + *pvalue = value;
> >> + }
> >> +out:
> >> + close(fd);
> >> + return rc;
> >> +}
> >> +
> >> +static inline int xen_host_pci_get_hex_value(XenHostPCIDevice *d,
> >> + const char *name,
> >> + unsigned int *pvalue)
> >> +{
> >> + return xen_host_pci_get_value(d, name, pvalue, 16);
> >> +}
> >> +
> >> +static inline int xen_host_pci_get_dec_value(XenHostPCIDevice *d,
> >> + const char *name,
> >> + unsigned int *pvalue)
> >> +{
> >> + return xen_host_pci_get_value(d, name, pvalue, 10);
> >> +}
> >> +
> >> +static bool xen_host_pci_dev_is_virtfn(XenHostPCIDevice *d)
> >> +{
> >> + char path[PATH_MAX];
> >> + struct stat buf;
> >> +
> >> + if (xen_host_pci_sysfs_path(d, "physfn", path, sizeof (path))) {
> >> + return false;
> >> + }
> >> + return !stat(path, &buf);
> >> +}
> >> +
> >> +static int xen_host_pci_config_open(XenHostPCIDevice *d)
> >> +{
> >> + char path[PATH_MAX];
> >> +
> >> + if (xen_host_pci_sysfs_path(d, "config", path, sizeof (path))) {
> >> + return -1;
> >
> > -ENODEV
> >
> >> + }
> >> + d->config_fd = open(path, O_RDWR);
> >> + if (d->config_fd < 0) {
> >> + return -errno;
> >> + }
> >> + return 0;
> >> +}
>
> [...]
>
> >> +int xen_host_pci_find_ext_cap_offset(XenHostPCIDevice *d, uint32_t cap)
> >> +{
> >> + uint32_t header = 0;
> >> + int max_cap = XEN_HOST_PCI_MAX_EXT_CAP;
> >> + int pos = PCI_CONFIG_SPACE_SIZE;
> >> +
> >> + do {
> >> + if (xen_host_pci_get_long(d, pos, &header)) {
> >> + break;
> >> + }
> >> + /*
> >> + * If we have no capabilities, this is indicated by cap ID,
> >> + * cap version and next pointer all being 0.
> >> + */
> >> + if (header == 0) {
> >> + break;
> >> + }
> >> +
> >> + if (PCI_EXT_CAP_ID(header) == cap) {
> >> + return pos;
> >> + }
> >> +
> >> + pos = PCI_EXT_CAP_NEXT(header);
> >> + if (pos < PCI_CONFIG_SPACE_SIZE) {
> >> + break;
> >> + }
> >> +
> >> + max_cap--;
> >> + } while (max_cap > 0);
> >> +
> >> + return 0;
> >
> > If we fail in this function (which can happen [https://bugzilla.redhat.com/show_bug.cgi?id=767742])
> > shouldn't this function return something else besides 0?
>
> -1 should be good enough, as it's not an offset.
>
> > Besides those comments, the patch looks good to me.
>
> Thanks,
>
> --
> Anthony PERARD
WARNING: multiple messages have this Message-ID (diff)
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Anthony PERARD <anthony.perard@citrix.com>
Cc: Xen Devel <xen-devel@lists.xensource.com>,
"Michael S . Tsirkin" <mst@redhat.com>,
QEMU-devel <qemu-devel@nongnu.org>,
Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: Re: [Xen-devel] [PATCH V10 3/8] Introduce XenHostPCIDevice to access a pci device on the host.
Date: Fri, 30 Mar 2012 10:39:09 -0400 [thread overview]
Message-ID: <20120330143909.GC22274@phenom.dumpdata.com> (raw)
In-Reply-To: <CAJJyHjKjgpOrt2kYs_uJPvjoEfo-cCvouA8HaZpxfwv=bQp9QQ@mail.gmail.com>
On Fri, Mar 30, 2012 at 03:21:07PM +0100, Anthony PERARD wrote:
> On Wed, Mar 28, 2012 at 19:52, Konrad Rzeszutek Wilk
> <konrad.wilk@oracle.com> wrote:
> >> +static int xen_host_pci_sysfs_path(const XenHostPCIDevice *d,
> >> + const char *name, char *buf, ssize_t size)
> >> +{
> >> + int rc;
> >> +
> >> + rc = snprintf(buf, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%x/%s",
> >
> > The format is actually " %04x:%02x:%02x.%d"
> >
> >> + d->domain, d->bus, d->dev, d->func, name);
> >> +
> >> + if (rc >= size || rc < 0) {
> >> + /* The ouput is truncated or an other error is encountered */
> >> + return -1;
> >
> > -ENODEV
> >
> >> + }
> >> + return 0;
> >> +}
> >> +
> >> +static int xen_host_pci_get_resource(XenHostPCIDevice *d)
> >> +{
> >> + int i, rc, fd;
> >> + char path[PATH_MAX];
> >> + char buf[512];
> >
> > You should have a #define for the 512.
> >
> >> + unsigned long long start, end, flags, size;
> >> + char *endptr, *s;
> >> +
> >> + if (xen_host_pci_sysfs_path(d, "resource", path, sizeof (path))) {
> >> + return -1;
> >
> > -ENODEV
>
> I still does not understand why return ENODEV (No such device) when an
> error occure. Is it the better way to say that a device does not
> behave like it should, or that a "module" using a device encounter any
> kind of error that prevent it to use the device ?
That is fine too - there is probably a -Exxx that is exactly for that.
Perhaps ENOSPC?
>
>
> >> + }
> >> + fd = open(path, O_RDONLY);
> >> + if (fd == -1) {
> >> + XEN_HOST_PCI_LOG("Error: Can't open %s: %s\n", path, strerror(errno));
> >> + return -errno;
> >> + }
> >> +
> >> + do {
> >> + rc = read(fd, &buf, sizeof (buf));
> >> + if (rc < 0 && errno != EINTR) {
> >> + rc = -errno;
> >
> > So you are using the errnor types, so you should use them throughout
> > this function.
> >
> >> + goto out;
> >> + }
> >> + } while (rc < 0);
> >> + buf[rc] = 0;
> >> + rc = 0;
> >> +
> >> + s = buf;
> >> + for (i = 0; i < PCI_NUM_REGIONS; i++) {
> >> + start = strtoll(s, &endptr, 16);
> >> + if (*endptr != ' ' || s == endptr) {
> >> + break;
> >> + }
> >> + s = endptr + 1;
> >> + end = strtoll(s, &endptr, 16);
> >> + if (*endptr != ' ' || s == endptr) {
> >> + break;
> >> + }
> >> + s = endptr + 1;
> >> + flags = strtoll(s, &endptr, 16);
> >> + if (*endptr != '\n' || s == endptr) {
> >> + break;
> >> + }
> >> + s = endptr + 1;
> >> +
> >> + if (start) {
> >> + size = end - start + 1;
> >> + } else {
> >> + size = 0;
> >> + }
> >> +
> >> + if (i < PCI_ROM_SLOT) {
> >> + d->io_regions[i].base_addr = start;
> >> + d->io_regions[i].size = size;
> >> + d->io_regions[i].flags = flags;
> >> + } else {
> >> + d->rom.base_addr = start;
> >> + d->rom.size = size;
> >> + d->rom.flags = flags;
> >> + }
> >> + }
> >> + if (i != PCI_NUM_REGIONS) {
> >> + rc = -1;
> >
> > -ENODEV
> >
> >
> >> + }
> >> +
> >> +out:
> >> + close(fd);
> >> + return rc;
> >> +}
> >> +
> >> +static int xen_host_pci_get_value(XenHostPCIDevice *d, const char *name,
> >> + unsigned int *pvalue, int base)
> >> +{
> >> + char path[PATH_MAX];
> >> + char buf[42];
> >
> > You should use a #define
> >
> >> + int fd, rc;
> >> + unsigned long value;
> >> + char *endptr;
> >> +
> >> + if (xen_host_pci_sysfs_path(d, name, path, sizeof (path))) {
> >> + return -1;
> >
> > -ENODEV
> >
> >> + }
> >> + fd = open(path, O_RDONLY);
> >> + if (fd == -1) {
> >> + XEN_HOST_PCI_LOG("Error: Can't open %s: %s\n", path, strerror(errno));
> >> + return -errno;
> >> + }
> >> + do {
> >> + rc = read(fd, &buf, sizeof (buf) - 1);
> >
> > Here you have sizeof(buf) - 1, but in the function xen_host_pci_get_resource(..)
> > you didn't do that. Any particular reason?
>
> Nop, it's just a mistake.
>
> >> + if (rc < 0 && errno != EINTR) {
> >> + rc = -errno;
> >> + goto out;
> >> + }
> >> + } while (rc < 0);
> >> + buf[rc] = 0;
> >> + value = strtol(buf, &endptr, base);
> >> + if (endptr == buf || *endptr != '\n') {
> >> + rc = -1;
> >
> > ??? -Exx something I think
> >
> >> + } else if ((value == LONG_MIN || value == LONG_MAX) && errno == ERANGE) {
> >> + rc = -errno;
> >> + } else {
> >> + rc = 0;
> >> + *pvalue = value;
> >> + }
> >> +out:
> >> + close(fd);
> >> + return rc;
> >> +}
> >> +
> >> +static inline int xen_host_pci_get_hex_value(XenHostPCIDevice *d,
> >> + const char *name,
> >> + unsigned int *pvalue)
> >> +{
> >> + return xen_host_pci_get_value(d, name, pvalue, 16);
> >> +}
> >> +
> >> +static inline int xen_host_pci_get_dec_value(XenHostPCIDevice *d,
> >> + const char *name,
> >> + unsigned int *pvalue)
> >> +{
> >> + return xen_host_pci_get_value(d, name, pvalue, 10);
> >> +}
> >> +
> >> +static bool xen_host_pci_dev_is_virtfn(XenHostPCIDevice *d)
> >> +{
> >> + char path[PATH_MAX];
> >> + struct stat buf;
> >> +
> >> + if (xen_host_pci_sysfs_path(d, "physfn", path, sizeof (path))) {
> >> + return false;
> >> + }
> >> + return !stat(path, &buf);
> >> +}
> >> +
> >> +static int xen_host_pci_config_open(XenHostPCIDevice *d)
> >> +{
> >> + char path[PATH_MAX];
> >> +
> >> + if (xen_host_pci_sysfs_path(d, "config", path, sizeof (path))) {
> >> + return -1;
> >
> > -ENODEV
> >
> >> + }
> >> + d->config_fd = open(path, O_RDWR);
> >> + if (d->config_fd < 0) {
> >> + return -errno;
> >> + }
> >> + return 0;
> >> +}
>
> [...]
>
> >> +int xen_host_pci_find_ext_cap_offset(XenHostPCIDevice *d, uint32_t cap)
> >> +{
> >> + uint32_t header = 0;
> >> + int max_cap = XEN_HOST_PCI_MAX_EXT_CAP;
> >> + int pos = PCI_CONFIG_SPACE_SIZE;
> >> +
> >> + do {
> >> + if (xen_host_pci_get_long(d, pos, &header)) {
> >> + break;
> >> + }
> >> + /*
> >> + * If we have no capabilities, this is indicated by cap ID,
> >> + * cap version and next pointer all being 0.
> >> + */
> >> + if (header == 0) {
> >> + break;
> >> + }
> >> +
> >> + if (PCI_EXT_CAP_ID(header) == cap) {
> >> + return pos;
> >> + }
> >> +
> >> + pos = PCI_EXT_CAP_NEXT(header);
> >> + if (pos < PCI_CONFIG_SPACE_SIZE) {
> >> + break;
> >> + }
> >> +
> >> + max_cap--;
> >> + } while (max_cap > 0);
> >> +
> >> + return 0;
> >
> > If we fail in this function (which can happen [https://bugzilla.redhat.com/show_bug.cgi?id=767742])
> > shouldn't this function return something else besides 0?
>
> -1 should be good enough, as it's not an offset.
>
> > Besides those comments, the patch looks good to me.
>
> Thanks,
>
> --
> Anthony PERARD
next prev parent reply other threads:[~2012-03-30 14:44 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-03-28 11:41 [Qemu-devel] [PATCH V10 0/8] Xen PCI Passthrough Anthony PERARD
2012-03-28 11:41 ` Anthony PERARD
2012-03-28 11:41 ` [Qemu-devel] [PATCH V10 1/8] pci_ids: Add INTEL_82599_SFP_VF id Anthony PERARD
2012-03-28 11:41 ` Anthony PERARD
2012-03-28 18:53 ` [Qemu-devel] [Xen-devel] " Konrad Rzeszutek Wilk
2012-03-28 18:53 ` Konrad Rzeszutek Wilk
2012-03-30 14:24 ` [Qemu-devel] [Xen-devel] " Anthony PERARD
2012-03-30 14:24 ` Anthony PERARD
2012-03-28 11:41 ` [Qemu-devel] [PATCH V10 2/8] configure: Introduce --enable-xen-pci-passthrough Anthony PERARD
2012-03-28 11:41 ` Anthony PERARD
2012-03-28 18:52 ` [Qemu-devel] [Xen-devel] " Konrad Rzeszutek Wilk
2012-03-28 18:52 ` Konrad Rzeszutek Wilk
2012-03-28 21:02 ` [Qemu-devel] [Xen-devel] " Anthony Liguori
2012-03-28 21:02 ` Anthony Liguori
2012-03-28 21:07 ` [Qemu-devel] [Xen-devel] " Konrad Rzeszutek Wilk
2012-03-28 21:07 ` Konrad Rzeszutek Wilk
2012-03-28 11:41 ` [Qemu-devel] [PATCH V10 3/8] Introduce XenHostPCIDevice to access a pci device on the host Anthony PERARD
2012-03-28 11:41 ` Anthony PERARD
2012-03-28 18:52 ` [Qemu-devel] [Xen-devel] " Konrad Rzeszutek Wilk
2012-03-28 18:52 ` Konrad Rzeszutek Wilk
2012-03-30 14:21 ` [Qemu-devel] [Xen-devel] " Anthony PERARD
2012-03-30 14:21 ` Anthony PERARD
2012-03-30 14:39 ` Konrad Rzeszutek Wilk [this message]
2012-03-30 14:39 ` Konrad Rzeszutek Wilk
2012-03-28 11:41 ` [Qemu-devel] [PATCH V10 4/8] pci.c: Add opaque argument to pci_for_each_device Anthony PERARD
2012-03-28 11:41 ` Anthony PERARD
2012-03-28 21:00 ` [Qemu-devel] [Xen-devel] " Konrad Rzeszutek Wilk
2012-03-28 21:00 ` Konrad Rzeszutek Wilk
2012-03-30 14:36 ` [Qemu-devel] [Xen-devel] " Anthony PERARD
2012-03-30 14:36 ` Anthony PERARD
2012-03-28 11:41 ` [Qemu-devel] [PATCH V10 5/8] Introduce Xen PCI Passthrough, qdevice (1/3) Anthony PERARD
2012-03-28 11:41 ` Anthony PERARD
2012-03-28 11:41 ` [Qemu-devel] [PATCH V10 6/8] Introduce Xen PCI Passthrough, PCI config space helpers (2/3) Anthony PERARD
2012-03-28 11:41 ` Anthony PERARD
2012-03-28 11:41 ` [Qemu-devel] [PATCH V10 7/8] Introduce apic-msidef.h Anthony PERARD
2012-03-28 11:41 ` Anthony PERARD
2012-03-28 11:41 ` [Qemu-devel] [PATCH V10 8/8] Introduce Xen PCI Passthrough, MSI (3/3) Anthony PERARD
2012-03-28 11:41 ` Anthony PERARD
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=20120330143909.GC22274@phenom.dumpdata.com \
--to=konrad.wilk@oracle.com \
--cc=anthony.perard@citrix.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefano.stabellini@eu.citrix.com \
--cc=xen-devel@lists.xensource.com \
/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.