2012-10-09 20:00:10

by Bounine, Alexandre

[permalink] [raw]
Subject: [PATCH 0/3] rapidio: updates for multiple mport patches

This is a set of updates for patches submitted earlier:
https://lkml.org/lkml/2012/10/3/460.

Alexandre Bounine (3):
rapidio: use msleep in discovery wait
rapidio: update asynchronous discovery initialization
rapidio: update for destination ID allocation

drivers/rapidio/rio-scan.c | 40 ++++++++++-------------
drivers/rapidio/rio.c | 75 +++++++++++++++++++++++++++----------------
include/linux/rio.h | 1 -
3 files changed, 64 insertions(+), 52 deletions(-)

--
1.7.8.4


2012-10-09 20:00:15

by Bounine, Alexandre

[permalink] [raw]
Subject: [PATCH 1/3] rapidio: use msleep in discovery wait

Use msleep() routine for code clarity as suggested by Andrew Morton in his
comments for the original patch: https://lkml.org/lkml/2012/10/3/546.

Signed-off-by: Alexandre Bounine <[email protected]>
Cc: Matt Porter <[email protected]>
Cc: Li Yang <[email protected]>
---
drivers/rapidio/rio-scan.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 48e9041..05f0ed9 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -1391,7 +1391,7 @@ int __devinit rio_disc_mport(struct rio_mport *mport)
while (time_before(jiffies, to_end)) {
if (rio_enum_complete(mport))
goto enum_done;
- schedule_timeout_uninterruptible(msecs_to_jiffies(10));
+ msleep(10);
}

pr_debug("RIO: discovery timeout on mport %d %s\n",
--
1.7.8.4

2012-10-09 20:00:18

by Bounine, Alexandre

[permalink] [raw]
Subject: [PATCH 2/3] rapidio: update asynchronous discovery initialization

Update discovery process initialization based on Andrew Morton's comments:
https://lkml.org/lkml/2012/10/3/552.

This update processes all enumerating mports first and schedules discovery
work after that. If the initialization routine fails to allocate resources
needed to execute discovery, it abandons discovery for all ports.

Signed-off-by: Alexandre Bounine <[email protected]>
Cc: Matt Porter <[email protected]>
Cc: Li Yang <[email protected]>
---
drivers/rapidio/rio.c | 75 ++++++++++++++++++++++++++++++------------------
1 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index d4bd690..c17ae22 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1275,49 +1275,68 @@ static void __devinit disc_work_handler(struct work_struct *_work)
pr_debug("RIO: discovery work for mport %d %s\n",
work->mport->id, work->mport->name);
rio_disc_mport(work->mport);
-
- kfree(work);
}

int __devinit rio_init_mports(void)
{
struct rio_mport *port;
struct rio_disc_work *work;
- int no_disc = 0;
+ int n = 0;
+
+ if (!next_portid)
+ return -ENODEV;

+ /*
+ * First, run enumerations and check if we need to perform discovery
+ * on any of the registered mports.
+ */
list_for_each_entry(port, &rio_mports, node) {
if (port->host_deviceid >= 0)
rio_enum_mport(port);
- else if (!no_disc) {
- if (!rio_wq) {
- rio_wq = alloc_workqueue("riodisc", 0, 0);
- if (!rio_wq) {
- pr_err("RIO: unable allocate rio_wq\n");
- no_disc = 1;
- continue;
- }
- }
-
- work = kzalloc(sizeof *work, GFP_KERNEL);
- if (!work) {
- pr_err("RIO: no memory for work struct\n");
- no_disc = 1;
- continue;
- }
-
- work->mport = port;
- INIT_WORK(&work->work, disc_work_handler);
- queue_work(rio_wq, &work->work);
- }
+ else
+ n++;
+ }
+
+ if (!n)
+ goto no_disc;
+
+ /*
+ * If we have mports that require discovery schedule a discovery work
+ * for each of them. If the code below fails to allocate needed
+ * resources, exit without error to keep results of enumeration
+ * process (if any).
+ * TODO: Implement restart of dicovery process for all or
+ * individual discovering mports.
+ */
+ rio_wq = alloc_workqueue("riodisc", 0, 0);
+ if (!rio_wq) {
+ pr_err("RIO: unable allocate rio_wq\n");
+ goto no_disc;
}

- if (rio_wq) {
- pr_debug("RIO: flush discovery workqueue\n");
- flush_workqueue(rio_wq);
- pr_debug("RIO: flush discovery workqueue finished\n");
+ work = kcalloc(n, sizeof *work, GFP_KERNEL);
+ if (!work) {
+ pr_err("RIO: no memory for work struct\n");
destroy_workqueue(rio_wq);
+ goto no_disc;
}

+ n = 0;
+ list_for_each_entry(port, &rio_mports, node) {
+ if (port->host_deviceid < 0) {
+ work[n].mport = port;
+ INIT_WORK(&work[n].work, disc_work_handler);
+ queue_work(rio_wq, &work[n].work);
+ n++;
+ }
+ }
+
+ flush_workqueue(rio_wq);
+ pr_debug("RIO: destroy discovery workqueue\n");
+ destroy_workqueue(rio_wq);
+ kfree(work);
+
+no_disc:
rio_init();

return 0;
--
1.7.8.4

2012-10-09 20:00:12

by Bounine, Alexandre

[permalink] [raw]
Subject: [PATCH 3/3] rapidio: update for destination ID allocation

This patch address comments provided by Andrew Morton:
https://lkml.org/lkml/2012/10/3/550

- Keeps consistent kerneldoc compatible comments style for new static functions.
- Removes unnecessary complexity from destination ID allocation routine.
- Uses kcalloc() for code clarity.

Signed-off-by: Alexandre Bounine <[email protected]>
Cc: Matt Porter <[email protected]>
Cc: Li Yang <[email protected]>
---
drivers/rapidio/rio-scan.c | 38 ++++++++++++++++----------------------
include/linux/rio.h | 1 -
2 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 05f0ed9..07da58b 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -55,9 +55,9 @@ static int rio_mport_phys_table[] = {
};


-/*
+/**
* rio_destid_alloc - Allocate next available destID for given network
- * net: RIO network
+ * @net: RIO network
*
* Returns next available device destination ID for the specified RIO network.
* Marks allocated ID as one in use.
@@ -69,14 +69,9 @@ static u16 rio_destid_alloc(struct rio_net *net)
struct rio_id_table *idtab = &net->destid_table;

spin_lock(&idtab->lock);
- destid = find_next_zero_bit(idtab->table, idtab->max, idtab->next);
- if (destid >= idtab->max)
- destid = find_first_zero_bit(idtab->table, idtab->max);
+ destid = find_first_zero_bit(idtab->table, idtab->max);

if (destid < idtab->max) {
- idtab->next = destid + 1;
- if (idtab->next >= idtab->max)
- idtab->next = 0;
set_bit(destid, idtab->table);
destid += idtab->start;
} else
@@ -86,10 +81,10 @@ static u16 rio_destid_alloc(struct rio_net *net)
return (u16)destid;
}

-/*
+/**
* rio_destid_reserve - Reserve the specivied destID
- * net: RIO network
- * destid: destID to reserve
+ * @net: RIO network
+ * @destid: destID to reserve
*
* Tries to reserve the specified destID.
* Returns 0 if successfull.
@@ -106,10 +101,10 @@ static int rio_destid_reserve(struct rio_net *net, u16 destid)
return oldbit;
}

-/*
+/**
* rio_destid_free - free a previously allocated destID
- * net: RIO network
- * destid: destID to free
+ * @net: RIO network
+ * @destid: destID to free
*
* Makes the specified destID available for use.
*/
@@ -123,9 +118,9 @@ static void rio_destid_free(struct rio_net *net, u16 destid)
spin_unlock(&idtab->lock);
}

-/*
+/**
* rio_destid_first - return first destID in use
- * net: RIO network
+ * @net: RIO network
*/
static u16 rio_destid_first(struct rio_net *net)
{
@@ -142,10 +137,10 @@ static u16 rio_destid_first(struct rio_net *net)
return (u16)destid;
}

-/*
+/**
* rio_destid_next - return next destID in use
- * net: RIO network
- * from: destination ID from which search shall continue
+ * @net: RIO network
+ * @from: destination ID from which search shall continue
*/
static u16 rio_destid_next(struct rio_net *net, u16 from)
{
@@ -1163,8 +1158,8 @@ static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port,

net = kzalloc(sizeof(struct rio_net), GFP_KERNEL);
if (net && do_enum) {
- net->destid_table.table = kzalloc(
- BITS_TO_LONGS(RIO_MAX_ROUTE_ENTRIES(port->sys_size)) *
+ net->destid_table.table = kcalloc(
+ BITS_TO_LONGS(RIO_MAX_ROUTE_ENTRIES(port->sys_size)),
sizeof(long),
GFP_KERNEL);

@@ -1174,7 +1169,6 @@ static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port,
net = NULL;
} else {
net->destid_table.start = start;
- net->destid_table.next = 0;
net->destid_table.max =
RIO_MAX_ROUTE_ENTRIES(port->sys_size);
spin_lock_init(&net->destid_table.lock);
diff --git a/include/linux/rio.h b/include/linux/rio.h
index d2dff22..ac21ac6 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -266,7 +266,6 @@ struct rio_mport {

struct rio_id_table {
u16 start; /* logical minimal id */
- u16 next; /* hint for find */
u32 max; /* max number of IDs in table */
spinlock_t lock;
unsigned long *table;
--
1.7.8.4