* Re: [PATCHv5 3/3] vhost_net: a kernel-level virtio server
From: Gregory Haskins @ 2009-09-17 3:11 UTC (permalink / raw)
To: Avi Kivity
Cc: Michael S. Tsirkin, Ira W. Snyder, netdev, virtualization, kvm,
linux-kernel, mingo, linux-mm, akpm, hpa, Rusty Russell, s.hetze,
alacrityvm-devel
In-Reply-To: <4AB151D7.10402@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 12081 bytes --]
Avi Kivity wrote:
> On 09/16/2009 10:22 PM, Gregory Haskins wrote:
>> Avi Kivity wrote:
>>
>>> On 09/16/2009 05:10 PM, Gregory Haskins wrote:
>>>
>>>>> If kvm can do it, others can.
>>>>>
>>>>>
>>>> The problem is that you seem to either hand-wave over details like
>>>> this,
>>>> or you give details that are pretty much exactly what vbus does
>>>> already.
>>>> My point is that I've already sat down and thought about these
>>>> issues
>>>> and solved them in a freely available GPL'ed software package.
>>>>
>>>>
>>> In the kernel. IMO that's the wrong place for it.
>>>
>> 3) "in-kernel": You can do something like virtio-net to vhost to
>> potentially meet some of the requirements, but not all.
>>
>> In order to fully meet (3), you would need to do some of that stuff you
>> mentioned in the last reply with muxing device-nr/reg-nr. In addition,
>> we need to have a facility for mapping eventfds and establishing a
>> signaling mechanism (like PIO+qid), etc. KVM does this with
>> IRQFD/IOEVENTFD, but we dont have KVM in this case so it needs to be
>> invented.
>>
>
> irqfd/eventfd is the abstraction layer, it doesn't need to be reabstracted.
Not per se, but it needs to be interfaced. How do I register that
eventfd with the fastpath in Ira's rig? How do I signal the eventfd
(x86->ppc, and ppc->x86)?
To take it to the next level, how do I organize that mechanism so that
it works for more than one IO-stream (e.g. address the various queues
within ethernet or a different device like the console)? KVM has
IOEVENTFD and IRQFD managed with MSI and PIO. This new rig does not
have the luxury of an established IO paradigm.
Is vbus the only way to implement a solution? No. But it is _a_ way,
and its one that was specifically designed to solve this very problem
(as well as others).
(As an aside, note that you generally will want an abstraction on top of
irqfd/eventfd like shm-signal or virtqueues to do shared-memory based
event mitigation, but I digress. That is a separate topic).
>
>> To meet performance, this stuff has to be in kernel and there has to be
>> a way to manage it.
>
> and management belongs in userspace.
vbus does not dictate where the management must be. Its an extensible
framework, governed by what you plug into it (ala connectors and devices).
For instance, the vbus-kvm connector in alacrityvm chooses to put DEVADD
and DEVDROP hotswap events into the interrupt stream, because they are
simple and we already needed the interrupt stream anyway for fast-path.
As another example: venet chose to put ->call(MACQUERY) "config-space"
into its call namespace because its simple, and we already need
->calls() for fastpath. It therefore exports an attribute to sysfs that
allows the management app to set it.
I could likewise have designed the connector or device-model differently
as to keep the mac-address and hotswap-events somewhere else (QEMU/PCI
userspace) but this seems silly to me when they are so trivial, so I didn't.
>
>> Since vbus was designed to do exactly that, this is
>> what I would advocate. You could also reinvent these concepts and put
>> your own mux and mapping code in place, in addition to all the other
>> stuff that vbus does. But I am not clear why anyone would want to.
>>
>
> Maybe they like their backward compatibility and Windows support.
This is really not relevant to this thread, since we are talking about
Ira's hardware. But if you must bring this up, then I will reiterate
that you just design the connector to interface with QEMU+PCI and you
have that too if that was important to you.
But on that topic: Since you could consider KVM a "motherboard
manufacturer" of sorts (it just happens to be virtual hardware), I don't
know why KVM seems to consider itself the only motherboard manufacturer
in the world that has to make everything look legacy. If a company like
ASUS wants to add some cutting edge IO controller/bus, they simply do
it. Pretty much every product release may contain a different array of
devices, many of which are not backwards compatible with any prior
silicon. The guy/gal installing Windows on that system may see a "?" in
device-manager until they load a driver that supports the new chip, and
subsequently it works. It is certainly not a requirement to make said
chip somehow work with existing drivers/facilities on bare metal, per
se. Why should virtual systems be different?
So, yeah, the current design of the vbus-kvm connector means I have to
provide a driver. This is understood, and I have no problem with that.
The only thing that I would agree has to be backwards compatible is the
BIOS/boot function. If you can't support running an image like the
Windows installer, you are hosed. If you can't use your ethernet until
you get a chance to install a driver after the install completes, its
just like most other systems in existence. IOW: It's not a big deal.
For cases where the IO system is needed as part of the boot/install, you
provide BIOS and/or an install-disk support for it.
>
>> So no, the kernel is not the wrong place for it. Its the _only_ place
>> for it. Otherwise, just use (1) and be done with it.
>>
>>
>
> I'm talking about the config stuff, not the data path.
As stated above, where config stuff lives is a function of what you
interface to vbus. Data-path stuff must be in the kernel for
performance reasons, and this is what I was referring to. I think we
are generally both in agreement, here.
What I was getting at is that you can't just hand-wave the datapath
stuff. We do fast path in KVM with IRQFD/IOEVENTFD+PIO, and we do
device discovery/addressing with PCI. Neither of those are available
here in Ira's case yet the general concepts are needed. Therefore, we
have to come up with something else.
>
>>> Further, if we adopt
>>> vbus, if drop compatibility with existing guests or have to support both
>>> vbus and virtio-pci.
>>>
>> We already need to support both (at least to support Ira). virtio-pci
>> doesn't work here. Something else (vbus, or vbus-like) is needed.
>>
>
> virtio-ira.
Sure, virtio-ira and he is on his own to make a bus-model under that, or
virtio-vbus + vbus-ira-connector to use the vbus framework. Either
model can work, I agree.
>
>>>> So the question is: is your position that vbus is all wrong and you
>>>> wish
>>>> to create a new bus-like thing to solve the problem?
>>>>
>>> I don't intend to create anything new, I am satisfied with virtio. If
>>> it works for Ira, excellent. If not, too bad.
>>>
>> I think that about sums it up, then.
>>
>
> Yes. I'm all for reusing virtio, but I'm not going switch to vbus or
> support both for this esoteric use case.
With all due respect, no one asked you to. This sub-thread was
originally about using vhost in Ira's rig. When problems surfaced in
that proposed model, I highlighted that I had already addressed that
problem in vbus, and here we are.
>
>>>> If so, how is it
>>>> different from what Ive already done? More importantly, what specific
>>>> objections do you have to what Ive done, as perhaps they can be fixed
>>>> instead of starting over?
>>>>
>>>>
>>> The two biggest objections are:
>>> - the host side is in the kernel
>>>
>> As it needs to be.
>>
>
> vhost-net somehow manages to work without the config stuff in the kernel.
I was referring to data-path stuff, like signal and memory
configuration/routing.
As an aside, it should be noted that vhost under KVM has
IRQFD/IOEVENTFD, PCI-emulation, QEMU, etc to complement it and fill in
some of the pieces one needs for a complete solution. Not all
environments have all of those pieces (nor should they), and those
pieces need to come from somewhere.
It should also be noted that what remains (config/management) after the
data-path stuff is laid out is actually quite simple. It consists of
pretty much an enumerated list of device-ids within a container,
DEVADD(id), DEVDROP(id) events, and some sysfs attributes as defined on
a per-device basis (many of which are often needed regardless of whether
the "config-space" operation is handled in-kernel or not)
Therefore, the configuration aspect of the system does not necessitate a
complicated (e.g. full PCI emulation) or external (e.g. userspace)
component per se. The parts of vbus that could be construed as
"management" are (afaict) built using accepted/best-practices for
managing arbitrary kernel subsystems (sysfs, configfs, ioctls, etc) so
there is nothing new or reasonably controversial there. It is for this
reason that I think the objection to "in-kernel config" is unfounded.
Disagreements on this point may be settled by the connector design,
while still utilizing vbus, and thus retaining most of the other
benefits of using the vbus framework. The connector ultimately dictates
how and what is exposed to the "guest".
>
>> With all due respect, based on all of your comments in aggregate I
>> really do not think you are truly grasping what I am actually building
>> here.
>>
>
> Thanks.
>
>
>
>>>> Bingo. So now its a question of do you want to write this layer from
>>>> scratch, or re-use my framework.
>>>>
>>>>
>>> You will have to implement a connector or whatever for vbus as well.
>>> vbus has more layers so it's probably smaller for vbus.
>>>
>> Bingo!
>
> (addictive, isn't it)
Apparently.
>
>> That is precisely the point.
>>
>> All the stuff for how to map eventfds, handle signal mitigation, demux
>> device/function pointers, isolation, etc, are built in. All the
>> connector has to do is transport the 4-6 verbs and provide a memory
>> mapping/copy function, and the rest is reusable. The device models
>> would then work in all environments unmodified, and likewise the
>> connectors could use all device-models unmodified.
>>
>
> Well, virtio has a similar abstraction on the guest side. The host side
> abstraction is limited to signalling since all configuration is in
> userspace. vhost-net ought to work for lguest and s390 without change.
But IIUC that is primarily because the revectoring work is already in
QEMU for virtio-u and it rides on that, right? Not knocking that, thats
nice and a distinct advantage. It should just be noted that its based
on sunk-cost, and not truly free. Its just already paid for, which is
different. It also means it only works in environments based on QEMU,
which not all are (as evident by this sub-thread).
>
>>> It was already implemented three times for virtio, so apparently that's
>>> extensible too.
>>>
>> And to my point, I'm trying to commoditize as much of that process as
>> possible on both the front and backends (at least for cases where
>> performance matters) so that you don't need to reinvent the wheel for
>> each one.
>>
>
> Since you're interested in any-to-any connectors it makes sense to you.
> I'm only interested in kvm-host-to-kvm-guest, so reducing the already
> minor effort to implement a new virtio binding has little appeal to me.
>
Fair enough.
>>> You mean, if the x86 board was able to access the disks and dma into the
>>> ppb boards memory? You'd run vhost-blk on x86 and virtio-net on ppc.
>>>
>> But as we discussed, vhost doesn't work well if you try to run it on the
>> x86 side due to its assumptions about pagable "guest" memory, right? So
>> is that even an option? And even still, you would still need to solve
>> the aggregation problem so that multiple devices can coexist.
>>
>
> I don't know. Maybe it can be made to work and maybe it cannot. It
> probably can with some determined hacking.
>
I guess you can say the same for any of the solutions.
Kind Regards,
-Greg
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 267 bytes --]
^ permalink raw reply
* question about tcp_ack_update_window
From: hong liu @ 2009-09-17 3:24 UTC (permalink / raw)
To: netdev
Hi,
In tcp_ack_update_window, we don't scale the window if it's a SYN packet.
This modification is introduced by Kevin Lahey during 2.5.75
(http://oss.sgi.com/archives/netdev/2003-10/msg01391.html).
tcp_ack_update_window is only called by tcp_ack, which is called by
tcp_rcv_synsent_state_process & tcp_rcv_established, and we change the
snd_wnd back to th->window in tcp_rcv_synsent_state_process, so why we
still need this check in tcp_ack_update_window?
I think we may need to add tp->max_window = tp->snd_wnd in
tcp_rcv_syssent_state_process if we remove the check in tcp_ack_update_window.
The only problem I can see is: client entered into established state and sent
an ack (the last packet in 3-way handershake) to the server, but the packet
got lost / arrived slightly late. Then server resent a SYN+ACK packet,
then client can get a SYN packet and call tcp_ack in tcp_rcv_established.
Is this the only concern?
Thanks,
Hong
^ permalink raw reply
* Re: [PATCH] ks8851_ml ethernet network driver
From: David Miller @ 2009-09-17 3:48 UTC (permalink / raw)
To: greg; +Cc: netdev, Charles.Li, Choi, David.Choi, jgarzik, shemminger
In-Reply-To: <20090917023836.GA15260@kroah.com>
From: Greg KH <greg@kroah.com>
Date: Wed, 16 Sep 2009 19:38:36 -0700
> From: Choi, David <David.Choi@Micrel.Com>
>
> This is a network driver for the ks8851 16bit MLL ethernet device.
>
> Signed-off-by: David J. Choi <david.choi@micrel.com>
> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This doesn't even build cleanly:
drivers/net/ks8851_mll.c: In function ‘ks_inblk’:
drivers/net/ks8851_mll.c:555: warning: cast from pointer to integer of different size
drivers/net/ks8851_mll.c:558: warning: passing argument 1 of ‘_readw’ makes pointer from integer without a cast
drivers/net/ks8851_mll.c: In function ‘ks_outblk’:
drivers/net/ks8851_mll.c:571: warning: cast from pointer to integer of different size
drivers/net/ks8851_mll.c:574: warning: passing argument 2 of ‘_writew’ makes pointer from integer without a cast
It also has a big "#define DEBUG" at the beginning of the driver.
And it also has stuff like:
+#define MALLOC(x) kmalloc(x, GFP_KERNEL)
which actually decreases the readability of this driver.
Please fix this up.
^ permalink raw reply
* Re: [PATCH 1/2] wl12xx: switch to %pM to print the mac address
From: David Miller @ 2009-09-17 3:51 UTC (permalink / raw)
To: linville; +Cc: plagnioj, netdev
In-Reply-To: <20090917002852.GE14393@tuxdriver.com>
From: "John W. Linville" <linville@tuxdriver.com>
Date: Wed, 16 Sep 2009 20:28:52 -0400
> On Thu, Sep 17, 2009 at 02:07:38AM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
>> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
...
>
> ACK
Applied.
^ permalink raw reply
* Re: [PATCH 2/2] net: remove print_mac as it's not anymore used
From: David Miller @ 2009-09-17 3:51 UTC (permalink / raw)
To: plagnioj; +Cc: netdev
In-Reply-To: <1253146059-4169-2-git-send-email-plagnioj@jcrosoft.com>
From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Date: Thu, 17 Sep 2009 02:07:39 +0200
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Applied.
^ permalink raw reply
* Re: [PATCH 2/2] net: remove print_mac as it's not anymore used
From: David Miller @ 2009-09-17 3:54 UTC (permalink / raw)
To: plagnioj; +Cc: netdev
In-Reply-To: <20090916.205159.191998627.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Wed, 16 Sep 2009 20:51:59 -0700 (PDT)
> From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> Date: Thu, 17 Sep 2009 02:07:39 +0200
>
>> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
>
> Applied.
Actually I had to revert. It's still used by the FCOE stack in
the scsi layer.
Did you actually run grep on the entire tree to see if it's still used
anywhere or did you only check drivers/net/ and net/ or something
equally lazy?
^ permalink raw reply
* Re: [GIT PULL 0/2] Fixes for IEEE 802.15.4
From: David Miller @ 2009-09-17 3:55 UTC (permalink / raw)
To: dbaryshkov; +Cc: linux-zigbee-devel, slapin, netdev
In-Reply-To: <1253107333-25043-1-git-send-email-dbaryshkov@gmail.com>
From: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Date: Wed, 16 Sep 2009 17:22:11 +0400
> Hi, David,
>
> Please pull both into net/master and net-next/master (as I'd like
> to submit few patches into net-next/master depending on this).
>
> The following changes since commit 4e36a95e591e9c58dd10bb4103c00993917c27fd:
> David Howells (1):
> RxRPC: Use uX/sX rather than uintX_t/intX_t types
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git for-linus
Pulled thanks.
^ permalink raw reply
* Re: [PATCHv5 3/3] vhost_net: a kernel-level virtio server
From: Michael S. Tsirkin @ 2009-09-17 3:57 UTC (permalink / raw)
To: Gregory Haskins
Cc: Avi Kivity, Ira W. Snyder, netdev, virtualization, kvm,
linux-kernel, mingo, linux-mm, akpm, hpa, Rusty Russell, s.hetze,
alacrityvm-devel
In-Reply-To: <4AB0F1EF.5050102@gmail.com>
On Wed, Sep 16, 2009 at 10:10:55AM -0400, Gregory Haskins wrote:
> > There is no role reversal.
>
> So if I have virtio-blk driver running on the x86 and vhost-blk device
> running on the ppc board, I can use the ppc board as a block-device.
> What if I really wanted to go the other way?
It seems ppc is the only one that can initiate DMA to an arbitrary
address, so you can't do this really, or you can by tunneling each
request back to ppc, or doing an extra data copy, but it's unlikely to
work well.
The limitation comes from hardware, not from the API we use.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [patch 0/7] s390: iucv / af_iucv fixes for 2.6.31+
From: David Miller @ 2009-09-17 3:58 UTC (permalink / raw)
To: ursula.braun; +Cc: netdev, linux-s390, schwidefsky, heiko.carstens
In-Reply-To: <20090916143721.863799000@linux.vnet.ibm.com>
From: Ursula Braun <ursula.braun@de.ibm.com>
Date: Wed, 16 Sep 2009 16:37:21 +0200
> Summary:
>
> Ursula Braun (1)
> iucv: suspend/resume error msg for left over pathes
>
> Hendrik Brueckner (6)
> iucv: fix iucv_buffer_cpumask check when calling IUCV functions
> iucv: use correct output register in iucv_query_maxconn()
> af_iucv: fix race in __iucv_sock_wait()
> af_iucv: handle non-accepted sockets after resuming from suspend
> af_iucv: do not call iucv_sock_kill() twice
> af_iucv: fix race when queueing skbs on the backlog queue
All applied, thank you.
^ permalink raw reply
* Re: [PATCH] ks8851_ml ethernet network driver
From: Stephen Hemminger @ 2009-09-17 4:03 UTC (permalink / raw)
To: Li, Charles; +Cc: Greg KH, netdev, David S. Miller, Choi, David, Jeff Garzik
In-Reply-To: <20090917023836.GA15260@kroah.com>
On Wed, 16 Sep 2009 19:38:36 -0700
Greg KH <greg@kroah.com> wrote:
> /**
> + * ks_irq - device interrupt handler
> + * @irq: Interrupt number passed from the IRQ hnalder.
> + * @pw: The private word passed to register_irq(), our struct ks_net.
> + *
> + * This is the handler invoked to find out what happened
> + *
> + * Read the interrupt status, work out what needs to be done and then clear
> + * any of the interrupts that are not needed.
> + */
> +
> +static irqreturn_t ks_irq(int irq, void *pw)
> +{
> + struct ks_net *ks = pw;
> + struct net_device *netdev = ks->netdev;
> + u16 status;
> +
> + /*this should be the first in IRQ handler */
> + ks_save_cmd_reg(ks);
> +
> + status = ks_rdreg16(ks, KS_ISR);
> + ks_wrreg16(ks, KS_ISR, status);
if status == 0 or status == ~0 then device should not return IRQ_HANDLED.
In the former case, the IRQ is shared, in later case the device is not present
on the bus (hotplug).
^ permalink raw reply
* Re: [PATCH] ks8851_ml ethernet network driver
From: Stephen Hemminger @ 2009-09-17 4:07 UTC (permalink / raw)
To: Greg KH, Li, Charles; +Cc: netdev, David S. Miller, Choi, David, Jeff Garzik
In-Reply-To: <20090917023836.GA15260@kroah.com>
On Wed, 16 Sep 2009 19:38:36 -0700
Greg KH <greg@kroah.com> wrote:
> +
> +/**
> + * ks_net_open - open network device
> + * @netdev: The network device being opened.
> + *
> + * Called when the network device is marked active, such as a user executing
> + * 'ifconfig up' on the device.
> + */
> +static int ks_net_open(struct net_device *netdev)
> +{
> + struct ks_net *ks = netdev_priv(netdev);
> + int err;
> +
> +#define KS_INT_FLAGS (IRQF_DISABLED|IRQF_TRIGGER_LOW)
> + /* lock the card, even if we may not actually do anything
> + * else at the moment.
> + */
> + mutex_lock(&ks->lock);
> +
I don't understand the purpose of ks->lock mutex. What is it
really protecting? open/close are already protected by rtnl_mutex,
is it really only for the PHY?
^ permalink raw reply
* Re: [PATCHv5 3/3] vhost_net: a kernel-level virtio server
From: Gregory Haskins @ 2009-09-17 4:13 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Avi Kivity, Ira W. Snyder, netdev, virtualization, kvm,
linux-kernel, mingo, linux-mm, akpm, hpa, Rusty Russell, s.hetze,
alacrityvm-devel
In-Reply-To: <20090917035717.GB3088@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 1561 bytes --]
Michael S. Tsirkin wrote:
> On Wed, Sep 16, 2009 at 10:10:55AM -0400, Gregory Haskins wrote:
>>> There is no role reversal.
>> So if I have virtio-blk driver running on the x86 and vhost-blk device
>> running on the ppc board, I can use the ppc board as a block-device.
>> What if I really wanted to go the other way?
>
> It seems ppc is the only one that can initiate DMA to an arbitrary
> address, so you can't do this really, or you can by tunneling each
> request back to ppc, or doing an extra data copy, but it's unlikely to
> work well.
>
> The limitation comes from hardware, not from the API we use.
Understood, but presumably it can be exposed as a sub-function of the
ppc's board's register file as a DMA-controller service to the x86.
This would fall into the "tunnel requests back" category you mention
above, though I think "tunnel" implies a heavier protocol than it would
actually require. This would look more like a PIO cycle to a DMA
controller than some higher layer protocol.
You would then utilize that DMA service inside the memctx, and it the
rest of vbus would work transparently with the existing devices/drivers.
I do agree it would require some benchmarking to determine its
feasibility, which is why I was careful to say things like "may work"
;). I also do not even know if its possible to expose the service this
way on his system. If this design is not possible or performs poorly, I
admit vbus is just as hosed as vhost in regard to the "role correction"
benefit.
Kind Regards,
-Greg
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 267 bytes --]
^ permalink raw reply
* [net-next-2.6 PATCH] be2net: fix some cmds to use mccq instead of mbox
From: Sathya Perla @ 2009-09-17 4:43 UTC (permalink / raw)
To: netdev
All cmds issued to BE after the creation of mccq must now use the mcc-q
(and not mbox) to avoid a hw issue that results in mbox poll timeout.
Signed-off-by: Sathya Perla <sathyap@serverengines.com>
---
drivers/net/benet/be.h | 1 +
drivers/net/benet/be_cmds.c | 412 ++++++++++++++++++++++++++-----------------
drivers/net/benet/be_cmds.h | 5 +-
drivers/net/benet/be_main.c | 42 +++---
4 files changed, 271 insertions(+), 189 deletions(-)
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 13b72ce..684c6fe 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -362,5 +362,6 @@ static inline u8 is_udp_pkt(struct sk_buff *skb)
extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
u16 num_popped);
extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
+extern void netdev_stats_update(struct be_adapter *adapter);
extern int be_load_fw(struct be_adapter *adapter, u8 *func);
#endif /* BE_H */
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 1db0924..3dd76c4 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -59,15 +59,22 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
CQE_STATUS_COMPL_MASK;
- if (compl_status != MCC_STATUS_SUCCESS) {
+ if (compl_status == MCC_STATUS_SUCCESS) {
+ if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
+ struct be_cmd_resp_get_stats *resp =
+ adapter->stats.cmd.va;
+ be_dws_le_to_cpu(&resp->hw_stats,
+ sizeof(resp->hw_stats));
+ netdev_stats_update(adapter);
+ }
+ } else if (compl_status != MCC_STATUS_NOT_SUPPORTED) {
extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
CQE_STATUS_EXTD_MASK;
dev_warn(&adapter->pdev->dev,
"Error in cmd completion: status(compl/extd)=%d/%d\n",
compl_status, extd_status);
- return -1;
}
- return 0;
+ return compl_status;
}
/* Link state evt is a string of bytes; no need for endian swapping */
@@ -97,10 +104,10 @@ static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
return NULL;
}
-void be_process_mcc(struct be_adapter *adapter)
+int be_process_mcc(struct be_adapter *adapter)
{
struct be_mcc_compl *compl;
- int num = 0;
+ int num = 0, status = 0;
spin_lock_bh(&adapter->mcc_cq_lock);
while ((compl = be_mcc_compl_get(adapter))) {
@@ -111,38 +118,47 @@ void be_process_mcc(struct be_adapter *adapter)
/* Interpret compl as a async link evt */
be_async_link_state_process(adapter,
(struct be_async_event_link_state *) compl);
- } else {
- be_mcc_compl_process(adapter, compl);
- atomic_dec(&adapter->mcc_obj.q.used);
+ } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
+ status = be_mcc_compl_process(adapter, compl);
+ atomic_dec(&adapter->mcc_obj.q.used);
}
be_mcc_compl_use(compl);
num++;
}
+
if (num)
be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, num);
+
spin_unlock_bh(&adapter->mcc_cq_lock);
+ return status;
}
/* Wait till no more pending mcc requests are present */
-static void be_mcc_wait_compl(struct be_adapter *adapter)
+static int be_mcc_wait_compl(struct be_adapter *adapter)
{
-#define mcc_timeout 50000 /* 5s timeout */
- int i;
+#define mcc_timeout 120000 /* 12s timeout */
+ int i, status;
for (i = 0; i < mcc_timeout; i++) {
- be_process_mcc(adapter);
+ status = be_process_mcc(adapter);
+ if (status)
+ return status;
+
if (atomic_read(&adapter->mcc_obj.q.used) == 0)
break;
udelay(100);
}
- if (i == mcc_timeout)
+ if (i == mcc_timeout) {
dev_err(&adapter->pdev->dev, "mccq poll timed out\n");
+ return -1;
+ }
+ return 0;
}
/* Notify MCC requests and wait for completion */
-static void be_mcc_notify_wait(struct be_adapter *adapter)
+static int be_mcc_notify_wait(struct be_adapter *adapter)
{
be_mcc_notify(adapter);
- be_mcc_wait_compl(adapter);
+ return be_mcc_wait_compl(adapter);
}
static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
@@ -173,7 +189,7 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
* Insert the mailbox address into the doorbell in two steps
* Polls on the mbox doorbell till a command completion (or a timeout) occurs
*/
-static int be_mbox_notify(struct be_adapter *adapter)
+static int be_mbox_notify_wait(struct be_adapter *adapter)
{
int status;
u32 val = 0;
@@ -182,8 +198,6 @@ static int be_mbox_notify(struct be_adapter *adapter)
struct be_mcc_mailbox *mbox = mbox_mem->va;
struct be_mcc_compl *compl = &mbox->compl;
- memset(compl, 0, sizeof(*compl));
-
val |= MPU_MAILBOX_DB_HI_MASK;
/* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
@@ -310,34 +324,40 @@ static u32 eq_delay_to_mult(u32 usec_delay)
return multiplier;
}
-static inline struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem)
+static inline struct be_mcc_wrb *wrb_from_mbox(struct be_adapter *adapter)
{
- return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
+ struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
+ struct be_mcc_wrb *wrb
+ = &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
+ memset(wrb, 0, sizeof(*wrb));
+ return wrb;
}
-static inline struct be_mcc_wrb *wrb_from_mcc(struct be_queue_info *mccq)
+static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter)
{
- struct be_mcc_wrb *wrb = NULL;
- if (atomic_read(&mccq->used) < mccq->len) {
- wrb = queue_head_node(mccq);
- queue_head_inc(mccq);
- atomic_inc(&mccq->used);
- memset(wrb, 0, sizeof(*wrb));
- }
+ struct be_queue_info *mccq = &adapter->mcc_obj.q;
+ struct be_mcc_wrb *wrb;
+
+ BUG_ON(atomic_read(&mccq->used) >= mccq->len);
+ wrb = queue_head_node(mccq);
+ queue_head_inc(mccq);
+ atomic_inc(&mccq->used);
+ memset(wrb, 0, sizeof(*wrb));
return wrb;
}
int be_cmd_eq_create(struct be_adapter *adapter,
struct be_queue_info *eq, int eq_delay)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_eq_create *req = embedded_payload(wrb);
- struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_eq_create *req;
struct be_dma_mem *q_mem = &eq->dma_mem;
int status;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -359,25 +379,29 @@ int be_cmd_eq_create(struct be_adapter *adapter,
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
- status = be_mbox_notify(adapter);
+ status = be_mbox_notify_wait(adapter);
if (!status) {
+ struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
eq->id = le16_to_cpu(resp->eq_id);
eq->created = true;
}
+
spin_unlock(&adapter->mbox_lock);
return status;
}
+/* Uses mbox */
int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
u8 type, bool permanent, u32 if_handle)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_mac_query *req = embedded_payload(wrb);
- struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_mac_query *req;
int status;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -388,27 +412,32 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
if (permanent) {
req->permanent = 1;
} else {
- req->if_id = cpu_to_le16((u16)if_handle);
+ req->if_id = cpu_to_le16((u16) if_handle);
req->permanent = 0;
}
- status = be_mbox_notify(adapter);
- if (!status)
+ status = be_mbox_notify_wait(adapter);
+ if (!status) {
+ struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
+ }
spin_unlock(&adapter->mbox_lock);
return status;
}
+/* Uses synchronous MCCQ */
int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
u32 if_id, u32 *pmac_id)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_pmac_add *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_pmac_add *req;
int status;
- spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -418,24 +447,27 @@ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
req->if_id = cpu_to_le32(if_id);
memcpy(req->mac_address, mac_addr, ETH_ALEN);
- status = be_mbox_notify(adapter);
+ status = be_mcc_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_pmac_add *resp = embedded_payload(wrb);
*pmac_id = le32_to_cpu(resp->pmac_id);
}
- spin_unlock(&adapter->mbox_lock);
+ spin_unlock_bh(&adapter->mcc_lock);
return status;
}
+/* Uses synchronous MCCQ */
int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_pmac_del *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_pmac_del *req;
int status;
- spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -445,25 +477,29 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id)
req->if_id = cpu_to_le32(if_id);
req->pmac_id = cpu_to_le32(pmac_id);
- status = be_mbox_notify(adapter);
- spin_unlock(&adapter->mbox_lock);
+ status = be_mcc_notify_wait(adapter);
+
+ spin_unlock_bh(&adapter->mcc_lock);
return status;
}
+/* Uses Mbox */
int be_cmd_cq_create(struct be_adapter *adapter,
struct be_queue_info *cq, struct be_queue_info *eq,
bool sol_evts, bool no_delay, int coalesce_wm)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_cq_create *req = embedded_payload(wrb);
- struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_cq_create *req;
struct be_dma_mem *q_mem = &cq->dma_mem;
- void *ctxt = &req->context;
+ void *ctxt;
int status;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
+ ctxt = &req->context;
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -486,11 +522,13 @@ int be_cmd_cq_create(struct be_adapter *adapter,
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
- status = be_mbox_notify(adapter);
+ status = be_mbox_notify_wait(adapter);
if (!status) {
+ struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
cq->id = le16_to_cpu(resp->cq_id);
cq->created = true;
}
+
spin_unlock(&adapter->mbox_lock);
return status;
@@ -508,14 +546,17 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
struct be_queue_info *mccq,
struct be_queue_info *cq)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_mcc_create *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_mcc_create *req;
struct be_dma_mem *q_mem = &mccq->dma_mem;
- void *ctxt = &req->context;
+ void *ctxt;
int status;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
+ ctxt = &req->context;
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -534,7 +575,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
- status = be_mbox_notify(adapter);
+ status = be_mbox_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
mccq->id = le16_to_cpu(resp->id);
@@ -549,15 +590,17 @@ int be_cmd_txq_create(struct be_adapter *adapter,
struct be_queue_info *txq,
struct be_queue_info *cq)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_eth_tx_create *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_eth_tx_create *req;
struct be_dma_mem *q_mem = &txq->dma_mem;
- void *ctxt = &req->context;
+ void *ctxt;
int status;
- u32 len_encoded;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
+ ctxt = &req->context;
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -568,10 +611,8 @@ int be_cmd_txq_create(struct be_adapter *adapter,
req->ulp_num = BE_ULP1_NUM;
req->type = BE_ETH_TX_RING_TYPE_STANDARD;
- len_encoded = fls(txq->len); /* log2(len) + 1 */
- if (len_encoded == 16)
- len_encoded = 0;
- AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, len_encoded);
+ AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt,
+ be_encoded_q_len(txq->len));
AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt,
be_pci_func(adapter));
AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1);
@@ -581,28 +622,32 @@ int be_cmd_txq_create(struct be_adapter *adapter,
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
- status = be_mbox_notify(adapter);
+ status = be_mbox_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb);
txq->id = le16_to_cpu(resp->cid);
txq->created = true;
}
+
spin_unlock(&adapter->mbox_lock);
return status;
}
+/* Uses mbox */
int be_cmd_rxq_create(struct be_adapter *adapter,
struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
u16 max_frame_size, u32 if_id, u32 rss)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_eth_rx_create *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_eth_rx_create *req;
struct be_dma_mem *q_mem = &rxq->dma_mem;
int status;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -617,29 +662,34 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
req->max_frame_size = cpu_to_le16(max_frame_size);
req->rss_queue = cpu_to_le32(rss);
- status = be_mbox_notify(adapter);
+ status = be_mbox_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb);
rxq->id = le16_to_cpu(resp->id);
rxq->created = true;
}
+
spin_unlock(&adapter->mbox_lock);
return status;
}
-/* Generic destroyer function for all types of queues */
+/* Generic destroyer function for all types of queues
+ * Uses Mbox
+ */
int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
int queue_type)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_q_destroy *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_q_destroy *req;
u8 subsys = 0, opcode = 0;
int status;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
+
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
switch (queue_type) {
@@ -669,23 +719,27 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req));
req->id = cpu_to_le16(q->id);
- status = be_mbox_notify(adapter);
+ status = be_mbox_notify_wait(adapter);
spin_unlock(&adapter->mbox_lock);
return status;
}
-/* Create an rx filtering policy configuration on an i/f */
+/* Create an rx filtering policy configuration on an i/f
+ * Uses mbox
+ */
int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_if_create *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_if_create *req;
int status;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -694,10 +748,11 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
req->capability_flags = cpu_to_le32(flags);
req->enable_flags = cpu_to_le32(flags);
+ req->pmac_invalid = pmac_invalid;
if (!pmac_invalid)
memcpy(req->mac_addr, mac, ETH_ALEN);
- status = be_mbox_notify(adapter);
+ status = be_mbox_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_if_create *resp = embedded_payload(wrb);
*if_handle = le32_to_cpu(resp->interface_id);
@@ -709,14 +764,17 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
return status;
}
+/* Uses mbox */
int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_if_destroy *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_if_destroy *req;
int status;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -724,7 +782,8 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req));
req->interface_id = cpu_to_le32(interface_id);
- status = be_mbox_notify(adapter);
+
+ status = be_mbox_notify_wait(adapter);
spin_unlock(&adapter->mbox_lock);
@@ -733,20 +792,22 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
/* Get stats is a non embedded command: the request is not embedded inside
* WRB but is a separate dma memory block
+ * Uses asynchronous MCC
*/
int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_get_stats *req = nonemb_cmd->va;
- struct be_sge *sge = nonembedded_sgl(wrb);
- int status;
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_get_stats *req;
+ struct be_sge *sge;
- spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+ spin_lock_bh(&adapter->mcc_lock);
- memset(req, 0, sizeof(*req));
+ wrb = wrb_from_mccq(adapter);
+ req = nonemb_cmd->va;
+ sge = nonembedded_sgl(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
+ wrb->tag0 = OPCODE_ETH_GET_STATISTICS;
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
OPCODE_ETH_GET_STATISTICS, sizeof(*req));
@@ -754,59 +815,61 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
sge->len = cpu_to_le32(nonemb_cmd->size);
- status = be_mbox_notify(adapter);
- if (!status) {
- struct be_cmd_resp_get_stats *resp = nonemb_cmd->va;
- be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats));
- }
+ be_mcc_notify(adapter);
- spin_unlock(&adapter->mbox_lock);
- return status;
+ spin_unlock_bh(&adapter->mcc_lock);
+ return 0;
}
+/* Uses synchronous mcc */
int be_cmd_link_status_query(struct be_adapter *adapter,
bool *link_up)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_link_status *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_link_status *req;
int status;
- spin_lock(&adapter->mbox_lock);
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ req = embedded_payload(wrb);
*link_up = false;
- memset(wrb, 0, sizeof(*wrb));
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req));
- status = be_mbox_notify(adapter);
+ status = be_mcc_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
if (resp->mac_speed != PHY_LINK_SPEED_ZERO)
*link_up = true;
}
- spin_unlock(&adapter->mbox_lock);
+ spin_unlock_bh(&adapter->mcc_lock);
return status;
}
+/* Uses Mbox */
int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_get_fw_version *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_get_fw_version *req;
int status;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_GET_FW_VERSION, sizeof(*req));
- status = be_mbox_notify(adapter);
+ status = be_mbox_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN);
@@ -816,15 +879,18 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
return status;
}
-/* set the EQ delay interval of an EQ to specified value */
+/* set the EQ delay interval of an EQ to specified value
+ * Uses async mcc
+ */
int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_modify_eq_delay *req = embedded_payload(wrb);
- int status;
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_modify_eq_delay *req;
- spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -836,21 +902,24 @@ int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd)
req->delay[0].phase = 0;
req->delay[0].delay_multiplier = cpu_to_le32(eqd);
- status = be_mbox_notify(adapter);
+ be_mcc_notify(adapter);
- spin_unlock(&adapter->mbox_lock);
- return status;
+ spin_unlock_bh(&adapter->mcc_lock);
+ return 0;
}
+/* Uses sycnhronous mcc */
int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
u32 num, bool untagged, bool promiscuous)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_vlan_config *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_vlan_config *req;
int status;
- spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -866,23 +935,24 @@ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
req->num_vlan * sizeof(vtag_array[0]));
}
- status = be_mbox_notify(adapter);
+ status = be_mcc_notify_wait(adapter);
- spin_unlock(&adapter->mbox_lock);
+ spin_unlock_bh(&adapter->mcc_lock);
return status;
}
-/* Use MCC for this command as it may be called in BH context */
+/* Uses MCC for this command as it may be called in BH context
+ * Uses synchronous mcc
+ */
int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_promiscuous_config *req;
+ int status;
spin_lock_bh(&adapter->mcc_lock);
- wrb = wrb_from_mcc(&adapter->mcc_obj.q);
- BUG_ON(!wrb);
-
+ wrb = wrb_from_mccq(adapter);
req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -895,14 +965,14 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
else
req->port0_promiscuous = en;
- be_mcc_notify_wait(adapter);
+ status = be_mcc_notify_wait(adapter);
spin_unlock_bh(&adapter->mcc_lock);
- return 0;
+ return status;
}
/*
- * Use MCC for this command as it may be called in BH context
+ * Uses MCC for this command as it may be called in BH context
* (mc == NULL) => multicast promiscous
*/
int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
@@ -914,9 +984,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
spin_lock_bh(&adapter->mcc_lock);
- wrb = wrb_from_mcc(&adapter->mcc_obj.q);
- BUG_ON(!wrb);
-
+ wrb = wrb_from_mccq(adapter);
req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -944,15 +1012,17 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
return 0;
}
+/* Uses synchrounous mcc */
int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_set_flow_control *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_set_flow_control *req;
int status;
- spin_lock(&adapter->mbox_lock);
+ spin_lock_bh(&adapter->mcc_lock);
- memset(wrb, 0, sizeof(*wrb));
+ wrb = wrb_from_mccq(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -962,28 +1032,30 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
req->tx_flow_control = cpu_to_le16((u16)tx_fc);
req->rx_flow_control = cpu_to_le16((u16)rx_fc);
- status = be_mbox_notify(adapter);
+ status = be_mcc_notify_wait(adapter);
- spin_unlock(&adapter->mbox_lock);
+ spin_unlock_bh(&adapter->mcc_lock);
return status;
}
+/* Uses sycn mcc */
int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_get_flow_control *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_get_flow_control *req;
int status;
- spin_lock(&adapter->mbox_lock);
+ spin_lock_bh(&adapter->mcc_lock);
- memset(wrb, 0, sizeof(*wrb));
+ wrb = wrb_from_mccq(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req));
- status = be_mbox_notify(adapter);
+ status = be_mcc_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_get_flow_control *resp =
embedded_payload(wrb);
@@ -991,26 +1063,28 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
*rx_fc = le16_to_cpu(resp->rx_flow_control);
}
- spin_unlock(&adapter->mbox_lock);
+ spin_unlock_bh(&adapter->mcc_lock);
return status;
}
+/* Uses mbox */
int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_query_fw_cfg *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_query_fw_cfg *req;
int status;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
- status = be_mbox_notify(adapter);
+ status = be_mbox_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
*port_num = le32_to_cpu(resp->phys_port);
@@ -1020,22 +1094,24 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
return status;
}
+/* Uses mbox */
int be_cmd_reset_function(struct be_adapter *adapter)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
- struct be_cmd_req_hdr *req = embedded_payload(wrb);
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_hdr *req;
int status;
spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+ wrb = wrb_from_mbox(adapter);
+ req = embedded_payload(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(req, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_FUNCTION_RESET, sizeof(*req));
- status = be_mbox_notify(adapter);
+ status = be_mbox_notify_wait(adapter);
spin_unlock(&adapter->mbox_lock);
return status;
@@ -1044,13 +1120,17 @@ int be_cmd_reset_function(struct be_adapter *adapter)
int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 flash_type, u32 flash_opcode, u32 buf_size)
{
- struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
+ struct be_mcc_wrb *wrb;
struct be_cmd_write_flashrom *req = cmd->va;
- struct be_sge *sge = nonembedded_sgl(wrb);
+ struct be_sge *sge;
int status;
- spin_lock(&adapter->mbox_lock);
- memset(wrb, 0, sizeof(*wrb));
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ req = embedded_payload(wrb);
+ sge = nonembedded_sgl(wrb);
+
be_wrb_hdr_prepare(wrb, cmd->size, false, 1);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
@@ -1063,8 +1143,8 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
req->params.op_code = cpu_to_le32(flash_opcode);
req->params.data_buf_size = cpu_to_le32(buf_size);
- status = be_mbox_notify(adapter);
+ status = be_mcc_notify_wait(adapter);
- spin_unlock(&adapter->mbox_lock);
+ spin_unlock_bh(&adapter->mcc_lock);
return status;
}
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index fd7028e..93e432f 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -61,7 +61,8 @@ enum {
/* The command is completing because the queue was getting flushed */
MCC_STATUS_QUEUE_FLUSHING = 0x4,
/* The command is completing with a DMA error */
- MCC_STATUS_DMA_FAILED = 0x5
+ MCC_STATUS_DMA_FAILED = 0x5,
+ MCC_STATUS_NOT_SUPPORTED = 0x66
};
#define CQE_STATUS_COMPL_MASK 0xFFFF
@@ -761,7 +762,7 @@ extern int be_cmd_get_flow_control(struct be_adapter *adapter,
u32 *tx_fc, u32 *rx_fc);
extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num);
extern int be_cmd_reset_function(struct be_adapter *adapter);
-extern void be_process_mcc(struct be_adapter *adapter);
+extern int be_process_mcc(struct be_adapter *adapter);
extern int be_cmd_write_flashrom(struct be_adapter *adapter,
struct be_dma_mem *cmd, u32 flash_oper,
u32 flash_opcode, u32 buf_size);
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index ce11bba..409cf05 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -135,7 +135,7 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
return status;
}
-static void netdev_stats_update(struct be_adapter *adapter)
+void netdev_stats_update(struct be_adapter *adapter)
{
struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va);
struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
@@ -431,8 +431,7 @@ static int make_tx_wrbs(struct be_adapter *adapter,
}
static netdev_tx_t be_xmit(struct sk_buff *skb,
- struct net_device *netdev)
-
+ struct net_device *netdev)
{
struct be_adapter *adapter = netdev_priv(netdev);
struct be_tx_obj *tx_obj = &adapter->tx_obj;
@@ -490,11 +489,11 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu)
* program them in BE. If more than BE_NUM_VLANS_SUPPORTED are configured,
* set the BE in promiscuous VLAN mode.
*/
-static void be_vid_config(struct net_device *netdev)
+static int be_vid_config(struct be_adapter *adapter)
{
- struct be_adapter *adapter = netdev_priv(netdev);
u16 vtag[BE_NUM_VLANS_SUPPORTED];
u16 ntags = 0, i;
+ int status;
if (adapter->num_vlans <= BE_NUM_VLANS_SUPPORTED) {
/* Construct VLAN Table to give to HW */
@@ -504,12 +503,13 @@ static void be_vid_config(struct net_device *netdev)
ntags++;
}
}
- be_cmd_vlan_config(adapter, adapter->if_handle,
- vtag, ntags, 1, 0);
+ status = be_cmd_vlan_config(adapter, adapter->if_handle,
+ vtag, ntags, 1, 0);
} else {
- be_cmd_vlan_config(adapter, adapter->if_handle,
- NULL, 0, 1, 1);
+ status = be_cmd_vlan_config(adapter, adapter->if_handle,
+ NULL, 0, 1, 1);
}
+ return status;
}
static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp)
@@ -532,7 +532,7 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
adapter->num_vlans++;
adapter->vlan_tag[vid] = 1;
- be_vid_config(netdev);
+ be_vid_config(adapter);
}
static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
@@ -543,7 +543,7 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
adapter->vlan_tag[vid] = 0;
vlan_group_set_device(adapter->vlan_grp, vid, NULL);
- be_vid_config(netdev);
+ be_vid_config(adapter);
}
static void be_set_multicast_list(struct net_device *netdev)
@@ -1444,12 +1444,8 @@ static void be_worker(struct work_struct *work)
{
struct be_adapter *adapter =
container_of(work, struct be_adapter, work.work);
- int status;
- /* Get Stats */
- status = be_cmd_get_stats(adapter, &adapter->stats.cmd);
- if (!status)
- netdev_stats_update(adapter);
+ be_cmd_get_stats(adapter, &adapter->stats.cmd);
/* Set EQ delay */
be_rx_eqd_update(adapter);
@@ -1622,11 +1618,6 @@ static int be_setup(struct be_adapter *adapter)
if (status != 0)
goto do_none;
- be_vid_config(netdev);
-
- status = be_cmd_set_flow_control(adapter, true, true);
- if (status != 0)
- goto if_destroy;
status = be_tx_queues_create(adapter);
if (status != 0)
@@ -1640,8 +1631,17 @@ static int be_setup(struct be_adapter *adapter)
if (status != 0)
goto rx_qs_destroy;
+ status = be_vid_config(adapter);
+ if (status != 0)
+ goto mccqs_destroy;
+
+ status = be_cmd_set_flow_control(adapter, true, true);
+ if (status != 0)
+ goto mccqs_destroy;
return 0;
+mccqs_destroy:
+ be_mcc_queues_destroy(adapter);
rx_qs_destroy:
be_rx_queues_destroy(adapter);
tx_qs_destroy:
--
1.6.0.4
^ permalink raw reply related
* [PATCH 1/2] ipv4: fix do_ip_setsockopt optlen check for IP_MULTICAST_IF
From: Xiaotian Feng @ 2009-09-17 5:19 UTC (permalink / raw)
To: davem, kaber, yoshfuji, jmorris, pekkas, kuznet
Cc: netdev, linux-kernel, Xiaotian Feng
Due to man page of setsockopt, if optlen is not valid, kernel should return
-EINVAL. But a simple testcase as following, errno is 0, which means setsockopt
is successful.
addr.s_addr = inet_addr("192.1.2.3");
setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &addr, 1);
printf("errno is %d\n", errno);
This patch fixes the optlen check part, with the patch, we got errno EINVAL.
Signed-off-by: Xiaotian Feng <dfeng@redhat.com>
Cc: Patrick McHardy <kaber@trash.net>
Cc: David S. Miller <davem@davemloft.net>
---
net/ipv4/ip_sockglue.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index fc7993e..5a29dce 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -615,13 +615,13 @@ static int do_ip_setsockopt(struct sock *sk, int level,
if (optlen >= sizeof(struct ip_mreqn)) {
if (copy_from_user(&mreq, optval, sizeof(mreq)))
break;
- } else {
+ } else if (optlen >= sizeof(struct in_addr)) {
memset(&mreq, 0, sizeof(mreq));
- if (optlen >= sizeof(struct in_addr) &&
- copy_from_user(&mreq.imr_address, optval,
+ if (copy_from_user(&mreq.imr_address, optval,
sizeof(struct in_addr)))
break;
- }
+ } else /* Invalid optlen */
+ goto e_inval;
if (!mreq.imr_ifindex) {
if (mreq.imr_address.s_addr == htonl(INADDR_ANY)) {
--
1.6.2.5
^ permalink raw reply related
* [PATCH 2/2] ipv4: make do_ip_setsockopt for IP_MULTICAST_IF support ip_mreq struct
From: Xiaotian Feng @ 2009-09-17 5:20 UTC (permalink / raw)
To: davem, kaber, yoshfuji, jmorris, pekkas, kuznet
Cc: netdev, linux-kernel, Xiaotian Feng, Marc Milgram
ip_mreq and ip_mreqn is almost the same, and do_ip_setsockopt for IP_MULTICAST_IF
part supported ip_mreqn struct. This patch adds support for ip_mreq struct.
Signed-off-by: Marc Milgram <mmilgram@redhat.com>
Signed-off-by: Xiaotian Feng <dfeng@redhat.com>
Cc: Patrick McHardy <kaber@trash.net>
Cc: David S. Miller <davem@davemloft.net>
---
net/ipv4/ip_sockglue.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 5a29dce..1e8d026 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -612,11 +612,16 @@ static int do_ip_setsockopt(struct sock *sk, int level,
*/
err = -EFAULT;
+ memset(&mreq, 0, sizeof(mreq));
+
if (optlen >= sizeof(struct ip_mreqn)) {
if (copy_from_user(&mreq, optval, sizeof(mreq)))
break;
+ } else if (optlen >= sizeof(struct ip_mreq)) {
+ if (copy_from_user(&mreq, optval,
+ sizeof(struct ip_mreq)))
+ break;
} else if (optlen >= sizeof(struct in_addr)) {
- memset(&mreq, 0, sizeof(mreq));
if (copy_from_user(&mreq.imr_address, optval,
sizeof(struct in_addr)))
break;
--
1.6.2.5
^ permalink raw reply related
* Re: [PATCHv2 1/2] mm: export use_mm/unuse_mm to modules
From: Michael S. Tsirkin @ 2009-09-17 5:38 UTC (permalink / raw)
To: Andrew Morton
Cc: netdev, virtualization, kvm, linux-kernel, mingo, linux-mm, hpa,
aarcange
In-Reply-To: <20090811151010.c9c56955.akpm@linux-foundation.org>
Hi Andrew,
On Tue, Aug 11, 2009 at 03:10:10PM -0700, Andrew Morton wrote:
> On Wed, 12 Aug 2009 00:27:52 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>
> > vhost net module wants to do copy to/from user from a kernel thread,
> > which needs use_mm (like what fs/aio has). Move that into mm/ and
> > export to modules.
>
> OK by me. Please include this change in the virtio patchset. Which I
> shall cheerfully not be looking at :)
The virtio patches are somewhat delayed as we are ironing out the
kernel/user interface with Rusty. Can the patch moving use_mm to mm/ be
applied without exporting to modules for now? This will make it easier
for virtio which will only have to patch in the EXPORT line.
I also have a small patch optimizing atomic usage in use_mm (which I did for
virtio) and it's easier to apply it if the code is in the new place.
If ok, pls let me know and I'll post the patch without the EXPORT line.
--
MST
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCHv2 1/2] mm: export use_mm/unuse_mm to modules
From: Andrew Morton @ 2009-09-17 5:43 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: netdev, virtualization, kvm, linux-kernel, mingo, linux-mm, hpa,
aarcange
In-Reply-To: <20090917053817.GB6770@redhat.com>
On Thu, 17 Sep 2009 08:38:18 +0300 "Michael S. Tsirkin" <mst@redhat.com> wrote:
> Hi Andrew,
> On Tue, Aug 11, 2009 at 03:10:10PM -0700, Andrew Morton wrote:
> > On Wed, 12 Aug 2009 00:27:52 +0300
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> >
> > > vhost net module wants to do copy to/from user from a kernel thread,
> > > which needs use_mm (like what fs/aio has). Move that into mm/ and
> > > export to modules.
> >
> > OK by me. Please include this change in the virtio patchset. Which I
> > shall cheerfully not be looking at :)
>
> The virtio patches are somewhat delayed as we are ironing out the
> kernel/user interface with Rusty. Can the patch moving use_mm to mm/ be
> applied without exporting to modules for now? This will make it easier
> for virtio which will only have to patch in the EXPORT line.
That was 10,000 patches ago.
> I also have a small patch optimizing atomic usage in use_mm (which I did for
> virtio) and it's easier to apply it if the code is in the new place.
>
> If ok, pls let me know and I'll post the patch without the EXPORT line.
Please just send them all out.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH 2/2] net: remove print_mac as it's not anymore used
From: Jean-Christophe PLAGNIOL-VILLARD @ 2009-09-17 5:48 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090916.205417.253183573.davem@davemloft.net>
On 20:54 Wed 16 Sep , David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Wed, 16 Sep 2009 20:51:59 -0700 (PDT)
>
> > From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> > Date: Thu, 17 Sep 2009 02:07:39 +0200
> >
> >> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> >
> > Applied.
>
> Actually I had to revert. It's still used by the FCOE stack in
> the scsi layer.
>
> Did you actually run grep on the entire tree to see if it's still used
> anywhere or did you only check drivers/net/ and net/ or something
> equally lazy?
Yes I've done a git grep print_mac + cscope on the current Linus tree and
see no more use of print_mac
Best Regards,
J.
^ permalink raw reply
* Re: [PATCH 2/2] net: remove print_mac as it's not anymore used
From: Jean-Christophe PLAGNIOL-VILLARD @ 2009-09-17 6:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090916.205417.253183573.davem@davemloft.net>
On 20:54 Wed 16 Sep , David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Wed, 16 Sep 2009 20:51:59 -0700 (PDT)
>
> > From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> > Date: Thu, 17 Sep 2009 02:07:39 +0200
> >
> >> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> >
> > Applied.
>
> Actually I had to revert. It's still used by the FCOE stack in
> the scsi layer.
>
> Did you actually run grep on the entire tree to see if it's still used
> anywhere or did you only check drivers/net/ and net/ or something
> equally lazy?
I've download the next tree
and noone use use it anymore except the wl12xx which I'll fix
If you can point me in while file or tree I can fous the remaining code I'll
fix it
arch/m68k/kernel/head.S:mmu_print_machine_cpu_types:
arch/m68k/kernel/head.S: jbsr mmu_print_machine_cpu_types
drivers/infiniband/hw/amso1100/c2.c:static void c2_print_macaddr(struct net_device *netdev)
drivers/infiniband/hw/amso1100/c2.c: c2_print_macaddr(netdev);
drivers/infiniband/hw/amso1100/c2.c: c2_print_macaddr(netdev);
drivers/infiniband/hw/nes/nes.c: * nes_print_macaddr
drivers/infiniband/hw/nes/nes.c:static void nes_print_macaddr(struct net_device *netdev)
drivers/infiniband/hw/nes/nes.c: nes_print_macaddr(netdev);
drivers/net/r8169.c:static void rtl8169_print_mac_version(struct rtl8169_private *tp)
drivers/net/r8169.c: rtl8169_print_mac_version(tp);
drivers/net/r8169.c: rtl8169_print_mac_version(tp);
drivers/net/wireless/wl12xx/wl1271_main.c: print_mac(mac, conf->bssid));
drivers/net/wireless/zd1211rw/zd_chip.c:static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size)
drivers/net/wireless/zd1211rw/zd_chip.c: i += scnprint_mac_oui(chip, buffer+i, size-i);
include/linux/if_ether.h:extern char *print_mac(char *buf, const unsigned char *addr) __deprecated;
net/ethernet/eth.c:char *print_mac(char *buf, const unsigned char *addr)
net/ethernet/eth.c:EXPORT_SYMBOL(print_mac);
Best Regards,
J.
^ permalink raw reply
* [PATCH 1/2 v2] wl12xx: switch to %pM to print the mac address
From: Jean-Christophe PLAGNIOL-VILLARD @ 2009-09-17 6:15 UTC (permalink / raw)
To: netdev; +Cc: Jean-Christophe PLAGNIOL-VILLARD
In-Reply-To: <1253146059-4169-1-git-send-email-plagnioj@jcrosoft.com>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
drivers/net/wireless/wl12xx/wl1271_main.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
v2:
Fix correctly
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index d9169b4..27298b1 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -644,11 +644,10 @@ static int wl1271_op_config_interface(struct ieee80211_hw *hw,
{
struct wl1271 *wl = hw->priv;
struct sk_buff *beacon;
- DECLARE_MAC_BUF(mac);
int ret;
- wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %s",
- print_mac(mac, conf->bssid));
+ wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %pM",
+ conf->bssid);
wl1271_dump_ascii(DEBUG_MAC80211, "ssid: ", conf->ssid,
conf->ssid_len);
--
1.6.4
^ permalink raw reply related
* Re: [PATCH 2/2] net: remove print_mac as it's not anymore used
From: Jean-Christophe PLAGNIOL-VILLARD @ 2009-09-17 6:09 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090916.205417.253183573.davem@davemloft.net>
On 20:54 Wed 16 Sep , David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Wed, 16 Sep 2009 20:51:59 -0700 (PDT)
>
> > From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> > Date: Thu, 17 Sep 2009 02:07:39 +0200
> >
> >> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> >
> > Applied.
>
> Actually I had to revert. It's still used by the FCOE stack in
> the scsi layer.
I've found the commit that already fix it
commit 66d6faec2f874cf6bf9bd4900966584ea9feae3d
Refs: v2.6.31-rc7-23-g66d6fae
Author: Johannes Berg <johannes@sipsolutions.net>
AuthorDate: Wed Jul 15 17:21:14 2009 +0200
Commit: James Bottomley <James.Bottomley@suse.de>
CommitDate: Sat Aug 22 17:51:56 2009 -0500
[SCSI] fcoe: convert to %pM
Best Regards,
J.
^ permalink raw reply
* [PATCHv3 0/2] mm: use_mm/unuse_mm
From: Michael S. Tsirkin @ 2009-09-17 7:20 UTC (permalink / raw)
To: netdev, virtualization, kvm, linux-kernel, mingo, linux-mm, akpm
This moves use_mm/unuse_mm from aio into mm, and optimizes atomic usage
there. Original patchset also exported use_mm/unuse_mm to modules, for
use by vhost, that bit will come in later when vhost is posted for
inclusion.
Michael S. Tsirkin (2):
mm: move use_mm/unuse_mm from aio.c to mm/
mm: reduce atomic use on use_mm fast path
fs/aio.c | 47 +----------------------------------
include/linux/mmu_context.h | 9 ++++++
mm/Makefile | 2 +-
mm/mmu_context.c | 58 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 69 insertions(+), 47 deletions(-)
create mode 100644 include/linux/mmu_context.h
create mode 100644 mm/mmu_context.c
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [PATCHv3 1/2] mm: move use_mm/unuse_mm from aio.c to mm/
From: Michael S. Tsirkin @ 2009-09-17 7:21 UTC (permalink / raw)
To: netdev, virtualization, kvm, linux-kernel, mingo, linux-mm, akpm
In-Reply-To: <cover.1253171695.git.mst@redhat.com>
Anyone who wants to do copy to/from user from a kernel thread, needs
use_mm (like what fs/aio has). Move that into mm/, to make reusing and
exporting easier down the line, and make aio use it. Next intended
user, besides aio, will be vhost-net.
Acked-by: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
fs/aio.c | 47 +------------------------------------
include/linux/mmu_context.h | 9 +++++++
mm/Makefile | 2 +-
mm/mmu_context.c | 55 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 66 insertions(+), 47 deletions(-)
create mode 100644 include/linux/mmu_context.h
create mode 100644 mm/mmu_context.c
diff --git a/fs/aio.c b/fs/aio.c
index d065b2c..fc21c23 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -24,6 +24,7 @@
#include <linux/file.h>
#include <linux/mm.h>
#include <linux/mman.h>
+#include <linux/mmu_context.h>
#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/aio.h>
@@ -34,7 +35,6 @@
#include <asm/kmap_types.h>
#include <asm/uaccess.h>
-#include <asm/mmu_context.h>
#if DEBUG > 1
#define dprintk printk
@@ -595,51 +595,6 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id)
}
/*
- * use_mm
- * Makes the calling kernel thread take on the specified
- * mm context.
- * Called by the retry thread execute retries within the
- * iocb issuer's mm context, so that copy_from/to_user
- * operations work seamlessly for aio.
- * (Note: this routine is intended to be called only
- * from a kernel thread context)
- */
-static void use_mm(struct mm_struct *mm)
-{
- struct mm_struct *active_mm;
- struct task_struct *tsk = current;
-
- task_lock(tsk);
- active_mm = tsk->active_mm;
- atomic_inc(&mm->mm_count);
- tsk->mm = mm;
- tsk->active_mm = mm;
- switch_mm(active_mm, mm, tsk);
- task_unlock(tsk);
-
- mmdrop(active_mm);
-}
-
-/*
- * unuse_mm
- * Reverses the effect of use_mm, i.e. releases the
- * specified mm context which was earlier taken on
- * by the calling kernel thread
- * (Note: this routine is intended to be called only
- * from a kernel thread context)
- */
-static void unuse_mm(struct mm_struct *mm)
-{
- struct task_struct *tsk = current;
-
- task_lock(tsk);
- tsk->mm = NULL;
- /* active_mm is still 'mm' */
- enter_lazy_tlb(mm, tsk);
- task_unlock(tsk);
-}
-
-/*
* Queue up a kiocb to be retried. Assumes that the kiocb
* has already been marked as kicked, and places it on
* the retry run list for the corresponding ioctx, if it
diff --git a/include/linux/mmu_context.h b/include/linux/mmu_context.h
new file mode 100644
index 0000000..70fffeb
--- /dev/null
+++ b/include/linux/mmu_context.h
@@ -0,0 +1,9 @@
+#ifndef _LINUX_MMU_CONTEXT_H
+#define _LINUX_MMU_CONTEXT_H
+
+struct mm_struct;
+
+void use_mm(struct mm_struct *mm);
+void unuse_mm(struct mm_struct *mm);
+
+#endif
diff --git a/mm/Makefile b/mm/Makefile
index 5e0bd64..46c3892 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -11,7 +11,7 @@ obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
maccess.o page_alloc.o page-writeback.o pdflush.o \
readahead.o swap.o truncate.o vmscan.o shmem.o \
prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \
- page_isolation.o mm_init.o $(mmu-y)
+ page_isolation.o mm_init.o mmu_context.o $(mmu-y)
obj-y += init-mm.o
obj-$(CONFIG_PROC_PAGE_MONITOR) += pagewalk.o
diff --git a/mm/mmu_context.c b/mm/mmu_context.c
new file mode 100644
index 0000000..fd473b5
--- /dev/null
+++ b/mm/mmu_context.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 2009 Red Hat, Inc.
+ *
+ * See ../COPYING for licensing terms.
+ */
+
+#include <linux/mm.h>
+#include <linux/mmu_context.h>
+#include <linux/sched.h>
+
+#include <asm/mmu_context.h>
+
+/*
+ * use_mm
+ * Makes the calling kernel thread take on the specified
+ * mm context.
+ * Called by the retry thread execute retries within the
+ * iocb issuer's mm context, so that copy_from/to_user
+ * operations work seamlessly for aio.
+ * (Note: this routine is intended to be called only
+ * from a kernel thread context)
+ */
+void use_mm(struct mm_struct *mm)
+{
+ struct mm_struct *active_mm;
+ struct task_struct *tsk = current;
+
+ task_lock(tsk);
+ active_mm = tsk->active_mm;
+ atomic_inc(&mm->mm_count);
+ tsk->mm = mm;
+ tsk->active_mm = mm;
+ switch_mm(active_mm, mm, tsk);
+ task_unlock(tsk);
+
+ mmdrop(active_mm);
+}
+
+/*
+ * unuse_mm
+ * Reverses the effect of use_mm, i.e. releases the
+ * specified mm context which was earlier taken on
+ * by the calling kernel thread
+ * (Note: this routine is intended to be called only
+ * from a kernel thread context)
+ */
+void unuse_mm(struct mm_struct *mm)
+{
+ struct task_struct *tsk = current;
+
+ task_lock(tsk);
+ tsk->mm = NULL;
+ /* active_mm is still 'mm' */
+ enter_lazy_tlb(mm, tsk);
+ task_unlock(tsk);
+}
--
1.6.2.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCHv3 2/2] mm: reduce atomic use on use_mm fast path
From: Michael S. Tsirkin @ 2009-09-17 7:22 UTC (permalink / raw)
To: netdev, virtualization, kvm, linux-kernel, mingo, linux-mm, akpm
In-Reply-To: <cover.1253171695.git.mst@redhat.com>
When mm switched to matches that of active mm, we don't need to
increment and then drop the mm count. In a simple benchmark this
happens in about 50% of time. Making that conditional reduces
contention on that cache line on SMP systems.
Acked-by: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
mm/mmu_context.c | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/mm/mmu_context.c b/mm/mmu_context.c
index fd473b5..ded9081 100644
--- a/mm/mmu_context.c
+++ b/mm/mmu_context.c
@@ -26,13 +26,16 @@ void use_mm(struct mm_struct *mm)
task_lock(tsk);
active_mm = tsk->active_mm;
- atomic_inc(&mm->mm_count);
+ if (active_mm != mm) {
+ atomic_inc(&mm->mm_count);
+ tsk->active_mm = mm;
+ }
tsk->mm = mm;
- tsk->active_mm = mm;
switch_mm(active_mm, mm, tsk);
task_unlock(tsk);
- mmdrop(active_mm);
+ if (active_mm != mm)
+ mmdrop(active_mm);
}
/*
--
1.6.2.5
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* tun: Return -EINVAL if neither IFF_TUN nor IFF_TAP is set.
From: Kusanagi Kouichi @ 2009-09-17 7:36 UTC (permalink / raw)
To: netdev; +Cc: linux-kernel
After commit 2b980dbd77d229eb60588802162c9659726b11f4
("lsm: Add hooks to the TUN driver") tun_set_iff doesn't
return -EINVAL though neither IFF_TUN nor IFF_TAP is set.
Signed-off-by: Kusanagi Kouichi <slash@ma.neweb.ne.jp>
---
drivers/net/tun.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 3f5d288..e091756 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -946,8 +946,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
char *name;
unsigned long flags = 0;
- err = -EINVAL;
-
if (!capable(CAP_NET_ADMIN))
return -EPERM;
err = security_tun_dev_create();
@@ -964,7 +962,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
flags |= TUN_TAP_DEV;
name = "tap%d";
} else
- goto failed;
+ return -EINVAL;
if (*ifr->ifr_name)
name = ifr->ifr_name;
--
1.6.4.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox