net/ncsi: Rework request index allocation
authorGavin Shan <gwshan@linux.vnet.ibm.com>
Tue, 4 Oct 2016 00:25:50 +0000 (11:25 +1100)
committerDavid S. Miller <davem@davemloft.net>
Tue, 4 Oct 2016 06:11:50 +0000 (02:11 -0400)
The NCSI request index (struct ncsi_request::id) is put into instance
ID (IID) field while sending NCSI command packet. It was designed the
available IDs are given in round-robin fashion. @ndp->request_id was
introduced to represent the next available ID, but it has been used
as number of successively allocated IDs. It breaks the round-robin
design. Besides, we shouldn't put 0 to NCSI command packet's IID
field, meaning ID#0 should be reserved according section 6.3.1.1
in NCSI spec (v1.1.0).

This fixes above two issues. With it applied, the available IDs will
be assigned in round-robin fashion and ID#0 won't be assigned.

Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ncsi/internal.h
net/ncsi/ncsi-manage.c

index 66dc851..c956fe8 100644 (file)
@@ -259,6 +259,7 @@ struct ncsi_dev_priv {
        struct list_head    packages;        /* List of packages           */
        struct ncsi_request requests[256];   /* Request table              */
        unsigned int        request_id;      /* Last used request ID       */
+#define NCSI_REQ_START_IDX     1
        unsigned int        pending_req_num; /* Number of pending requests */
        struct ncsi_package *active_package; /* Currently handled package  */
        struct ncsi_channel *active_channel; /* Currently handled channel  */
index 8c5e016..00ce2c7 100644 (file)
@@ -427,30 +427,31 @@ struct ncsi_request *ncsi_alloc_request(struct ncsi_dev_priv *ndp, bool driven)
 
        /* Check if there is one available request until the ceiling */
        spin_lock_irqsave(&ndp->lock, flags);
-       for (i = ndp->request_id; !nr && i < limit; i++) {
+       for (i = ndp->request_id; i < limit; i++) {
                if (ndp->requests[i].used)
                        continue;
 
                nr = &ndp->requests[i];
                nr->used = true;
                nr->driven = driven;
-               if (++ndp->request_id >= limit)
-                       ndp->request_id = 0;
+               ndp->request_id = i + 1;
+               goto found;
        }
 
        /* Fail back to check from the starting cursor */
-       for (i = 0; !nr && i < ndp->request_id; i++) {
+       for (i = NCSI_REQ_START_IDX; i < ndp->request_id; i++) {
                if (ndp->requests[i].used)
                        continue;
 
                nr = &ndp->requests[i];
                nr->used = true;
                nr->driven = driven;
-               if (++ndp->request_id >= limit)
-                       ndp->request_id = 0;
+               ndp->request_id = i + 1;
+               goto found;
        }
-       spin_unlock_irqrestore(&ndp->lock, flags);
 
+found:
+       spin_unlock_irqrestore(&ndp->lock, flags);
        return nr;
 }
 
@@ -1148,7 +1149,7 @@ struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
        /* Initialize private NCSI device */
        spin_lock_init(&ndp->lock);
        INIT_LIST_HEAD(&ndp->packages);
-       ndp->request_id = 0;
+       ndp->request_id = NCSI_REQ_START_IDX;
        for (i = 0; i < ARRAY_SIZE(ndp->requests); i++) {
                ndp->requests[i].id = i;
                ndp->requests[i].ndp = ndp;