Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 150837
b: refs/heads/master
c: 74b793e
h: refs/heads/master
i:
  150835: 073c68d
v: v3
  • Loading branch information
Divy Le Ray authored and David S. Miller committed Jun 11, 2009
1 parent 670fb9e commit d4d36ea
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 87433bfc75f34599c38137e172b6bf8fd41971ba
refs/heads/master: 74b793e1ef79edc49bc031a88d62f1e93fc6b30f
2 changes: 2 additions & 0 deletions trunk/drivers/net/cxgb3/adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ struct adapter {
struct mutex mdio_lock;
spinlock_t stats_lock;
spinlock_t work_lock;

struct sk_buff *nofail_skb;
};

static inline u32 t3_read_reg(struct adapter *adapter, u32 reg_addr)
Expand Down
78 changes: 73 additions & 5 deletions trunk/drivers/net/cxgb3/cxgb3_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,40 +433,78 @@ static int init_tp_parity(struct adapter *adap)
for (i = 0; i < 16; i++) {
struct cpl_smt_write_req *req;

skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
skb = alloc_skb(sizeof(*req), GFP_KERNEL);
if (!skb)
skb = adap->nofail_skb;
if (!skb)
goto alloc_skb_fail;

req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i));
req->iff = i;
t3_mgmt_tx(adap, skb);
if (skb == adap->nofail_skb) {
await_mgmt_replies(adap, cnt, i + 1);
adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
if (!adap->nofail_skb)
goto alloc_skb_fail;
}
}

for (i = 0; i < 2048; i++) {
struct cpl_l2t_write_req *req;

skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
skb = alloc_skb(sizeof(*req), GFP_KERNEL);
if (!skb)
skb = adap->nofail_skb;
if (!skb)
goto alloc_skb_fail;

req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i));
req->params = htonl(V_L2T_W_IDX(i));
t3_mgmt_tx(adap, skb);
if (skb == adap->nofail_skb) {
await_mgmt_replies(adap, cnt, 16 + i + 1);
adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
if (!adap->nofail_skb)
goto alloc_skb_fail;
}
}

for (i = 0; i < 2048; i++) {
struct cpl_rte_write_req *req;

skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
skb = alloc_skb(sizeof(*req), GFP_KERNEL);
if (!skb)
skb = adap->nofail_skb;
if (!skb)
goto alloc_skb_fail;

req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i));
req->l2t_idx = htonl(V_L2T_W_IDX(i));
t3_mgmt_tx(adap, skb);
if (skb == adap->nofail_skb) {
await_mgmt_replies(adap, cnt, 16 + 2048 + i + 1);
adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
if (!adap->nofail_skb)
goto alloc_skb_fail;
}
}

skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL);
skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
if (!skb)
skb = adap->nofail_skb;
if (!skb)
goto alloc_skb_fail;

greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq));
memset(greq, 0, sizeof(*greq));
greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
Expand All @@ -475,8 +513,17 @@ static int init_tp_parity(struct adapter *adap)
t3_mgmt_tx(adap, skb);

i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
if (skb == adap->nofail_skb) {
i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
}

t3_tp_set_offload_mode(adap, 0);
return i;

alloc_skb_fail:
t3_tp_set_offload_mode(adap, 0);
return -ENOMEM;
}

/**
Expand Down Expand Up @@ -871,7 +918,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
struct mngt_pktsched_wr *req;
int ret;

skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
skb = alloc_skb(sizeof(*req), GFP_KERNEL);
if (!skb)
skb = adap->nofail_skb;
if (!skb)
return -ENOMEM;

req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req));
req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT));
req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET;
Expand All @@ -881,6 +933,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
req->max = hi;
req->binding = port;
ret = t3_mgmt_tx(adap, skb);
if (skb == adap->nofail_skb) {
adap->nofail_skb = alloc_skb(sizeof(struct cpl_set_tcb_field),
GFP_KERNEL);
if (!adap->nofail_skb)
ret = -ENOMEM;
}

return ret;
}
Expand Down Expand Up @@ -3020,6 +3078,14 @@ static int __devinit init_one(struct pci_dev *pdev,
goto out_disable_device;
}

adapter->nofail_skb =
alloc_skb(sizeof(struct cpl_set_tcb_field), GFP_KERNEL);
if (!adapter->nofail_skb) {
dev_err(&pdev->dev, "cannot allocate nofail buffer\n");
err = -ENOMEM;
goto out_free_adapter;
}

adapter->regs = ioremap_nocache(mmio_start, mmio_len);
if (!adapter->regs) {
dev_err(&pdev->dev, "cannot map device registers\n");
Expand Down Expand Up @@ -3176,6 +3242,8 @@ static void __devexit remove_one(struct pci_dev *pdev)
free_netdev(adapter->port[i]);

iounmap(adapter->regs);
if (adapter->nofail_skb)
kfree_skb(adapter->nofail_skb);
kfree(adapter);
pci_release_regions(pdev);
pci_disable_device(pdev);
Expand Down
27 changes: 25 additions & 2 deletions trunk/drivers/net/cxgb3/cxgb3_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,13 +566,31 @@ static void t3_process_tid_release_list(struct work_struct *work)
spin_unlock_bh(&td->tid_release_lock);

skb = alloc_skb(sizeof(struct cpl_tid_release),
GFP_KERNEL | __GFP_NOFAIL);
GFP_KERNEL);
if (!skb)
skb = td->nofail_skb;
if (!skb) {
spin_lock_bh(&td->tid_release_lock);
p->ctx = (void *)td->tid_release_list;
td->tid_release_list = (struct t3c_tid_entry *)p;
break;
}
mk_tid_release(skb, p - td->tid_maps.tid_tab);
cxgb3_ofld_send(tdev, skb);
p->ctx = NULL;
if (skb == td->nofail_skb)
td->nofail_skb =
alloc_skb(sizeof(struct cpl_tid_release),
GFP_KERNEL);
spin_lock_bh(&td->tid_release_lock);
}
td->release_list_incomplete = (td->tid_release_list == NULL) ? 0 : 1;
spin_unlock_bh(&td->tid_release_lock);

if (!td->nofail_skb)
td->nofail_skb =
alloc_skb(sizeof(struct cpl_tid_release),
GFP_KERNEL);
}

/* use ctx as a next pointer in the tid release list */
Expand All @@ -585,7 +603,7 @@ void cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid)
p->ctx = (void *)td->tid_release_list;
p->client = NULL;
td->tid_release_list = p;
if (!p->ctx)
if (!p->ctx || td->release_list_incomplete)
schedule_work(&td->tid_release_task);
spin_unlock_bh(&td->tid_release_lock);
}
Expand Down Expand Up @@ -1274,6 +1292,9 @@ int cxgb3_offload_activate(struct adapter *adapter)
if (list_empty(&adapter_list))
register_netevent_notifier(&nb);

t->nofail_skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_KERNEL);
t->release_list_incomplete = 0;

add_adapter(adapter);
return 0;

Expand All @@ -1298,6 +1319,8 @@ void cxgb3_offload_deactivate(struct adapter *adapter)
T3C_DATA(tdev) = NULL;
t3_free_l2t(L2DATA(tdev));
L2DATA(tdev) = NULL;
if (t->nofail_skb)
kfree_skb(t->nofail_skb);
kfree(t);
}

Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/cxgb3/cxgb3_offload.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ struct t3c_data {
struct t3c_tid_entry *tid_release_list;
spinlock_t tid_release_lock;
struct work_struct tid_release_task;

struct sk_buff *nofail_skb;
unsigned int release_list_incomplete;
};

/*
Expand Down

0 comments on commit d4d36ea

Please sign in to comment.