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: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* A skb->len error-check was enabled (removed from a "#ifdef DEBUG" block).
* Several unneeded "#ifdef DEBUG" blocks were removed.
* A dev_err() was converted to the more-appropriate netdev_err().
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Previously we simplified the serverdown function to basically turn it
into a dev_close(), but missed the analogous logic in visornic_resume()
(which is essentially the "book-end" of visornic_serverdown_complete()).
As a result, during IO partition recovery, the nic would go closed when
the IO partition went away, but would never be opened again when the IO
partition came back.
This patch changes visornic_resume() to use dev_open(), so that it once
again plays nicely with visornic_serverdown_complete(). Because
dev_open() forces us into the visornic_open() path, other logic in
visornic_resume() was no longer necessary, and lended to simplifying
visornic_resume() even more.
Fixes: 36645d72a377 ("staging: unisys: simplify visornic_serverdown_complete")
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Because devdata->enab_dis_acked is the flag used to determine whether an
enable/disable operation to the IO partition has completed, it should
always be cleared prior to initiating the operation. The call added to
visornic_enable_with_timeout() added in this patch makes the usage there
consistent with visornic_disable_with_timeout().
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This makes sure the kthread name can't be parsed as a format string.
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This patch adds modalias files that export the device UUID type to sysfs
so that udev can autoload the appropriate device driver on demand. Note
that is required a minor name change to the channel device sysfs files
which are currently named visorbus_dev_groups, and are now named
visorbus_channel_groups.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This file has a lot of dead comments and needs to be cleaned up.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
After IO partition recovery, it was possible to get into a situation where
a visornic device would repeatedly report:
NETDEV WATCHDOG: eth0 (): transmit queue 0 timed out
The actual problem would affect any visornic device that was rapidly
transmitting at the same time the IO partition was being recovered. Once
you hit the problem, the only way to resume use of the nic would be to
reboot the Linux client partition.
The problem was caused by chstat.sent_xmit and chstat.got_xmit_done NOT
getting cleared during IO partition recovery. This is necessary because
outstanding xmits would essentially be "abandoned" during such recovery.
These fields are now cleared in virtnic_serverdown_complete().
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Logic to check for failures of visorchannel_signalinsert() and
visorchannel_signalremove() were added, and a new sent_post_failed counter
tracks the number of times we failed to post a rcv buffer to the IO
partition.
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
visornic tx reset handling is done asynchronously via a workqueue in
visornic_timeout_reset(). As a result, it needs to use rtnl_lock() /
rtnl_unlock() to lock against possible simultaneous close() of the network
device.
(I consulted the bnx2 driver as a model here, as that driver also does
its tx reset handling asynchronously, just like visornic does. See
bnx2_tx_timeout() and bnx2_reset_task().)
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
When s-Par is in polling mode it checks every 2 ms to see if there is
a response from the IO service partition in the queue. Currently it
just reads one entry per 2 ms, this needs to be changed so it drains
the queue on each check.
Signed-off-by: David Kershner <david.kershner@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The netdev we're testing for can't be removed, because its never
unregistered, so don't bother checking for it
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
All it does is return no supported. Removing the function entirely
accomplishes the same thing
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
dev_trans_start does this for us now
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Using NETDEV_TX_BUSY is tricky. Its meant for situations where the error
in question is transient and quickly resolved. But the driver rarely is
able to know that to a certainty. And in the case of visornic, it just
uses it without any care for that, in the hopes that it won't loose frames,
even if the problem is that the skb is somehow malformed for the hardware.
If we get one of those kinds of skbs, NETDEV_TX_BUSY will just cause us to
spin, processing the same error over and over.
Fix it by dropping the frame, stopping the queue where appropriate, and
returning NETDEV_TX_OK
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
If we put them in the enable and disable paths, we don't need them in
several other places
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
I don't see why the server should stop responding, or that we should just
give up if it does. Wait forever when enabling/disabling the visornic
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
I don't see why serverdown should be async on a workqueue. Just make it
synchronous, and remove some code in the process
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Theres a lot of code duplication going on in visornic_serverdown_complete.
We should just be able to send it through the dev_close path and have it
do the right things.
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Its possible to overwrite the old task pointer in visornic_resume. Add a
check to guard against that and a warning if we find that its already
running
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Remove the has_stopped completion as theres already one available
internally.
Correct the while loops
Remove the while loop in drain_queue as it already exists in the top level
loop
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
If we can't fit an skb into a frag array, linaraize it so we don't have to
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
We precheck that we have enough space in an iochannel prior to writing to
it when we send in a fragmented skb. Given that there is no recovery from
this condition that I can see, turn it into a BUG halt
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
One call site for visor_copy_fragsinfo_from_skb was checking for an rc of
-1, but thhe function doesn't return that, it returns -errno. Correct it
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
As pointed out in a recent review, the num_visornic_open array didn't do
anything useful, and it exposed a potential race in the visornic code that
could arise while taking down a net interface while reading from the
debugfs files. Fix that by removing the array entirely, and just iterating
over all the registered netdevs in a given namespace, filtering on them
having visornic ops (to identify which are ours), and having their queues
not be stopped (identifying that they are up). This should prevent any oops
conditions happening due to changing state in that array, and save us a
bunch of code too.
Signed-off-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The copyright statements in the drivers need to be correct and
consistent; this patch fixes the year for all of them, and makes the
statement text cover just the GPL V2.
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
We learned that it was possible for the core networking code to call
visornic_xmit() within ISR context, resulting in the need for us to
use spin_lock_irqsave() / spin_lock_irqrestore() to lock accesses to our
virtual device channels.
Without the correct locking added in this patch, random hangs would occur
on typical kernels while stressing the netork. When using a kernel with
CONFIG_DEBUG_SPINLOCK=y, a stackdump would occur at the time of the hang
reporting:
BUG: spinlock recursion on CPU#0, vnic_incoming/<pid>
(see below for more details)
We considered the possibility of adding a protocol between a visordriver
and visorbus where the visordriver could specify which type of locking it
required for its virtual device channels (essentially indicating whether
or not it was possible for the channel to be accessed in ISR context), but
decided this extra complexity was NOT needed, and that channel queues
should always be accessed with the most-stringent locking. So that is
what is implemented in this commit.
Below is an example stackdump illustrating the spinlock recursion that is
fixed by this commit. Note that we are first in virtnic_rx() writing to
the device channel when an APIC timer interrupt occurs. Within the core
networking code, net_rx_action() calls process_backlog(), which eventually
lands up back up in virtnic_xmit() in the code attempting to also write to
the device channel.
BUG: spinlock recursion on CPU#0, vnic_incoming/262
lock: 0xffff88002db810c0, .magic: dead4ead, .owner: vnic_incoming/262,
.owner_cpu: 0
CPU: 0 PID: 262 Comm: vnic_incoming
Tainted: G C 4.2.0-rc1-ARCH+ #56
Hardware name: Dell Inc. PowerEdge T110/ , BIOS 1.23 12/15/2009
ffff8800216ac200 ffff88002c803388 ffffffff81476364 0000000000000106
ffff88002db810c0 ffff88002c8033a8 ffffffff8109e2bc ffff88002db810c0
ffffffff817631d4 ffff88002c8033c8 ffffffff8109e330 ffff88002db810c0
Call Trace:
<IRQ> [<ffffffff81476364>] dump_stack+0x4f/0x73
[<ffffffff8109e2bc>] spin_dump+0x7c/0xc0
[<ffffffff8109e330>] spin_bug+0x30/0x40
[<ffffffff8109e547>] do_raw_spin_lock+0x127/0x140
[<ffffffff8147bad0>] _raw_spin_lock+0x40/0x50
[<ffffffffa0151fa6>] ? visorchannel_signalinsert+0x46/0x70 [visorbus]
[<ffffffffa0151fa6>] visorchannel_signalinsert+0x46/0x70 [visorbus]
[<ffffffffa01683a2>] visornic_xmit+0x302/0x5d0 [visornic]
[<ffffffff813b2f30>] dev_hard_start_xmit+0x2e0/0x510
[<ffffffff813b2b75>] ? validate_xmit_skb+0x235/0x310
[<ffffffff813d79e7>] sch_direct_xmit+0xf7/0x1d0
[<ffffffff813b34d3>] __dev_queue_xmit+0x203/0x640
[<ffffffff813b3320>] ? __dev_queue_xmit+0x50/0x640
[<ffffffff813f3f6f>] ? ip_finish_output+0x1df/0x310
[<ffffffff813b3933>] dev_queue_xmit_sk+0x13/0x20
[<ffffffff813f3a5c>] ip_finish_output2+0x22c/0x470
[<ffffffff813f3f6f>] ? ip_finish_output+0x1df/0x310
[<ffffffff810987e0>] ? __lock_is_held+0x50/0x70
[<ffffffff813f3f6f>] ip_finish_output+0x1df/0x310
[<ffffffff813f4c31>] ip_output+0xb1/0x100
[<ffffffff813f41be>] ip_local_out_sk+0x3e/0x80
[<ffffffff813f4388>] ip_queue_xmit+0x188/0x4a0
[<ffffffff813f4200>] ? ip_local_out_sk+0x80/0x80
[<ffffffff8139fcd6>] ? __alloc_skb+0x86/0x1e0
[<ffffffff8140bd5b>] tcp_transmit_skb+0x4cb/0x9c0
[<ffffffff8139f0dc>] ? __kmalloc_reserve+0x3c/0x90
[<ffffffff8139fcea>] ? __alloc_skb+0x9a/0x1e0
[<ffffffff8140c47d>] tcp_send_ack+0x10d/0x150
[<ffffffff814060ee>] __tcp_ack_snd_check+0x5e/0x90
[<ffffffff81408eb4>] tcp_rcv_established+0x354/0x710
[<ffffffff81412182>] tcp_v4_do_rcv+0x162/0x3f0
[<ffffffff81414412>] tcp_v4_rcv+0xb22/0xb50
[<ffffffff813ee2bc>] ? ip_local_deliver_finish+0x4c/0x2d0
[<ffffffff813ee350>] ip_local_deliver_finish+0xe0/0x2d0
[<ffffffff813ee2bc>] ? ip_local_deliver_finish+0x4c/0x2d0
[<ffffffff813ee72e>] ip_local_deliver+0xae/0xc0
[<ffffffff813edeaf>] ip_rcv_finish+0x14f/0x510
[<ffffffff813aab2d>] ? __netif_receive_skb_core+0x9d/0xb70
[<ffffffff813eea13>] ip_rcv+0x2d3/0x3b0
[<ffffffff81097110>] ? cpuacct_css_alloc+0xb0/0xb0
[<ffffffff813ab0f3>] __netif_receive_skb_core+0x663/0xb70
[<ffffffff813aab2d>] ? __netif_receive_skb_core+0x9d/0xb70
[<ffffffff810971a9>] ? cpuacct_charge+0x99/0xb0
[<ffffffff81097110>] ? cpuacct_css_alloc+0xb0/0xb0
[<ffffffff810987e0>] ? __lock_is_held+0x50/0x70
[<ffffffff813ab72c>] ? process_backlog+0xbc/0x150
[<ffffffff813ab78b>] ? process_backlog+0x11b/0x150
[<ffffffff813ab627>] __netif_receive_skb+0x27/0x70
[<ffffffff813ab702>] process_backlog+0x92/0x150
[<ffffffff813afffd>] net_rx_action+0x13d/0x350
[<ffffffff81036b2d>] ? lapic_next_event+0x1d/0x30
[<ffffffff81058694>] __do_softirq+0x104/0x320
[<ffffffff810c0788>] ? hrtimer_interrupt+0xc8/0x1a0
[<ffffffff81074e70>] ? blocking_notifier_chain_cond_register+0x70/0x70
[<ffffffff81058ab9>] irq_exit+0x79/0xa0
[<ffffffff8147ecca>] smp_apic_timer_interrupt+0x4a/0x60
[<ffffffff8147d2c8>] apic_timer_interrupt+0x68/0x70
<EOI> [<ffffffff81271c02>] ? __memcpy+0x12/0x20
[<ffffffffa01517da>] ? visorchannel_write+0x4a/0x80 [visorbus]
[<ffffffffa0151eb8>] signalinsert_inner+0x88/0x130 [visorbus]
[<ffffffffa0151fb5>] visorchannel_signalinsert+0x55/0x70 [visorbus]
[<ffffffffa0166e57>] visornic_rx+0x12e7/0x19d0 [visornic]
[<ffffffffa01677c9>] process_incoming_rsps+0x289/0x690 [visornic]
[<ffffffff814771c5>] ? preempt_schedule+0x25/0x30
[<ffffffff81001026>] ? ___preempt_schedule+0x12/0x14
[<ffffffff81093080>] ? wait_woken+0x90/0x90
[<ffffffffa0167540>] ? visornic_rx+0x19d0/0x19d0 [visornic]
[<ffffffffa0167540>] ? visornic_rx+0x19d0/0x19d0 [visornic]
[<ffffffff81073a39>] kthread+0xe9/0x110
[<ffffffff81073950>] ? __init_kthread_worker+0x70/0x70
[<ffffffff8147c89f>] ret_from_fork+0x3f/0x70
[<ffffffff81073950>] ? __init_kthread_worker+0x70/0x70
Fixes: b12fdf7da ('staging: unisys: rework signal remove/insert to avoid sparse lock warnings')
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
A visorchannel associated with a device should have its writing to
the channel protected by a lock.
Fixes: b32c4997c ('staging: unisys: Move channel creation up the stack')
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: David Kershner <david.kershner@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Remove some extra tabs in order to improve readalibility.
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This patch turns a kmalloc/memset into an equivalent kzalloc.
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
visorchannel_write() and it's user visorbus_write_channel() are
exported, so all visorbus function drivers (i.e., drivers that call
visorbus_register_visor_driver()) are potentially affected by the bug.
Because of pointer-arithmetic rules, the address being written to in the
affected code was actually at byte offset:
sizeof(struct channel_header) * offset
instead of just <offset> bytes as intended.
The bug could cause some very difficult-to-diagnose symptoms. The
particular problem that led me on this chase was a kernel fault that
would occur during 'insmod visornic' after a previous 'rmmod visornic',
where we would fault during netdev_register_kobject() within
pm_runtime_set_memalloc_noio() while traversing a device list, which
occurred because dev->parent for the visorbus device had become
corrupted.
Fixes: 0abb60c1c ('staging: unisys: visorchannel_write(): Handle...')
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Acked-by: Don Zickus <dzickus@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
I'm not sure what adverse runtime effects the previously-omitted
NULL-termination would cause, but the code was definitely wrong.
Fixes: 795731627c ('staging: unisys: Clean up device sysfs attributes')
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Acked-by: Don Zickus <dzickus@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
When building with ARCH=um you get the following error:
arch/x86/include/asm/cpufeature.h:252:42: error: 'REQUIRED_MASK0'
undeclared
The Unisys drivers should not be compiled for UML, so this patch addresses
that by adding a dependency to kconfig for !UML.
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Tested-by: Ken Cox <jkc@redhat.com>
Signed-off-by: Ken Cox <jkc@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
We inadvertently remove the MODULE_DEVICE_TABLE line for visorbus,
this patch adds it back in.
Signed-off-by: David Kershner <david.kershner@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Fixes: d5b3f1dccee4 ('staging: unisys: move timskmod.h functionality')
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
A struct visornic_devdata for each visornic device is actually allocated as
part of alloc_etherdev(), here in visornic_probe():
netdev = alloc_etherdev(sizeof(struct visornic_devdata));
But code in devdata_release() was treating devdata as a pointer that needed
to be kfree()d! This was causing all sorts of weird behavior after doing
an rmmod of visornic, both because free_netdev() was actually freeing the
memory used for devdata, and because devdata wasn't pointing to
dynamically-allocated memory in the first place.
The kfree(devdata) and the kref that tracked devdata's usage have been
appropriately deleted.
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Just switch this line so it uses the correct function call.
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This only makes sense, since the worker thread depends upon the netdev
existing.
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
visornic_cleanup() was previously incorrectly destroying its global
workqueues prior to cleaning up the devices which used them. This patch
corrects the order of these operations.
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
visornic_remove() is called to logically detach the visornic driver from a
visorbus-supplied device, which can happen either just prior to a
visorbus-supplied device disappearing, or as a result of an rmmod of
visornic. Prior to this patch, logic was missing to properly clean up for
this removal, which was fixed via the following changes:
* A going_away flag is now used to interlock between device destruction and
workqueue operations, protected by priv_lock. I.e., setting
going_away=true under lock guarantees that no new work items can get
queued to the work queues. going_away=true also short-circuits other
operations to enable device destruction to proceed.
* Missing clean-up operations for the workqueues, netdev, debugfs entries,
and the worker thread were added.
* Memory referenced from the visornic private devdata struct is now freed
as part of devdata destruction.
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Looks like an errant patch fitting caused us to redundantly allocate the
workqueues at both the beginning and end of visornic_init(). This was
corrected by removing the allocations at the beginning.
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Fixes: 68905a14e49c ('staging: unisys: Add s-Par visornic ethernet driver')
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Add error message to genuine rare error paths, and debug messages
to enable relatively non-verbose tracing of code paths
You can enable debug messages by including this on the kernel command line:
visornic.dyndbg=+p
or by this from the command line:
echo "module visornic +p" > <debugfs>/dynamic_debug/control
Refer to Documentation/dynamic-debug-howto.txt for more details.
In addition to the new debug and error messages, a message like the
following will be logged every time a visornic device is probed, which
will enable you to map back-and-forth between visorbus device names
(e.g., "vbus2:dev0") and netdev names (e.g., "eth0"):
visornic vbus2:dev0: visornic_probe success netdev=eth0
With this patch and visornic debugging enabled, you should expect to see
messages like the following in the most-common scenarios:
* driver loaded:
visornic_init
* device probed:
visornic vbus2:dev0: visornic_probe
visor_thread_start
visor_thread_start success
* network interface configured (ifconfig):
net eth0: visornic_open
net eth0: visornic_enable_with_timeout
net eth0: visornic_enable_with_timeout success
net eth0: visornic_open success
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Neglect to NULL rcvbuf pointer array could result in faults later
This problem would exhibit itself as a fault when when attempting to stop
any visornic device (i.e., in visornic_disable_with_timeout() or
visornic_serverdown_complete()) that had never been started (i.e., for
which init_rcv_bufs() had never been called). Because the array of rcvbuf
was never cleared to NULLs, we would mistakenly attempt to call kfree_skb()
on garbage memory.
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Prevent faults in visornic_pause, visornic_resume(), and visornic_remove()
Prior to this patch, any call to visornic_pause(), visornic_resume(), or
visornic_remove() would fault, due to dev_set_drvdata() never having been
called to stash our struct visornic_devdata * into the device's drvdata.
I.e., all calls to dev_get_drvdata() were returning NULL, meaning a fault
was soon to follow.
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Correct visornic_pause() to indicate completion asynchronously rather
than in-line
Previously, visornic_pause() (called to stop the device due to IOVM service
partition recovery) was calling the passed complete_func() in-line, rather
than delaying the calling until after the device had actually been stopped.
The behavior has been corrected so that the calling of the complete_func()
is now delayed until after the stopping of the device has been completed in
visornic_serverdown_complete(), which runs asynchronously via the workqueue
visornic_serverdown_workqueue.
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Prevent faults processing messages for devices that no driver has yet
registered to handle.
Previously, code of the form:
drv = to_visor_driver(dev->device.driver);
if (!drv)
goto away;
was not having the desired intent, because to_visor_driver() was
essentially returning garbage if its argument was NULL. The only existing
case of this is in initiate_chipset_device_pause_resume(), which is called
during IOVM service partition recovery. We were thus faulting when IOVM
service partition recovery was initiated on a bus that had at least one
device for which no function driver had registered
(visorbus_register_visor_driver).
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Fix problem that prevents us from responding to any device message after
device_create.
By neglecting to NULL out pending_msg_hdr after the device_create response,
we were effectively preventing any subsequent messages to the device from
working, because device_epilog() will correctly bail out early if it sees
that pending_msg_hdr is still set non-NULL, as that is an indicator to mean
that an unanswered message is still outstanding.
This problem was discovered as part of testing IOVM service partition
recovery, because device_epilog() was in fact bailing out when it was
called from my_device_changestate(), which of course prevented us from
transitioning the device to the paused state. However, the incorrect
behavior would occur for ANY subsequent command directed at the device,
not just for changestate.
Signed-off-by: Tim Sell <Timothy.Sell@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This fixes the memory corruption case, if nbytes is less than offset
and sizeof(struct channel_header)
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This driver creates a network device when s-Par sends a device
create message to create network adapter on the visorbus. When
the message is received by visorbus, the visornic_probe function
is called and the netdev device is created and managed by the
visornic driver.
Signed-off-by: David Kershner <david.kershner@unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>