Skip to content

Commit

Permalink
IB/qib: Don't rely on (undefined) order of function parameter evaluation
Browse files Browse the repository at this point in the history
Some of the qib sysfs code passes a buffer pointer into 
simple_read_from_buffer() but relies on a function call in another 
parameter of the same call to initialize that pointer.  Since the order
of evaluation of function parameters is undefined, this will break if
gcc chooses the wrong order.

Fix this by splitting the code into two separate function calls.

This was noticed because of warnings like the following on ppc:

    drivers/infiniband/hw/qib/qib_fs.c: In function 'portcntrs_2_read':
    drivers/infiniband/hw/qib/qib_fs.c:203: warning: 'counters' is used uninitialized in this function

Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
  • Loading branch information
Roland Dreier committed May 26, 2010
1 parent 7e3a1f4 commit f27ec1d
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions drivers/infiniband/hw/qib/qib_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,21 +144,23 @@ static ssize_t dev_counters_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
u64 *counters;
size_t avail;
struct qib_devdata *dd = private2dd(file);

return simple_read_from_buffer(buf, count, ppos, counters,
dd->f_read_cntrs(dd, *ppos, NULL, &counters));
avail = dd->f_read_cntrs(dd, *ppos, NULL, &counters);
return simple_read_from_buffer(buf, count, ppos, counters, avail);
}

/* read the per-device counters */
static ssize_t dev_names_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
char *names;
size_t avail;
struct qib_devdata *dd = private2dd(file);

return simple_read_from_buffer(buf, count, ppos, names,
dd->f_read_cntrs(dd, *ppos, &names, NULL));
avail = dd->f_read_cntrs(dd, *ppos, &names, NULL);
return simple_read_from_buffer(buf, count, ppos, names, avail);
}

static const struct file_operations cntr_ops[] = {
Expand All @@ -176,32 +178,35 @@ static ssize_t portnames_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
char *names;
size_t avail;
struct qib_devdata *dd = private2dd(file);

return simple_read_from_buffer(buf, count, ppos, names,
dd->f_read_portcntrs(dd, *ppos, 0, &names, NULL));
avail = dd->f_read_portcntrs(dd, *ppos, 0, &names, NULL);
return simple_read_from_buffer(buf, count, ppos, names, avail);
}

/* read the per-port counters for port 1 (pidx 0) */
static ssize_t portcntrs_1_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
u64 *counters;
size_t avail;
struct qib_devdata *dd = private2dd(file);

return simple_read_from_buffer(buf, count, ppos, counters,
dd->f_read_portcntrs(dd, *ppos, 0, NULL, &counters));
avail = dd->f_read_portcntrs(dd, *ppos, 0, NULL, &counters);
return simple_read_from_buffer(buf, count, ppos, counters, avail);
}

/* read the per-port counters for port 2 (pidx 1) */
static ssize_t portcntrs_2_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
u64 *counters;
size_t avail;
struct qib_devdata *dd = private2dd(file);

return simple_read_from_buffer(buf, count, ppos, counters,
dd->f_read_portcntrs(dd, *ppos, 1, NULL, &counters));
avail = dd->f_read_portcntrs(dd, *ppos, 1, NULL, &counters);
return simple_read_from_buffer(buf, count, ppos, counters, avail);
}

static const struct file_operations portcntr_ops[] = {
Expand Down

0 comments on commit f27ec1d

Please sign in to comment.