Commit 36927c18 authored by Tim Sell's avatar Tim Sell Committed by Greg Kroah-Hartman

staging: unisys: visornic - consolidate+simplify xmit watermark checks

The code that tests for high and low xmit watermarks was consolidatedand
simplified. The output behavior should be identical, with the exception
of an off-by-one error being corrected in the tests done when the counters
overflowed.
Signed-off-by: default avatarTim Sell <Timothy.Sell@unisys.com>
Signed-off-by: default avatarBenjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent cb84fca0
...@@ -135,15 +135,16 @@ struct visornic_devdata { ...@@ -135,15 +135,16 @@ struct visornic_devdata {
atomic_t num_rcvbuf_in_iovm; atomic_t num_rcvbuf_in_iovm;
unsigned long alloc_failed_in_if_needed_cnt; unsigned long alloc_failed_in_if_needed_cnt;
unsigned long alloc_failed_in_repost_rtn_cnt; unsigned long alloc_failed_in_repost_rtn_cnt;
int max_outstanding_net_xmits; /* absolute max number of outstanding unsigned long max_outstanding_net_xmits; /* absolute max number of
* xmits - should never hit this * outstanding xmits - should
*/ * never hit this
int upper_threshold_net_xmits; /* high water mark for calling */
* netif_stop_queue() unsigned long upper_threshold_net_xmits; /* high water mark for
*/ * calling netif_stop_queue()
int lower_threshold_net_xmits; /* high water mark for calling */
* netif_wake_queue() unsigned long lower_threshold_net_xmits; /* high water mark for calling
*/ * netif_wake_queue()
*/
struct sk_buff_head xmitbufhead; /* xmitbufhead is the head of the struct sk_buff_head xmitbufhead; /* xmitbufhead is the head of the
* xmit buffer list that have been * xmit buffer list that have been
* sent to the IOPART end * sent to the IOPART end
...@@ -794,6 +795,53 @@ visornic_close(struct net_device *netdev) ...@@ -794,6 +795,53 @@ visornic_close(struct net_device *netdev)
return 0; return 0;
} }
/**
* devdata_xmits_outstanding - compute outstanding xmits
* @devdata: visornic_devdata for device
*
* Return value is the number of outstanding xmits.
*/
static unsigned long devdata_xmits_outstanding(struct visornic_devdata *devdata)
{
if (devdata->chstat.sent_xmit >= devdata->chstat.got_xmit_done)
return devdata->chstat.sent_xmit -
devdata->chstat.got_xmit_done;
else
return (ULONG_MAX - devdata->chstat.got_xmit_done
+ devdata->chstat.sent_xmit + 1);
}
/**
* vnic_hit_high_watermark
* @devdata: indicates visornic device we are checking
* @high_watermark: max num of unacked xmits we will tolerate,
* before we will start throttling
*
* Returns true iff the number of unacked xmits sent to
* the IO partition is >= high_watermark.
*/
static inline bool vnic_hit_high_watermark(struct visornic_devdata *devdata,
ulong high_watermark)
{
return (devdata_xmits_outstanding(devdata) >= high_watermark);
}
/**
* vnic_hit_low_watermark
* @devdata: indicates visornic device we are checking
* @low_watermark: we will wait until the num of unacked xmits
* drops to this value or lower before we start
* transmitting again
*
* Returns true iff the number of unacked xmits sent to
* the IO partition is <= low_watermark.
*/
static inline bool vnic_hit_low_watermark(struct visornic_devdata *devdata,
ulong low_watermark)
{
return (devdata_xmits_outstanding(devdata) <= low_watermark);
}
/** /**
* visornic_xmit - send a packet to the IO Partition * visornic_xmit - send a packet to the IO Partition
* @skb: Packet to be sent * @skb: Packet to be sent
...@@ -869,13 +917,8 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -869,13 +917,8 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev)
/* save the pointer to skb -- we'll need it for completion */ /* save the pointer to skb -- we'll need it for completion */
cmdrsp->net.buf = skb; cmdrsp->net.buf = skb;
if (((devdata->chstat.sent_xmit >= devdata->chstat.got_xmit_done) && if (vnic_hit_high_watermark(devdata,
(devdata->chstat.sent_xmit - devdata->chstat.got_xmit_done >= devdata->max_outstanding_net_xmits)) {
devdata->max_outstanding_net_xmits)) ||
((devdata->chstat.sent_xmit < devdata->chstat.got_xmit_done) &&
(ULONG_MAX - devdata->chstat.got_xmit_done +
devdata->chstat.sent_xmit >=
devdata->max_outstanding_net_xmits))) {
/* too many NET_XMITs queued over to IOVM - need to wait /* too many NET_XMITs queued over to IOVM - need to wait
*/ */
devdata->chstat.reject_count++; devdata->chstat.reject_count++;
...@@ -957,13 +1000,8 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -957,13 +1000,8 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev)
/* check to see if we have hit the high watermark for /* check to see if we have hit the high watermark for
* netif_stop_queue() * netif_stop_queue()
*/ */
if (((devdata->chstat.sent_xmit >= devdata->chstat.got_xmit_done) && if (vnic_hit_high_watermark(devdata,
(devdata->chstat.sent_xmit - devdata->chstat.got_xmit_done >= devdata->upper_threshold_net_xmits)) {
devdata->upper_threshold_net_xmits)) ||
((devdata->chstat.sent_xmit < devdata->chstat.got_xmit_done) &&
(ULONG_MAX - devdata->chstat.got_xmit_done +
devdata->chstat.sent_xmit >=
devdata->upper_threshold_net_xmits))) {
/* too many NET_XMITs queued over to IOVM - need to wait */ /* too many NET_XMITs queued over to IOVM - need to wait */
netif_stop_queue(netdev); /* calling stop queue - call netif_stop_queue(netdev); /* calling stop queue - call
* netif_wake_queue() after lower * netif_wake_queue() after lower
...@@ -1457,13 +1495,13 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, ...@@ -1457,13 +1495,13 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf,
" num_rcv_bufs = %d\n", " num_rcv_bufs = %d\n",
devdata->num_rcv_bufs); devdata->num_rcv_bufs);
str_pos += scnprintf(vbuf + str_pos, len - str_pos, str_pos += scnprintf(vbuf + str_pos, len - str_pos,
" max_oustanding_next_xmits = %d\n", " max_oustanding_next_xmits = %lu\n",
devdata->max_outstanding_net_xmits); devdata->max_outstanding_net_xmits);
str_pos += scnprintf(vbuf + str_pos, len - str_pos, str_pos += scnprintf(vbuf + str_pos, len - str_pos,
" upper_threshold_net_xmits = %d\n", " upper_threshold_net_xmits = %lu\n",
devdata->upper_threshold_net_xmits); devdata->upper_threshold_net_xmits);
str_pos += scnprintf(vbuf + str_pos, len - str_pos, str_pos += scnprintf(vbuf + str_pos, len - str_pos,
" lower_threshold_net_xmits = %d\n", " lower_threshold_net_xmits = %lu\n",
devdata->lower_threshold_net_xmits); devdata->lower_threshold_net_xmits);
str_pos += scnprintf(vbuf + str_pos, len - str_pos, str_pos += scnprintf(vbuf + str_pos, len - str_pos,
" queuefullmsg_logged = %d\n", " queuefullmsg_logged = %d\n",
...@@ -1562,6 +1600,9 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf, ...@@ -1562,6 +1600,9 @@ static ssize_t info_debugfs_read(struct file *file, char __user *buf,
" netif_queue = %s\n", " netif_queue = %s\n",
netif_queue_stopped(devdata->netdev) ? netif_queue_stopped(devdata->netdev) ?
"stopped" : "running"); "stopped" : "running");
str_pos += scnprintf(vbuf + str_pos, len - str_pos,
" xmits_outstanding = %lu\n",
devdata_xmits_outstanding(devdata));
} }
rcu_read_unlock(); rcu_read_unlock();
bytes_read = simple_read_from_buffer(buf, len, offset, vbuf, str_pos); bytes_read = simple_read_from_buffer(buf, len, offset, vbuf, str_pos);
...@@ -1655,16 +1696,8 @@ drain_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata) ...@@ -1655,16 +1696,8 @@ drain_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata)
* the lower watermark for * the lower watermark for
* netif_wake_queue() * netif_wake_queue()
*/ */
if (((devdata->chstat.sent_xmit >= if (vnic_hit_low_watermark(devdata,
devdata->chstat.got_xmit_done) && devdata->lower_threshold_net_xmits)) {
(devdata->chstat.sent_xmit -
devdata->chstat.got_xmit_done <=
devdata->lower_threshold_net_xmits)) ||
((devdata->chstat.sent_xmit <
devdata->chstat.got_xmit_done) &&
(ULONG_MAX - devdata->chstat.got_xmit_done
+ devdata->chstat.sent_xmit <=
devdata->lower_threshold_net_xmits))) {
/* enough NET_XMITs completed /* enough NET_XMITs completed
* so can restart netif queue * so can restart netif queue
*/ */
...@@ -1834,12 +1867,15 @@ static int visornic_probe(struct visor_device *dev) ...@@ -1834,12 +1867,15 @@ static int visornic_probe(struct visor_device *dev)
/* set the net_xmit outstanding threshold */ /* set the net_xmit outstanding threshold */
/* always leave two slots open but you should have 3 at a minimum */ /* always leave two slots open but you should have 3 at a minimum */
/* note that max_outstanding_net_xmits must be > 0 */
devdata->max_outstanding_net_xmits = devdata->max_outstanding_net_xmits =
max(3, ((devdata->num_rcv_bufs / 3) - 2)); max_t(unsigned long, 3, ((devdata->num_rcv_bufs / 3) - 2));
devdata->upper_threshold_net_xmits = devdata->upper_threshold_net_xmits =
max(2, devdata->max_outstanding_net_xmits - 1); max_t(unsigned long,
2, (devdata->max_outstanding_net_xmits - 1));
devdata->lower_threshold_net_xmits = devdata->lower_threshold_net_xmits =
max(1, devdata->max_outstanding_net_xmits / 2); max_t(unsigned long,
1, (devdata->max_outstanding_net_xmits / 2));
skb_queue_head_init(&devdata->xmitbufhead); skb_queue_head_init(&devdata->xmitbufhead);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment