* Re: NFS directio
From: Chuck Lever @ 2006-04-09 22:09 UTC (permalink / raw)
To: Neil Brown; +Cc: Olaf Kirch, Trond Myklebust, nfs
In-Reply-To: <17465.67.550070.247218@cse.unsw.edu.au>
Neil Brown wrote:
> On Friday March 31, cel@citi.umich.edu wrote:
>> Olaf Kirch wrote:
>>> On Fri, Mar 31, 2006 at 09:35:34AM -0500, Chuck Lever wrote:
>>>> the check isn't in 2.6.16. it was removed sometime after 2.6.5.
>>> It is still in the 2.6.16 tree I'm looking at; else I wouldn't ask :)
>> it's been in my trees since 2.6.13 or even earlier, my mistake.
>>
>> that change is part of the aio+dio patches that were just included in
>> 2.6.17-rc1. instead of creating a single patch for this change, you
>> should consider taking those patches, since they were tested as a unit.
>>
>> if you can guarantee that atomic_t is 32-bits on every platform you
>> support, then it should be save to change that #define to 2^31.
>> otherwise, the work to eliminate the limit entirely has already been
>> done by the above-mentioned patches.
>
> (Coming into the conversation a bit late....)
>
> What about the kmalloc in nfs_get_user_pages:
>
> array_size = (page_count * sizeof(struct page *));
> *pages = kmalloc(array_size, GFP_KERNEL);
>
> With a page_count of 1024, this allocates one page (on 32bit) which is
> easy.
> With a page_count of 4096 (the previous MAX_DIRECTIO_SIZE)), this
> allocates 4 consecutive pages, which won't always succeed.
>
> If you want to go higher than that (which was the point of the start
> of this thread) then you need a large-order allocation which doesn't
> (in my understanding) have a good chance of success due to
> fragmentation.
>
> So I guess my question is: how hard would it be to use a more scalable
> data structure so that very large IO sizes would be reliably
> practical?
howdy neil-
usually I/O is broken up into smaller chunks by the time it gets down to
this level, so it's never been much of an issue. it's pretty
challenging to generate a test case for extremely large I/O sizes (for
example, the size of the entire process address space).
and until now, there really hasn't been much call for doing NFS O_DIRECT
with very large requests. it's been a matter of meeting the
requirements of database I/O, which is generally 4KB to 16KB for data
files, and about a megabyte for log writes.
at this point we don't really have a test case and a use case that
reliably breaks this, so it hasn't been a priority to address this.
the structure of this code was adapted (ie stolen) from other parts of
the kernel that also employ get_user_pages. you can probably take a
look at other places that employ get_user_pages(), and see how they've
since tackled the issue.
--
corporate: <cel at netapp dot com>
personal: <chucklever at bigfoot dot com>
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply
* Re: [Qemu-devel] Gentlemen we have absolute movement! was:Absolute USB-HID device musings (was Re: VNC Terminal Server)
From: Anthony Liguori @ 2006-04-09 22:08 UTC (permalink / raw)
To: qemu-devel
In-Reply-To: <44398445.4010602@wasp.net.au>
[-- Attachment #1: Type: text/plain, Size: 2251 bytes --]
Brad Campbell wrote:
> Anthony Liguori wrote:
>
>> + kbd_mouse_abs_event(dx * 0x7FFF / width,
>> + dy * 0x7FFF / height,
>
> I had just made that same mod to my tree.. solved the tracking problem
> perfectly.
>
> Now if only it would work under win98 without modification..
>
> Look what I just stumbled across.. irrelevant now I guess..
>
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/Hid_d/hh/HID_d/km-ovr_8d838937-f6b9-4245-8bb0-758bf162af7e.xml.asp
>
>
> I wonder.. does windows switch over from ps2 to hid or just react to
> both and given hid is more positive about where it wants the mouse to
> go it wins ?
> I'm sure I've used a ps2 mouse and a usb mouse on windows before.. I'm
> thought they both worked at the same time.
I think they do. I think the absolute movements just override the
relative ones. However, this may just be a twist of fate so I think
it's safer to disable relative reporting.
> Like what you have with the rest of the patch.. I'll clean up my tree
> and go with that I think..
Final one of the night. This patch disables relative mouse reporting
and disables grab automatically the first time SDL detects that the
absolute mouse was enabled. Needs a lot of cleanup but I'm very happy
with the user experience on this one.
> That should work quite well for sdl, gtk and vnc displays.. I guess
> cocoa also..
> Now all we need is X support. I guess as a temporary measure the wacom
> patch works with linux..
Creating a VM right now to try out the latest Xorg driver. Wacom for
older Linux guests is probably not a bad idea.
> Do you find having usb enabled makes the windows session feel a bit
> less responsive or jerkier ?
> I know the mouse tracking is not as smooth with usb.. perhaps having
> ps2 and usb on together will smooth that out a little.
I don't really see a difference. It actually seems a bit nicer with the
USB mouse enabled (as the mouse moves with the same acceleration as
under the host). One thing I noticed with the Wacom driver is that the
PS/2 mouse tends to accelerate faster than the host mouse and that tends
to give a feeling of a "snappier" interface. That may be what you're
experiencing.
Regards,
Anthony Liguori
[-- Attachment #2: qemu-abs-hid-1.diff --]
[-- Type: text/plain, Size: 10800 bytes --]
# HG changeset patch
# User Anthony Liguori <anthony@codemonkey.ws>
# Node ID c2a6c24121b8a56622cafddf39812a37ab887600
# Parent 8937c657c23f99c8d352cc2b68a2e8a814243ec7
USB Mouse support for with absolute coordinates. The HID modifications are
all from Brad Campbell <brad@wasp.net.au>
diff -r 8937c657c23f -r c2a6c24121b8 hw/usb-hid.c
--- a/hw/usb-hid.c Sun Mar 26 01:31:22 2006 +0000
+++ b/hw/usb-hid.c Sun Apr 9 16:59:35 2006 -0500
@@ -33,6 +33,7 @@
typedef struct USBMouseState {
USBDevice dev;
int dx, dy, dz, buttons_state;
+ int X, Y;
} USBMouseState;
/* mostly the same values as the Bochs USB Mouse device */
@@ -92,14 +93,6 @@
0x01, /* u8 if_bInterfaceSubClass; */
0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
0x05, /* u8 if_iInterface; */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x03, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
/* HID descriptor */
0x09, /* u8 bLength; */
@@ -108,9 +101,18 @@
0x00, /* u8 country_code */
0x01, /* u8 num_descriptors */
0x22, /* u8 type; Report */
- 50, 0, /* u16 len */
+ 53, 0, /* u16 len */
+
+ /* one endpoint (status change endpoint) */
+ 0x07, /* u8 ep_bLength; */
+ 0x05, /* u8 ep_bDescriptorType; Endpoint */
+ 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
+ 0x03, /* u8 ep_bmAttributes; Interrupt */
+ 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
+ 0x03, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
};
+#if 0
static const uint8_t qemu_mouse_hid_report_descriptor[] = {
0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
@@ -120,6 +122,41 @@
0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
0xC0, 0xC0,
};
+#else
+static const uint8_t qemu_mouse_hid_report_descriptor[] = {
+ 0x05, 0x01, /* Usage Page Generic Desktop */
+ 0x09, 0x01, /* Usage Mouse */
+ 0xA1, 0x01, /* Collection Application */
+ 0x09, 0x01, /* Usage Pointer */
+ 0xA1, 0x00, /* Collection Physical */
+ 0x05, 0x09, /* Usage Page Button */
+ 0x19, 0x01, /* Usage Minimum Button 1 */
+ 0x29, 0x03, /* Usage Maximum Button 3 */
+ 0x15, 0x00, /* Logical Minimum 0 */
+ 0x25, 0x01, /* Logical Maximum 1 */
+ 0x95, 0x03, /* Report Count 3 */
+ 0x75, 0x01, /* Report Size 1 */
+ 0x81, 0x02, /* Input (Data, Var, Abs) */
+ 0x95, 0x01, /* Report Count 1 */
+ 0x75, 0x05, /* Report Size 5 */
+ 0x81, 0x01, /* Input (Cnst, Var, Abs) */
+ 0x05, 0x01, /* Usage Page Generic Desktop */
+ 0x09, 0x30, /* Usage X */
+ 0x09, 0x31, /* Usage Y */
+ 0x15, 0x00, /* Logical Minimum 0 */
+ 0x27, 0xFF, 0xFF, 0x00, 0x00, /* Logical Maximum 0xffff */
+ 0x75, 0x10, /* Report Size 32 */
+ 0x95, 0x02, /* Report Count 2 */
+ 0x81, 0x02, /* Input (Data, Var, Abs) */
+// 0x09, 0x32, /* Usage Z */
+// 0x15, 0x81, /* Logical Minimum -127 */
+// 0x25, 0x7F, /* Logical Maximum 127 */
+// 0x75, 0x08, /* Report Size 8 */
+// 0x95, 0x01, /* Report Count 1 */
+ 0xC0, /* End Collection */
+ 0xC0, /* End Collection */
+};
+#endif
static void usb_mouse_event(void *opaque,
int dx1, int dy1, int dz1, int buttons_state)
@@ -129,6 +166,8 @@
s->dx += dx1;
s->dy += dy1;
s->dz += dz1;
+ s->X = dx1;
+ s->Y = dy1;
s->buttons_state = buttons_state;
}
@@ -142,6 +181,7 @@
return val;
}
+#if 0
static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len)
{
int dx, dy, dz, b, l;
@@ -172,6 +212,44 @@
}
return l;
}
+#else
+
+static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len)
+{
+ int dx, dy, dz, b, l;
+
+ /* FIXME this is ugly */
+ if (absolute_mouse == 0) {
+ /* disable the PS/2 mouse */
+ qemu_add_mouse_event_handler(NULL, NULL);
+ absolute_mouse = 1;
+ }
+
+ dx = int_clamp(s->dx, -128, 127);
+ dy = int_clamp(s->dy, -128, 127);
+ dz = int_clamp(s->dz, -128, 127);
+
+ s->dx -= dx;
+ s->dy -= dy;
+ s->dz -= dz;
+ b = 0;
+ if (s->buttons_state & MOUSE_EVENT_LBUTTON)
+ b |= 0x01;
+ if (s->buttons_state & MOUSE_EVENT_RBUTTON)
+ b |= 0x02;
+ if (s->buttons_state & MOUSE_EVENT_MBUTTON)
+ b |= 0x04;
+
+ buf[0] = b;
+ buf[1] = s->X & 0xff;
+ buf[2] = s->X >> 8;
+ buf[3] = s->Y & 0xff;
+ buf[4] = s->Y >> 8;
+ l = 5;
+
+ return l;
+}
+#endif
static void usb_mouse_handle_reset(USBDevice *dev)
{
@@ -180,6 +258,8 @@
s->dx = 0;
s->dy = 0;
s->dz = 0;
+ s->X = 0;
+ s->Y = 0;
s->buttons_state = 0;
}
@@ -341,7 +421,7 @@
s->dev.handle_control = usb_mouse_handle_control;
s->dev.handle_data = usb_mouse_handle_data;
- qemu_add_mouse_event_handler(usb_mouse_event, s);
+ qemu_add_mouse_abs_event_handler(usb_mouse_event, s);
return (USBDevice *)s;
}
diff -r 8937c657c23f -r c2a6c24121b8 sdl.c
--- a/sdl.c Sun Mar 26 01:31:22 2006 +0000
+++ b/sdl.c Sun Apr 9 16:59:35 2006 -0500
@@ -39,6 +39,11 @@
static int gui_fullscreen_initial_grab;
static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
static uint8_t modifiers_state[256];
+static int width, height;
+static SDL_Cursor *sdl_cursor_normal;
+static SDL_Cursor *sdl_cursor_hidden;
+static int cursor_hidden = 0;
+static int absolute_enabled = 0;
static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
{
@@ -55,6 +60,9 @@
flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
if (gui_fullscreen)
flags |= SDL_FULLSCREEN;
+
+ width = w;
+ height = h;
again:
screen = SDL_SetVideoMode(w, h, 0, flags);
@@ -273,7 +281,9 @@
static void sdl_grab_start(void)
{
- SDL_ShowCursor(0);
+ sdl_cursor_normal = SDL_GetCursor();
+ SDL_SetCursor(sdl_cursor_hidden);
+ cursor_hidden = 1;
SDL_WM_GrabInput(SDL_GRAB_ON);
/* dummy read to avoid moving the mouse */
SDL_GetRelativeMouseState(NULL, NULL);
@@ -284,7 +294,10 @@
static void sdl_grab_end(void)
{
SDL_WM_GrabInput(SDL_GRAB_OFF);
- SDL_ShowCursor(1);
+ if (!absolute_mouse) {
+ SDL_SetCursor(sdl_cursor_normal);
+ cursor_hidden = 1;
+ }
gui_grab = 0;
sdl_update_caption();
}
@@ -301,6 +314,25 @@
if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
buttons |= MOUSE_EVENT_MBUTTON;
kbd_mouse_event(dx, dy, dz, buttons);
+
+ if (absolute_mouse) {
+ if (!absolute_enabled) {
+ if (!cursor_hidden) {
+ sdl_cursor_normal = SDL_GetCursor();
+ SDL_SetCursor(sdl_cursor_hidden);
+ cursor_hidden = 1;
+ }
+ if (gui_grab) {
+ sdl_grab_end();
+ }
+ absolute_enabled = 1;
+ }
+
+ SDL_GetMouseState(&dx, &dy);
+ kbd_mouse_abs_event(dx * 0x7FFF / width,
+ dy * 0x7FFF / height,
+ dz, buttons);
+ }
}
static void toggle_full_screen(DisplayState *ds)
@@ -427,7 +459,7 @@
qemu_system_shutdown_request();
break;
case SDL_MOUSEMOTION:
- if (gui_grab) {
+ if (gui_grab || absolute_mouse) {
sdl_send_mouse_event(0);
}
break;
@@ -435,7 +467,7 @@
case SDL_MOUSEBUTTONUP:
{
SDL_MouseButtonEvent *bev = &ev->button;
- if (!gui_grab) {
+ if (!gui_grab && !absolute_mouse) {
if (ev->type == SDL_MOUSEBUTTONDOWN &&
(bev->state & SDL_BUTTON_LMASK)) {
/* start grabbing all events */
@@ -475,6 +507,7 @@
void sdl_display_init(DisplayState *ds, int full_screen)
{
int flags;
+ uint8_t data = 0;
#if defined(__APPLE__)
/* always use generic keymaps */
@@ -508,6 +541,8 @@
SDL_EnableUNICODE(1);
gui_grab = 0;
+ sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
+
atexit(sdl_cleanup);
if (full_screen) {
gui_fullscreen = 1;
diff -r 8937c657c23f -r c2a6c24121b8 vl.c
--- a/vl.c Sun Mar 26 01:31:22 2006 +0000
+++ b/vl.c Sun Apr 9 16:59:35 2006 -0500
@@ -148,6 +148,7 @@
USBDevice *vm_usb_hub;
static VLANState *first_vlan;
int smp_cpus = 1;
+int absolute_mouse = 0;
#if defined(TARGET_SPARC)
#define MAX_CPUS 16
#elif defined(TARGET_I386)
@@ -475,6 +476,8 @@
static void *qemu_put_kbd_event_opaque;
static QEMUPutMouseEvent *qemu_put_mouse_event;
static void *qemu_put_mouse_event_opaque;
+static QEMUPutMouseAbsEvent *qemu_put_mouse_abs_event;
+static void *qemu_put_mouse_abs_event_opaque;
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
{
@@ -486,6 +489,12 @@
{
qemu_put_mouse_event_opaque = opaque;
qemu_put_mouse_event = func;
+}
+
+void qemu_add_mouse_abs_event_handler(QEMUPutMouseAbsEvent *func, void *opaque)
+{
+ qemu_put_mouse_abs_event_opaque = opaque;
+ qemu_put_mouse_abs_event = func;
}
void kbd_put_keycode(int keycode)
@@ -500,6 +509,14 @@
if (qemu_put_mouse_event) {
qemu_put_mouse_event(qemu_put_mouse_event_opaque,
dx, dy, dz, buttons_state);
+ }
+}
+
+void kbd_mouse_abs_event(int x, int y, int dz, int buttons_state)
+{
+ if (qemu_put_mouse_abs_event) {
+ qemu_put_mouse_abs_event(qemu_put_mouse_abs_event_opaque,
+ x, y, dz, buttons_state);
}
}
diff -r 8937c657c23f -r c2a6c24121b8 vl.h
--- a/vl.h Sun Mar 26 01:31:22 2006 +0000
+++ b/vl.h Sun Apr 9 16:59:35 2006 -0500
@@ -138,6 +138,7 @@
extern int win2k_install_hack;
extern int usb_enabled;
extern int smp_cpus;
+extern int absolute_mouse;
/* XXX: make it dynamic */
#if defined (TARGET_PPC)
@@ -156,12 +157,15 @@
typedef void QEMUPutKBDEvent(void *opaque, int keycode);
typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
+typedef void QEMUPutMouseAbsEvent(void *opaque, int x, int y, int dz, int buttons_state);
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque);
+void qemu_add_mouse_abs_event_handler(QEMUPutMouseAbsEvent *func, void *opaque);
void kbd_put_keycode(int keycode);
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
+void kbd_mouse_abs_event(int x, int y, int dz, int buttons_state);
/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
constants) */
^ permalink raw reply
* Re: [ANNOUNCE] git-svnconvert: YASI (Yet Another SVN importer)
From: Randal L. Schwartz @ 2006-04-09 22:06 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Jakub Narebski, git
In-Reply-To: <Pine.LNX.4.63.0604092325590.29434@wbgn013.biozentrum.uni-wuerzburg.de>
>>>>> "Johannes" == Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
Johannes> I have _never_ seen a setup where Ruby was installed by
Johannes> default. Perl always, Python often.
OSX includes ruby by default.
Johannes> Furthermore, my feeling is that we are in the beginning phase of
Johannes> migration from scripting languages (which are good for prototyping)
Johannes> towards plain C. So adding yet another scripting language
Johannes> dependency is a little backwards.
You seem a bit prejudiced here. Are there performance problems in
the Perl and python parts of git? If so, concentrate first on optimizing
the code where it matters. Then, creating bindings to the "git lib"
so that the heavy lifting can be done in C while still providing for
the basic algorithms to be written in a higher level language.
It would be a step *backwards* to recode all of git in C.
Now, the *shell* parts, on the other hand, are screaming for a rewrite into
Perl or Python. fork-fork-fork and worrying about escaping special characters
needlessly burns a lot of cpu and programmer time.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
^ permalink raw reply
* [GIT PULL] post-2.6.17-rc1 fixes
From: Roland Dreier @ 2006-04-09 22:06 UTC (permalink / raw)
To: torvalds; +Cc: linux-kernel, openib-general
Linus, please pull from
master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git for-linus
This tree is also available from kernel.org mirrors at:
git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git for-linus
This includes some changes that I asked you to pull last week right
before you left. There are a couple of largish changes in here, but I
think they are all needed:
- the IPoIB ring size tunables fix horrible performance IBM sees
- the static rate change fixes big problems on mixed rate networks
- the callback refcounting changes are fixing possible crashes on
module unload
The exact changes and patch are:
Eli Cohen:
IPoIB: Wait for join to finish before freeing mcast struct
IPoIB: Close race in ipoib_flush_paths()
Jack Morgenstein:
IB: simplify static rate encoding
Michael S. Tsirkin:
IB/mad: fix oops in cancel_mads
IPoIB: Consolidate private neighbour data handling
IB/mthca: Disable tuning PCI read burst size
IB/sa: Don't let a module be unloaded with a callback running
Roland Dreier:
IPoIB: Always build debugging code unless CONFIG_EMBEDDED=y
IB/mthca: Always build debugging code unless CONFIG_EMBEDDED=y
IB/srp: Fix memory leak in options parsing
IPoIB: Use spin_lock_irq() instead of spin_lock_irqsave()
Sean Hefty:
IB/cm: Don't let a module be unloaded with a callback running
Shirley Ma:
IPoIB: Make send and receive queue sizes tunable
drivers/infiniband/core/cm.c | 31 +++-
drivers/infiniband/core/mad.c | 2
drivers/infiniband/core/sa_query.c | 93 +++++++-----
drivers/infiniband/core/verbs.c | 34 ++++
drivers/infiniband/hw/mthca/Kconfig | 11 +
drivers/infiniband/hw/mthca/Makefile | 4 -
drivers/infiniband/hw/mthca/mthca_av.c | 96 ++++++++++++
drivers/infiniband/hw/mthca/mthca_cmd.c | 4 +
drivers/infiniband/hw/mthca/mthca_cmd.h | 1
drivers/infiniband/hw/mthca/mthca_dev.h | 21 ++-
drivers/infiniband/hw/mthca/mthca_mad.c | 42 +++++
drivers/infiniband/hw/mthca/mthca_main.c | 27 ++++
drivers/infiniband/hw/mthca/mthca_provider.h | 3
drivers/infiniband/hw/mthca/mthca_qp.c | 46 ++++--
drivers/infiniband/ulp/ipoib/Kconfig | 3
drivers/infiniband/ulp/ipoib/ipoib.h | 7 +
drivers/infiniband/ulp/ipoib/ipoib_fs.c | 2
drivers/infiniband/ulp/ipoib/ipoib_ib.c | 22 +--
drivers/infiniband/ulp/ipoib/ipoib_main.c | 88 +++++++----
drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 58 +++-----
drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 6 -
drivers/infiniband/ulp/srp/ib_srp.c | 1
include/rdma/ib_cm.h | 13 +-
include/rdma/ib_sa.h | 185 ++++++++++++++++--------
include/rdma/ib_verbs.h | 28 ++++
25 files changed, 603 insertions(+), 225 deletions(-)
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 7cfedb8..66d1cb3 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -118,6 +118,7 @@ struct cm_timewait_info {
struct cm_id_private {
struct ib_cm_id id;
+ struct module *owner;
struct rb_node service_node;
struct rb_node sidr_id_node;
@@ -538,9 +539,9 @@ static void cm_reject_sidr_req(struct cm
ib_send_cm_sidr_rep(&cm_id_priv->id, ¶m);
}
-struct ib_cm_id *ib_create_cm_id(struct ib_device *device,
- ib_cm_handler cm_handler,
- void *context)
+struct ib_cm_id *__ib_create_cm_id(struct ib_device *device,
+ ib_cm_handler cm_handler,
+ void *context, struct module *owner)
{
struct cm_id_private *cm_id_priv;
int ret;
@@ -549,6 +550,7 @@ struct ib_cm_id *ib_create_cm_id(struct
if (!cm_id_priv)
return ERR_PTR(-ENOMEM);
+ cm_id_priv->owner = owner;
cm_id_priv->id.state = IB_CM_IDLE;
cm_id_priv->id.device = device;
cm_id_priv->id.cm_handler = cm_handler;
@@ -569,7 +571,7 @@ error:
kfree(cm_id_priv);
return ERR_PTR(-ENOMEM);
}
-EXPORT_SYMBOL(ib_create_cm_id);
+EXPORT_SYMBOL(__ib_create_cm_id);
static struct cm_work * cm_dequeue_work(struct cm_id_private *cm_id_priv)
{
@@ -1086,6 +1088,18 @@ static void cm_format_req_event(struct c
work->cm_event.private_data = &req_msg->private_data;
}
+static int invoke_cm_handler(struct cm_id_private *cm_id_priv,
+ struct ib_cm_event *event)
+{
+ int ret;
+
+ BUG_ON(!try_module_get(cm_id_priv->owner));
+ ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, event);
+ module_put(cm_id_priv->owner);
+
+ return ret;
+}
+
static void cm_process_work(struct cm_id_private *cm_id_priv,
struct cm_work *work)
{
@@ -1093,7 +1107,7 @@ static void cm_process_work(struct cm_id
int ret;
/* We will typically only have the current event to report. */
- ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, &work->cm_event);
+ ret = invoke_cm_handler(cm_id_priv, &work->cm_event);
cm_free_work(work);
while (!ret && !atomic_add_negative(-1, &cm_id_priv->work_count)) {
@@ -1101,8 +1115,7 @@ static void cm_process_work(struct cm_id
work = cm_dequeue_work(cm_id_priv);
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
BUG_ON(!work);
- ret = cm_id_priv->id.cm_handler(&cm_id_priv->id,
- &work->cm_event);
+ ret = invoke_cm_handler(cm_id_priv, &work->cm_event);
cm_free_work(work);
}
cm_deref_id(cm_id_priv);
@@ -1291,6 +1304,7 @@ static int cm_req_handler(struct cm_work
goto error2;
}
+ cm_id_priv->owner = listen_cm_id_priv->owner;
cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler;
cm_id_priv->id.context = listen_cm_id_priv->id.context;
cm_id_priv->id.service_id = req_msg->service_id;
@@ -2662,6 +2676,7 @@ static int cm_sidr_req_handler(struct cm
atomic_inc(&cur_cm_id_priv->refcount);
spin_unlock_irqrestore(&cm.lock, flags);
+ cm_id_priv->owner = cur_cm_id_priv->owner;
cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler;
cm_id_priv->id.context = cur_cm_id_priv->id.context;
cm_id_priv->id.service_id = sidr_req_msg->service_id;
@@ -2830,7 +2845,7 @@ static void cm_process_send_error(struct
cm_event.param.send_status = wc_status;
/* No other events can occur on the cm_id at this point. */
- ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, &cm_event);
+ ret = invoke_cm_handler(cm_id_priv, &cm_event);
cm_free_msg(msg);
if (ret)
ib_destroy_cm_id(&cm_id_priv->id);
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index ba54c85..3a702da 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -2311,6 +2311,7 @@ static void local_completions(void *data
local = list_entry(mad_agent_priv->local_list.next,
struct ib_mad_local_private,
completion_list);
+ list_del(&local->completion_list);
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
if (local->mad_priv) {
recv_mad_agent = local->recv_mad_agent;
@@ -2362,7 +2363,6 @@ local_send_completion:
&mad_send_wc);
spin_lock_irqsave(&mad_agent_priv->lock, flags);
- list_del(&local->completion_list);
atomic_dec(&mad_agent_priv->refcount);
if (!recv)
kmem_cache_free(ib_mad_cache, local->mad_priv);
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 501cc05..c43ed75 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -74,6 +74,7 @@ struct ib_sa_device {
struct ib_sa_query {
void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *);
void (*release)(struct ib_sa_query *);
+ struct module *owner;
struct ib_sa_port *port;
struct ib_mad_send_buf *mad_buf;
struct ib_sa_sm_ah *sm_ah;
@@ -547,15 +548,16 @@ static void ib_sa_path_rec_release(struc
* error code. Otherwise it is a query ID that can be used to cancel
* the query.
*/
-int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
- struct ib_sa_path_rec *rec,
- ib_sa_comp_mask comp_mask,
- int timeout_ms, gfp_t gfp_mask,
- void (*callback)(int status,
- struct ib_sa_path_rec *resp,
- void *context),
- void *context,
- struct ib_sa_query **sa_query)
+int __ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
+ struct ib_sa_path_rec *rec,
+ ib_sa_comp_mask comp_mask,
+ int timeout_ms, gfp_t gfp_mask,
+ void (*callback)(int status,
+ struct ib_sa_path_rec *resp,
+ void *context),
+ void *context,
+ struct module *owner,
+ struct ib_sa_query **sa_query)
{
struct ib_sa_path_query *query;
struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
@@ -590,6 +592,7 @@ int ib_sa_path_rec_get(struct ib_device
query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL;
query->sa_query.release = ib_sa_path_rec_release;
+ query->sa_query.owner = owner;
query->sa_query.port = port;
mad->mad_hdr.method = IB_MGMT_METHOD_GET;
mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_PATH_REC);
@@ -613,7 +616,7 @@ err1:
kfree(query);
return ret;
}
-EXPORT_SYMBOL(ib_sa_path_rec_get);
+EXPORT_SYMBOL(__ib_sa_path_rec_get);
static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query,
int status,
@@ -663,15 +666,16 @@ static void ib_sa_service_rec_release(st
* error code. Otherwise it is a request ID that can be used to cancel
* the query.
*/
-int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
- struct ib_sa_service_rec *rec,
- ib_sa_comp_mask comp_mask,
- int timeout_ms, gfp_t gfp_mask,
- void (*callback)(int status,
- struct ib_sa_service_rec *resp,
- void *context),
- void *context,
- struct ib_sa_query **sa_query)
+int __ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
+ struct ib_sa_service_rec *rec,
+ ib_sa_comp_mask comp_mask,
+ int timeout_ms, gfp_t gfp_mask,
+ void (*callback)(int status,
+ struct ib_sa_service_rec *resp,
+ void *context),
+ void *context,
+ struct module *owner,
+ struct ib_sa_query **sa_query)
{
struct ib_sa_service_query *query;
struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
@@ -711,6 +715,7 @@ int ib_sa_service_rec_query(struct ib_de
query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL;
query->sa_query.release = ib_sa_service_rec_release;
+ query->sa_query.owner = owner;
query->sa_query.port = port;
mad->mad_hdr.method = method;
mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
@@ -735,7 +740,7 @@ err1:
kfree(query);
return ret;
}
-EXPORT_SYMBOL(ib_sa_service_rec_query);
+EXPORT_SYMBOL(__ib_sa_service_rec_query);
static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
int status,
@@ -759,16 +764,17 @@ static void ib_sa_mcmember_rec_release(s
kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
}
-int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
- u8 method,
- struct ib_sa_mcmember_rec *rec,
- ib_sa_comp_mask comp_mask,
- int timeout_ms, gfp_t gfp_mask,
- void (*callback)(int status,
- struct ib_sa_mcmember_rec *resp,
- void *context),
- void *context,
- struct ib_sa_query **sa_query)
+int __ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
+ u8 method,
+ struct ib_sa_mcmember_rec *rec,
+ ib_sa_comp_mask comp_mask,
+ int timeout_ms, gfp_t gfp_mask,
+ void (*callback)(int status,
+ struct ib_sa_mcmember_rec *resp,
+ void *context),
+ void *context,
+ struct module *owner,
+ struct ib_sa_query **sa_query)
{
struct ib_sa_mcmember_query *query;
struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
@@ -803,6 +809,7 @@ int ib_sa_mcmember_rec_query(struct ib_d
query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL;
query->sa_query.release = ib_sa_mcmember_rec_release;
+ query->sa_query.owner = owner;
query->sa_query.port = port;
mad->mad_hdr.method = method;
mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
@@ -827,7 +834,15 @@ err1:
kfree(query);
return ret;
}
-EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
+EXPORT_SYMBOL(__ib_sa_mcmember_rec_query);
+
+static void call_sa_callback(struct ib_sa_query *query, int status,
+ struct ib_sa_mad *mad)
+{
+ BUG_ON(!try_module_get(query->owner));
+ query->callback(query, status, mad);
+ module_put(query->owner);
+}
static void send_handler(struct ib_mad_agent *agent,
struct ib_mad_send_wc *mad_send_wc)
@@ -841,13 +856,13 @@ static void send_handler(struct ib_mad_a
/* No callback -- already got recv */
break;
case IB_WC_RESP_TIMEOUT_ERR:
- query->callback(query, -ETIMEDOUT, NULL);
+ call_sa_callback(query, -ETIMEDOUT, NULL);
break;
case IB_WC_WR_FLUSH_ERR:
- query->callback(query, -EINTR, NULL);
+ call_sa_callback(query, -EINTR, NULL);
break;
default:
- query->callback(query, -EIO, NULL);
+ call_sa_callback(query, -EIO, NULL);
break;
}
@@ -871,12 +886,12 @@ static void recv_handler(struct ib_mad_a
if (query->callback) {
if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
- query->callback(query,
- mad_recv_wc->recv_buf.mad->mad_hdr.status ?
- -EINVAL : 0,
- (struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
+ call_sa_callback(query,
+ mad_recv_wc->recv_buf.mad->mad_hdr.status ?
+ -EINVAL : 0,
+ (struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
else
- query->callback(query, -EIO, NULL);
+ call_sa_callback(query, -EIO, NULL);
}
ib_free_recv_mad(mad_recv_wc);
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index cae0845..b78e7dc 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -45,6 +45,40 @@
#include <rdma/ib_verbs.h>
#include <rdma/ib_cache.h>
+int ib_rate_to_mult(enum ib_rate rate)
+{
+ switch (rate) {
+ case IB_RATE_2_5_GBPS: return 1;
+ case IB_RATE_5_GBPS: return 2;
+ case IB_RATE_10_GBPS: return 4;
+ case IB_RATE_20_GBPS: return 8;
+ case IB_RATE_30_GBPS: return 12;
+ case IB_RATE_40_GBPS: return 16;
+ case IB_RATE_60_GBPS: return 24;
+ case IB_RATE_80_GBPS: return 32;
+ case IB_RATE_120_GBPS: return 48;
+ default: return -1;
+ }
+}
+EXPORT_SYMBOL(ib_rate_to_mult);
+
+enum ib_rate mult_to_ib_rate(int mult)
+{
+ switch (mult) {
+ case 1: return IB_RATE_2_5_GBPS;
+ case 2: return IB_RATE_5_GBPS;
+ case 4: return IB_RATE_10_GBPS;
+ case 8: return IB_RATE_20_GBPS;
+ case 12: return IB_RATE_30_GBPS;
+ case 16: return IB_RATE_40_GBPS;
+ case 24: return IB_RATE_60_GBPS;
+ case 32: return IB_RATE_80_GBPS;
+ case 48: return IB_RATE_120_GBPS;
+ default: return IB_RATE_PORT_CURRENT;
+ }
+}
+EXPORT_SYMBOL(mult_to_ib_rate);
+
/* Protection domains */
struct ib_pd *ib_alloc_pd(struct ib_device *device)
diff --git a/drivers/infiniband/hw/mthca/Kconfig b/drivers/infiniband/hw/mthca/Kconfig
index e88be85..9aa5a44 100644
--- a/drivers/infiniband/hw/mthca/Kconfig
+++ b/drivers/infiniband/hw/mthca/Kconfig
@@ -7,10 +7,11 @@ config INFINIBAND_MTHCA
("Tavor") and the MT25208 PCI Express HCA ("Arbel").
config INFINIBAND_MTHCA_DEBUG
- bool "Verbose debugging output"
+ bool "Verbose debugging output" if EMBEDDED
depends on INFINIBAND_MTHCA
- default n
+ default y
---help---
- This option causes the mthca driver produce a bunch of debug
- messages. Select this is you are developing the driver or
- trying to diagnose a problem.
+ This option causes debugging code to be compiled into the
+ mthca driver. The output can be turned on via the
+ debug_level module parameter (which can also be set after
+ the driver is loaded through sysfs).
diff --git a/drivers/infiniband/hw/mthca/Makefile b/drivers/infiniband/hw/mthca/Makefile
index 47ec5a7..e388d95 100644
--- a/drivers/infiniband/hw/mthca/Makefile
+++ b/drivers/infiniband/hw/mthca/Makefile
@@ -1,7 +1,3 @@
-ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
-EXTRA_CFLAGS += -DDEBUG
-endif
-
obj-$(CONFIG_INFINIBAND_MTHCA) += ib_mthca.o
ib_mthca-y := mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index bc5bdcb..87e7c63 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -42,6 +42,20 @@
#include "mthca_dev.h"
+enum {
+ MTHCA_RATE_TAVOR_FULL = 0,
+ MTHCA_RATE_TAVOR_1X = 1,
+ MTHCA_RATE_TAVOR_4X = 2,
+ MTHCA_RATE_TAVOR_1X_DDR = 3
+};
+
+enum {
+ MTHCA_RATE_MEMFREE_FULL = 0,
+ MTHCA_RATE_MEMFREE_QUARTER = 1,
+ MTHCA_RATE_MEMFREE_EIGHTH = 2,
+ MTHCA_RATE_MEMFREE_HALF = 3
+};
+
struct mthca_av {
__be32 port_pd;
u8 reserved1;
@@ -55,6 +69,86 @@ struct mthca_av {
__be32 dgid[4];
};
+static enum ib_rate memfree_rate_to_ib(u8 mthca_rate, u8 port_rate)
+{
+ switch (mthca_rate) {
+ case MTHCA_RATE_MEMFREE_EIGHTH: return port_rate / 8;
+ case MTHCA_RATE_MEMFREE_QUARTER: return port_rate / 4;
+ case MTHCA_RATE_MEMFREE_HALF: return port_rate / 2;
+ case MTHCA_RATE_MEMFREE_FULL: return port_rate;
+ default: return port_rate;
+ }
+}
+
+static enum ib_rate tavor_rate_to_ib(u8 mthca_rate, u8 port_rate)
+{
+ switch (mthca_rate) {
+ case MTHCA_RATE_TAVOR_1X: return IB_RATE_2_5_GBPS;
+ case MTHCA_RATE_TAVOR_1X_DDR: return IB_RATE_5_GBPS;
+ case MTHCA_RATE_TAVOR_4X: return IB_RATE_10_GBPS;
+ default: return port_rate;
+ }
+}
+
+enum ib_rate mthca_rate_to_ib(struct mthca_dev *dev, u8 mthca_rate, u8 port)
+{
+ if (mthca_is_memfree(dev)) {
+ /* Handle old Arbel FW */
+ if (dev->limits.stat_rate_support == 0x3 && mthca_rate)
+ return IB_RATE_2_5_GBPS;
+
+ return memfree_rate_to_ib(mthca_rate, dev->rate[port - 1]);
+ } else
+ return tavor_rate_to_ib(mthca_rate, dev->rate[port - 1]);
+}
+
+static u8 ib_rate_to_memfree(u8 req_rate, u8 cur_rate)
+{
+ if (cur_rate <= req_rate)
+ return 0;
+
+ /*
+ * Inter-packet delay (IPD) to get from rate X down to a rate
+ * no more than Y is (X - 1) / Y.
+ */
+ switch ((cur_rate - 1) / req_rate) {
+ case 0: return MTHCA_RATE_MEMFREE_FULL;
+ case 1: return MTHCA_RATE_MEMFREE_HALF;
+ case 2: /* fall through */
+ case 3: return MTHCA_RATE_MEMFREE_QUARTER;
+ default: return MTHCA_RATE_MEMFREE_EIGHTH;
+ }
+}
+
+static u8 ib_rate_to_tavor(u8 static_rate)
+{
+ switch (static_rate) {
+ case IB_RATE_2_5_GBPS: return MTHCA_RATE_TAVOR_1X;
+ case IB_RATE_5_GBPS: return MTHCA_RATE_TAVOR_1X_DDR;
+ case IB_RATE_10_GBPS: return MTHCA_RATE_TAVOR_4X;
+ default: return MTHCA_RATE_TAVOR_FULL;
+ }
+}
+
+u8 mthca_get_rate(struct mthca_dev *dev, int static_rate, u8 port)
+{
+ u8 rate;
+
+ if (!static_rate || ib_rate_to_mult(static_rate) >= dev->rate[port - 1])
+ return 0;
+
+ if (mthca_is_memfree(dev))
+ rate = ib_rate_to_memfree(ib_rate_to_mult(static_rate),
+ dev->rate[port - 1]);
+ else
+ rate = ib_rate_to_tavor(static_rate);
+
+ if (!(dev->limits.stat_rate_support & (1 << rate)))
+ rate = 1;
+
+ return rate;
+}
+
int mthca_create_ah(struct mthca_dev *dev,
struct mthca_pd *pd,
struct ib_ah_attr *ah_attr,
@@ -107,7 +201,7 @@ on_hca_fail:
av->g_slid = ah_attr->src_path_bits;
av->dlid = cpu_to_be16(ah_attr->dlid);
av->msg_sr = (3 << 4) | /* 2K message */
- ah_attr->static_rate;
+ mthca_get_rate(dev, ah_attr->static_rate, ah_attr->port_num);
av->sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
if (ah_attr->ah_flags & IB_AH_GRH) {
av->g_slid |= 0x80;
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 343eca5..1985b5d 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -965,6 +965,7 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev
u32 *outbox;
u8 field;
u16 size;
+ u16 stat_rate;
int err;
#define QUERY_DEV_LIM_OUT_SIZE 0x100
@@ -995,6 +996,7 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev
#define QUERY_DEV_LIM_MTU_WIDTH_OFFSET 0x36
#define QUERY_DEV_LIM_VL_PORT_OFFSET 0x37
#define QUERY_DEV_LIM_MAX_GID_OFFSET 0x3b
+#define QUERY_DEV_LIM_RATE_SUPPORT_OFFSET 0x3c
#define QUERY_DEV_LIM_MAX_PKEY_OFFSET 0x3f
#define QUERY_DEV_LIM_FLAGS_OFFSET 0x44
#define QUERY_DEV_LIM_RSVD_UAR_OFFSET 0x48
@@ -1086,6 +1088,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev
dev_lim->num_ports = field & 0xf;
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_GID_OFFSET);
dev_lim->max_gids = 1 << (field & 0xf);
+ MTHCA_GET(stat_rate, outbox, QUERY_DEV_LIM_RATE_SUPPORT_OFFSET);
+ dev_lim->stat_rate_support = stat_rate;
MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_PKEY_OFFSET);
dev_lim->max_pkeys = 1 << (field & 0xf);
MTHCA_GET(dev_lim->flags, outbox, QUERY_DEV_LIM_FLAGS_OFFSET);
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h
index e4ec35c..2f976f2 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.h
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.h
@@ -146,6 +146,7 @@ struct mthca_dev_lim {
int max_vl;
int num_ports;
int max_gids;
+ u16 stat_rate_support;
int max_pkeys;
u32 flags;
int reserved_uars;
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index ad52edb..49d0eae 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -172,6 +172,7 @@ struct mthca_limits {
int reserved_pds;
u32 page_size_cap;
u32 flags;
+ u16 stat_rate_support;
u8 port_width_cap;
};
@@ -353,10 +354,24 @@ struct mthca_dev {
struct ib_mad_agent *send_agent[MTHCA_MAX_PORTS][2];
struct ib_ah *sm_ah[MTHCA_MAX_PORTS];
spinlock_t sm_lock;
+ u8 rate[MTHCA_MAX_PORTS];
};
-#define mthca_dbg(mdev, format, arg...) \
- dev_dbg(&mdev->pdev->dev, format, ## arg)
+#ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
+extern int mthca_debug_level;
+
+#define mthca_dbg(mdev, format, arg...) \
+ do { \
+ if (mthca_debug_level) \
+ dev_printk(KERN_DEBUG, &mdev->pdev->dev, format, ## arg); \
+ } while (0)
+
+#else /* CONFIG_INFINIBAND_MTHCA_DEBUG */
+
+#define mthca_dbg(mdev, format, arg...) do { (void) mdev; } while (0)
+
+#endif /* CONFIG_INFINIBAND_MTHCA_DEBUG */
+
#define mthca_err(mdev, format, arg...) \
dev_err(&mdev->pdev->dev, format, ## arg)
#define mthca_info(mdev, format, arg...) \
@@ -542,6 +557,8 @@ int mthca_read_ah(struct mthca_dev *dev,
struct ib_ud_header *header);
int mthca_ah_query(struct ib_ah *ibah, struct ib_ah_attr *attr);
int mthca_ah_grh_present(struct mthca_ah *ah);
+u8 mthca_get_rate(struct mthca_dev *dev, int static_rate, u8 port);
+enum ib_rate mthca_rate_to_ib(struct mthca_dev *dev, u8 mthca_rate, u8 port);
int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
index dfb482e..f235c7e 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -49,6 +49,30 @@ enum {
MTHCA_VENDOR_CLASS2 = 0xa
};
+int mthca_update_rate(struct mthca_dev *dev, u8 port_num)
+{
+ struct ib_port_attr *tprops = NULL;
+ int ret;
+
+ tprops = kmalloc(sizeof *tprops, GFP_KERNEL);
+ if (!tprops)
+ return -ENOMEM;
+
+ ret = ib_query_port(&dev->ib_dev, port_num, tprops);
+ if (ret) {
+ printk(KERN_WARNING "ib_query_port failed (%d) for %s port %d\n",
+ ret, dev->ib_dev.name, port_num);
+ goto out;
+ }
+
+ dev->rate[port_num - 1] = tprops->active_speed *
+ ib_width_enum_to_int(tprops->active_width);
+
+out:
+ kfree(tprops);
+ return ret;
+}
+
static void update_sm_ah(struct mthca_dev *dev,
u8 port_num, u16 lid, u8 sl)
{
@@ -90,6 +114,7 @@ static void smp_snoop(struct ib_device *
mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
mad->mad_hdr.method == IB_MGMT_METHOD_SET) {
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
+ mthca_update_rate(to_mdev(ibdev), port_num);
update_sm_ah(to_mdev(ibdev), port_num,
be16_to_cpup((__be16 *) (mad->data + 58)),
(*(u8 *) (mad->data + 76)) & 0xf);
@@ -246,6 +271,7 @@ int mthca_create_agents(struct mthca_dev
{
struct ib_mad_agent *agent;
int p, q;
+ int ret;
spin_lock_init(&dev->sm_lock);
@@ -255,11 +281,23 @@ int mthca_create_agents(struct mthca_dev
q ? IB_QPT_GSI : IB_QPT_SMI,
NULL, 0, send_handler,
NULL, NULL);
- if (IS_ERR(agent))
+ if (IS_ERR(agent)) {
+ ret = PTR_ERR(agent);
goto err;
+ }
dev->send_agent[p][q] = agent;
}
+
+ for (p = 1; p <= dev->limits.num_ports; ++p) {
+ ret = mthca_update_rate(dev, p);
+ if (ret) {
+ mthca_err(dev, "Failed to obtain port %d rate."
+ " aborting.\n", p);
+ goto err;
+ }
+ }
+
return 0;
err:
@@ -268,7 +306,7 @@ err:
if (dev->send_agent[p][q])
ib_unregister_mad_agent(dev->send_agent[p][q]);
- return PTR_ERR(agent);
+ return ret;
}
void __devexit mthca_free_agents(struct mthca_dev *dev)
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 266f347..7e9c97b 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -52,6 +52,14 @@ MODULE_DESCRIPTION("Mellanox InfiniBand
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRV_VERSION);
+#ifdef CONFIG_INFINIBAND_MTHCA_DEBUG
+
+int mthca_debug_level = 0;
+module_param_named(debug_level, mthca_debug_level, int, 0644);
+MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
+
+#endif /* CONFIG_INFINIBAND_MTHCA_DEBUG */
+
#ifdef CONFIG_PCI_MSI
static int msi_x = 0;
@@ -69,6 +77,10 @@ MODULE_PARM_DESC(msi, "attempt to use MS
#endif /* CONFIG_PCI_MSI */
+static int tune_pci = 0;
+module_param(tune_pci, int, 0444);
+MODULE_PARM_DESC(tune_pci, "increase PCI burst from the default set by BIOS if nonzero");
+
static const char mthca_version[] __devinitdata =
DRV_NAME ": Mellanox InfiniBand HCA driver v"
DRV_VERSION " (" DRV_RELDATE ")\n";
@@ -90,6 +102,9 @@ static int __devinit mthca_tune_pci(stru
int cap;
u16 val;
+ if (!tune_pci)
+ return 0;
+
/* First try to max out Read Byte Count */
cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX);
if (cap) {
@@ -191,6 +206,18 @@ static int __devinit mthca_dev_lim(struc
mdev->limits.port_width_cap = dev_lim->max_port_width;
mdev->limits.page_size_cap = ~(u32) (dev_lim->min_page_sz - 1);
mdev->limits.flags = dev_lim->flags;
+ /*
+ * For old FW that doesn't return static rate support, use a
+ * value of 0x3 (only static rate values of 0 or 1 are handled),
+ * except on Sinai, where even old FW can handle static rate
+ * values of 2 and 3.
+ */
+ if (dev_lim->stat_rate_support)
+ mdev->limits.stat_rate_support = dev_lim->stat_rate_support;
+ else if (mdev->mthca_flags & MTHCA_FLAG_SINAI_OPT)
+ mdev->limits.stat_rate_support = 0xf;
+ else
+ mdev->limits.stat_rate_support = 0x3;
/* IB_DEVICE_RESIZE_MAX_WR not supported by driver.
May be doable since hardware supports it for SRQ.
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
index 2e7f521..6676a78 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.h
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h
@@ -257,6 +257,8 @@ struct mthca_qp {
atomic_t refcount;
u32 qpn;
int is_direct;
+ u8 port; /* for SQP and memfree use only */
+ u8 alt_port; /* for memfree use only */
u8 transport;
u8 state;
u8 atomic_rd_en;
@@ -278,7 +280,6 @@ struct mthca_qp {
struct mthca_sqp {
struct mthca_qp qp;
- int port;
int pkey_index;
u32 qkey;
u32 send_psn;
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 057c8e6..f37b0e3 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -248,6 +248,9 @@ void mthca_qp_event(struct mthca_dev *de
return;
}
+ if (event_type == IB_EVENT_PATH_MIG)
+ qp->port = qp->alt_port;
+
event.device = &dev->ib_dev;
event.event = event_type;
event.element.qp = &qp->ibqp;
@@ -392,10 +395,16 @@ static void to_ib_ah_attr(struct mthca_d
{
memset(ib_ah_attr, 0, sizeof *path);
ib_ah_attr->port_num = (be32_to_cpu(path->port_pkey) >> 24) & 0x3;
+
+ if (ib_ah_attr->port_num == 0 || ib_ah_attr->port_num > dev->limits.num_ports)
+ return;
+
ib_ah_attr->dlid = be16_to_cpu(path->rlid);
ib_ah_attr->sl = be32_to_cpu(path->sl_tclass_flowlabel) >> 28;
ib_ah_attr->src_path_bits = path->g_mylmc & 0x7f;
- ib_ah_attr->static_rate = path->static_rate & 0x7;
+ ib_ah_attr->static_rate = mthca_rate_to_ib(dev,
+ path->static_rate & 0x7,
+ ib_ah_attr->port_num);
ib_ah_attr->ah_flags = (path->g_mylmc & (1 << 7)) ? IB_AH_GRH : 0;
if (ib_ah_attr->ah_flags) {
ib_ah_attr->grh.sgid_index = path->mgid_index & (dev->limits.gid_table_len - 1);
@@ -455,8 +464,10 @@ int mthca_query_qp(struct ib_qp *ibqp, s
qp_attr->cap.max_recv_sge = qp->rq.max_gs;
qp_attr->cap.max_inline_data = qp->max_inline_data;
- to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path);
- to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path);
+ if (qp->transport == RC || qp->transport == UC) {
+ to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path);
+ to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path);
+ }
qp_attr->pkey_index = be32_to_cpu(context->pri_path.port_pkey) & 0x7f;
qp_attr->alt_pkey_index = be32_to_cpu(context->alt_path.port_pkey) & 0x7f;
@@ -484,11 +495,11 @@ out:
}
static int mthca_path_set(struct mthca_dev *dev, struct ib_ah_attr *ah,
- struct mthca_qp_path *path)
+ struct mthca_qp_path *path, u8 port)
{
path->g_mylmc = ah->src_path_bits & 0x7f;
path->rlid = cpu_to_be16(ah->dlid);
- path->static_rate = !!ah->static_rate;
+ path->static_rate = mthca_get_rate(dev, ah->static_rate, port);
if (ah->ah_flags & IB_AH_GRH) {
if (ah->grh.sgid_index >= dev->limits.gid_table_len) {
@@ -634,7 +645,7 @@ int mthca_modify_qp(struct ib_qp *ibqp,
if (qp->transport == MLX)
qp_context->pri_path.port_pkey |=
- cpu_to_be32(to_msqp(qp)->port << 24);
+ cpu_to_be32(qp->port << 24);
else {
if (attr_mask & IB_QP_PORT) {
qp_context->pri_path.port_pkey |=
@@ -657,7 +668,8 @@ int mthca_modify_qp(struct ib_qp *ibqp,
}
if (attr_mask & IB_QP_AV) {
- if (mthca_path_set(dev, &attr->ah_attr, &qp_context->pri_path))
+ if (mthca_path_set(dev, &attr->ah_attr, &qp_context->pri_path,
+ attr_mask & IB_QP_PORT ? attr->port_num : qp->port))
return -EINVAL;
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH);
@@ -681,7 +693,8 @@ int mthca_modify_qp(struct ib_qp *ibqp,
return -EINVAL;
}
- if (mthca_path_set(dev, &attr->alt_ah_attr, &qp_context->alt_path))
+ if (mthca_path_set(dev, &attr->alt_ah_attr, &qp_context->alt_path,
+ attr->alt_ah_attr.port_num))
return -EINVAL;
qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index |
@@ -791,6 +804,10 @@ int mthca_modify_qp(struct ib_qp *ibqp,
qp->atomic_rd_en = attr->qp_access_flags;
if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
qp->resp_depth = attr->max_dest_rd_atomic;
+ if (attr_mask & IB_QP_PORT)
+ qp->port = attr->port_num;
+ if (attr_mask & IB_QP_ALT_PATH)
+ qp->alt_port = attr->alt_port_num;
if (is_sqp(dev, qp))
store_attrs(to_msqp(qp), attr, attr_mask);
@@ -802,13 +819,13 @@ int mthca_modify_qp(struct ib_qp *ibqp,
if (is_qp0(dev, qp)) {
if (cur_state != IB_QPS_RTR &&
new_state == IB_QPS_RTR)
- init_port(dev, to_msqp(qp)->port);
+ init_port(dev, qp->port);
if (cur_state != IB_QPS_RESET &&
cur_state != IB_QPS_ERR &&
(new_state == IB_QPS_RESET ||
new_state == IB_QPS_ERR))
- mthca_CLOSE_IB(dev, to_msqp(qp)->port, &status);
+ mthca_CLOSE_IB(dev, qp->port, &status);
}
/*
@@ -1212,6 +1229,9 @@ int mthca_alloc_qp(struct mthca_dev *dev
if (qp->qpn == -1)
return -ENOMEM;
+ /* initialize port to zero for error-catching. */
+ qp->port = 0;
+
err = mthca_alloc_qp_common(dev, pd, send_cq, recv_cq,
send_policy, qp);
if (err) {
@@ -1261,7 +1281,7 @@ int mthca_alloc_sqp(struct mthca_dev *de
if (err)
goto err_out;
- sqp->port = port;
+ sqp->qp.port = port;
sqp->qp.qpn = mqpn;
sqp->qp.transport = MLX;
@@ -1404,10 +1424,10 @@ static int build_mlx_header(struct mthca
sqp->ud_header.lrh.source_lid = IB_LID_PERMISSIVE;
sqp->ud_header.bth.solicited_event = !!(wr->send_flags & IB_SEND_SOLICITED);
if (!sqp->qp.ibqp.qp_num)
- ib_get_cached_pkey(&dev->ib_dev, sqp->port,
+ ib_get_cached_pkey(&dev->ib_dev, sqp->qp.port,
sqp->pkey_index, &pkey);
else
- ib_get_cached_pkey(&dev->ib_dev, sqp->port,
+ ib_get_cached_pkey(&dev->ib_dev, sqp->qp.port,
wr->wr.ud.pkey_index, &pkey);
sqp->ud_header.bth.pkey = cpu_to_be16(pkey);
sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->wr.ud.remote_qpn);
diff --git a/drivers/infiniband/ulp/ipoib/Kconfig b/drivers/infiniband/ulp/ipoib/Kconfig
index 8d2e04c..13d6d01 100644
--- a/drivers/infiniband/ulp/ipoib/Kconfig
+++ b/drivers/infiniband/ulp/ipoib/Kconfig
@@ -10,8 +10,9 @@ config INFINIBAND_IPOIB
group: <http://www.ietf.org/html.charters/ipoib-charter.html>.
config INFINIBAND_IPOIB_DEBUG
- bool "IP-over-InfiniBand debugging"
+ bool "IP-over-InfiniBand debugging" if EMBEDDED
depends on INFINIBAND_IPOIB
+ default y
---help---
This option causes debugging code to be compiled into the
IPoIB driver. The output can be turned on via the
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index b640107..12a1e05 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -65,6 +65,8 @@ enum {
IPOIB_RX_RING_SIZE = 128,
IPOIB_TX_RING_SIZE = 64,
+ IPOIB_MAX_QUEUE_SIZE = 8192,
+ IPOIB_MIN_QUEUE_SIZE = 2,
IPOIB_NUM_WC = 4,
@@ -230,6 +232,9 @@ static inline struct ipoib_neigh **to_ip
INFINIBAND_ALEN, sizeof(void *));
}
+struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh);
+void ipoib_neigh_free(struct ipoib_neigh *neigh);
+
extern struct workqueue_struct *ipoib_workqueue;
/* functions */
@@ -329,6 +334,8 @@ static inline void ipoib_unregister_debu
#define ipoib_warn(priv, format, arg...) \
ipoib_printk(KERN_WARNING, priv, format , ## arg)
+extern int ipoib_sendq_size;
+extern int ipoib_recvq_size;
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
extern int ipoib_debug_level;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
index 685258e..5dde380 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
@@ -213,7 +213,7 @@ static int ipoib_path_seq_show(struct se
gid_buf, path.pathrec.dlid ? "yes" : "no");
if (path.pathrec.dlid) {
- rate = ib_sa_rate_enum_to_int(path.pathrec.rate) * 25;
+ rate = ib_rate_to_mult(path.pathrec.rate) * 25;
seq_printf(file,
" DLID: 0x%04x\n"
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index ed65202..a54da42 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -161,7 +161,7 @@ static int ipoib_ib_post_receives(struct
struct ipoib_dev_priv *priv = netdev_priv(dev);
int i;
- for (i = 0; i < IPOIB_RX_RING_SIZE; ++i) {
+ for (i = 0; i < ipoib_recvq_size; ++i) {
if (ipoib_alloc_rx_skb(dev, i)) {
ipoib_warn(priv, "failed to allocate receive buffer %d\n", i);
return -ENOMEM;
@@ -187,7 +187,7 @@ static void ipoib_ib_handle_wc(struct ne
if (wr_id & IPOIB_OP_RECV) {
wr_id &= ~IPOIB_OP_RECV;
- if (wr_id < IPOIB_RX_RING_SIZE) {
+ if (wr_id < ipoib_recvq_size) {
struct sk_buff *skb = priv->rx_ring[wr_id].skb;
dma_addr_t addr = priv->rx_ring[wr_id].mapping;
@@ -252,9 +252,9 @@ static void ipoib_ib_handle_wc(struct ne
struct ipoib_tx_buf *tx_req;
unsigned long flags;
- if (wr_id >= IPOIB_TX_RING_SIZE) {
+ if (wr_id >= ipoib_sendq_size) {
ipoib_warn(priv, "completion event with wrid %d (> %d)\n",
- wr_id, IPOIB_TX_RING_SIZE);
+ wr_id, ipoib_sendq_size);
return;
}
@@ -275,7 +275,7 @@ static void ipoib_ib_handle_wc(struct ne
spin_lock_irqsave(&priv->tx_lock, flags);
++priv->tx_tail;
if (netif_queue_stopped(dev) &&
- priv->tx_head - priv->tx_tail <= IPOIB_TX_RING_SIZE / 2)
+ priv->tx_head - priv->tx_tail <= ipoib_sendq_size >> 1)
netif_wake_queue(dev);
spin_unlock_irqrestore(&priv->tx_lock, flags);
@@ -344,13 +344,13 @@ void ipoib_send(struct net_device *dev,
* means we have to make sure everything is properly recorded and
* our state is consistent before we call post_send().
*/
- tx_req = &priv->tx_ring[priv->tx_head & (IPOIB_TX_RING_SIZE - 1)];
+ tx_req = &priv->tx_ring[priv->tx_head & (ipoib_sendq_size - 1)];
tx_req->skb = skb;
addr = dma_map_single(priv->ca->dma_device, skb->data, skb->len,
DMA_TO_DEVICE);
pci_unmap_addr_set(tx_req, mapping, addr);
- if (unlikely(post_send(priv, priv->tx_head & (IPOIB_TX_RING_SIZE - 1),
+ if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
address->ah, qpn, addr, skb->len))) {
ipoib_warn(priv, "post_send failed\n");
++priv->stats.tx_errors;
@@ -363,7 +363,7 @@ void ipoib_send(struct net_device *dev,
address->last_send = priv->tx_head;
++priv->tx_head;
- if (priv->tx_head - priv->tx_tail == IPOIB_TX_RING_SIZE) {
+ if (priv->tx_head - priv->tx_tail == ipoib_sendq_size) {
ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
netif_stop_queue(dev);
}
@@ -488,7 +488,7 @@ static int recvs_pending(struct net_devi
int pending = 0;
int i;
- for (i = 0; i < IPOIB_RX_RING_SIZE; ++i)
+ for (i = 0; i < ipoib_recvq_size; ++i)
if (priv->rx_ring[i].skb)
++pending;
@@ -527,7 +527,7 @@ int ipoib_ib_dev_stop(struct net_device
*/
while ((int) priv->tx_tail - (int) priv->tx_head < 0) {
tx_req = &priv->tx_ring[priv->tx_tail &
- (IPOIB_TX_RING_SIZE - 1)];
+ (ipoib_sendq_size - 1)];
dma_unmap_single(priv->ca->dma_device,
pci_unmap_addr(tx_req, mapping),
tx_req->skb->len,
@@ -536,7 +536,7 @@ int ipoib_ib_dev_stop(struct net_device
++priv->tx_tail;
}
- for (i = 0; i < IPOIB_RX_RING_SIZE; ++i)
+ for (i = 0; i < ipoib_recvq_size; ++i)
if (priv->rx_ring[i].skb) {
dma_unmap_single(priv->ca->dma_device,
pci_unmap_addr(&priv->rx_ring[i],
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 9b0bd7c..cb078a7 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -41,6 +41,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/kernel.h>
#include <linux/if_arp.h> /* For ARPHRD_xxx */
@@ -53,6 +54,14 @@ MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
MODULE_LICENSE("Dual BSD/GPL");
+int ipoib_sendq_size __read_mostly = IPOIB_TX_RING_SIZE;
+int ipoib_recvq_size __read_mostly = IPOIB_RX_RING_SIZE;
+
+module_param_named(send_queue_size, ipoib_sendq_size, int, 0444);
+MODULE_PARM_DESC(send_queue_size, "Number of descriptors in send queue");
+module_param_named(recv_queue_size, ipoib_recvq_size, int, 0444);
+MODULE_PARM_DESC(recv_queue_size, "Number of descriptors in receive queue");
+
#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
int ipoib_debug_level;
@@ -252,8 +261,8 @@ static void path_free(struct net_device
*/
if (neigh->ah)
ipoib_put_ah(neigh->ah);
- *to_ipoib_neigh(neigh->neighbour) = NULL;
- kfree(neigh);
+
+ ipoib_neigh_free(neigh);
}
spin_unlock_irqrestore(&priv->lock, flags);
@@ -327,9 +336,8 @@ void ipoib_flush_paths(struct net_device
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_path *path, *tp;
LIST_HEAD(remove_list);
- unsigned long flags;
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock_irq(&priv->lock);
list_splice(&priv->path_list, &remove_list);
INIT_LIST_HEAD(&priv->path_list);
@@ -337,14 +345,15 @@ void ipoib_flush_paths(struct net_device
list_for_each_entry(path, &remove_list, list)
rb_erase(&path->rb_node, &priv->path_tree);
- spin_unlock_irqrestore(&priv->lock, flags);
-
list_for_each_entry_safe(path, tp, &remove_list, list) {
if (path->query)
ib_sa_cancel_query(path->query_id, path->query);
+ spin_unlock_irq(&priv->lock);
wait_for_completion(&path->done);
path_free(dev, path);
+ spin_lock_irq(&priv->lock);
}
+ spin_unlock_irq(&priv->lock);
}
static void path_rec_completion(int status,
@@ -373,16 +382,9 @@ static void path_rec_completion(int stat
struct ib_ah_attr av = {
.dlid = be16_to_cpu(pathrec->dlid),
.sl = pathrec->sl,
- .port_num = priv->port
+ .port_num = priv->port,
+ .static_rate = pathrec->rate
};
- int path_rate = ib_sa_rate_enum_to_int(pathrec->rate);
-
- if (path_rate > 0 && priv->local_rate > path_rate)
- av.static_rate = (priv->local_rate - 1) / path_rate;
-
- ipoib_dbg(priv, "static_rate %d for local port %dX, path %dX\n",
- av.static_rate, priv->local_rate,
- ib_sa_rate_enum_to_int(pathrec->rate));
ah = ipoib_create_ah(dev, priv->pd, &av);
}
@@ -481,7 +483,7 @@ static void neigh_add_path(struct sk_buf
struct ipoib_path *path;
struct ipoib_neigh *neigh;
- neigh = kmalloc(sizeof *neigh, GFP_ATOMIC);
+ neigh = ipoib_neigh_alloc(skb->dst->neighbour);
if (!neigh) {
++priv->stats.tx_dropped;
dev_kfree_skb_any(skb);
@@ -489,8 +491,6 @@ static void neigh_add_path(struct sk_buf
}
skb_queue_head_init(&neigh->queue);
- neigh->neighbour = skb->dst->neighbour;
- *to_ipoib_neigh(skb->dst->neighbour) = neigh;
/*
* We can only be called from ipoib_start_xmit, so we're
@@ -503,7 +503,7 @@ static void neigh_add_path(struct sk_buf
path = path_rec_create(dev,
(union ib_gid *) (skb->dst->neighbour->ha + 4));
if (!path)
- goto err;
+ goto err_path;
__path_add(dev, path);
}
@@ -521,17 +521,17 @@ static void neigh_add_path(struct sk_buf
__skb_queue_tail(&neigh->queue, skb);
if (!path->query && path_rec_start(dev, path))
- goto err;
+ goto err_list;
}
spin_unlock(&priv->lock);
return;
-err:
- *to_ipoib_neigh(skb->dst->neighbour) = NULL;
+err_list:
list_del(&neigh->list);
- kfree(neigh);
+err_path:
+ ipoib_neigh_free(neigh);
++priv->stats.tx_dropped;
dev_kfree_skb_any(skb);
@@ -763,8 +763,7 @@ static void ipoib_neigh_destructor(struc
if (neigh->ah)
ah = neigh->ah;
list_del(&neigh->list);
- *to_ipoib_neigh(n) = NULL;
- kfree(neigh);
+ ipoib_neigh_free(neigh);
}
spin_unlock_irqrestore(&priv->lock, flags);
@@ -773,6 +772,26 @@ static void ipoib_neigh_destructor(struc
ipoib_put_ah(ah);
}
+struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour)
+{
+ struct ipoib_neigh *neigh;
+
+ neigh = kmalloc(sizeof *neigh, GFP_ATOMIC);
+ if (!neigh)
+ return NULL;
+
+ neigh->neighbour = neighbour;
+ *to_ipoib_neigh(neighbour) = neigh;
+
+ return neigh;
+}
+
+void ipoib_neigh_free(struct ipoib_neigh *neigh)
+{
+ *to_ipoib_neigh(neigh->neighbour) = NULL;
+ kfree(neigh);
+}
+
static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
{
parms->neigh_destructor = ipoib_neigh_destructor;
@@ -785,20 +804,19 @@ int ipoib_dev_init(struct net_device *de
struct ipoib_dev_priv *priv = netdev_priv(dev);
/* Allocate RX/TX "rings" to hold queued skbs */
-
- priv->rx_ring = kzalloc(IPOIB_RX_RING_SIZE * sizeof (struct ipoib_rx_buf),
+ priv->rx_ring = kzalloc(ipoib_recvq_size * sizeof *priv->rx_ring,
GFP_KERNEL);
if (!priv->rx_ring) {
printk(KERN_WARNING "%s: failed to allocate RX ring (%d entries)\n",
- ca->name, IPOIB_RX_RING_SIZE);
+ ca->name, ipoib_recvq_size);
goto out;
}
- priv->tx_ring = kzalloc(IPOIB_TX_RING_SIZE * sizeof (struct ipoib_tx_buf),
+ priv->tx_ring = kzalloc(ipoib_sendq_size * sizeof *priv->tx_ring,
GFP_KERNEL);
if (!priv->tx_ring) {
printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n",
- ca->name, IPOIB_TX_RING_SIZE);
+ ca->name, ipoib_sendq_size);
goto out_rx_ring_cleanup;
}
@@ -866,7 +884,7 @@ static void ipoib_setup(struct net_devic
dev->hard_header_len = IPOIB_ENCAP_LEN + INFINIBAND_ALEN;
dev->addr_len = INFINIBAND_ALEN;
dev->type = ARPHRD_INFINIBAND;
- dev->tx_queue_len = IPOIB_TX_RING_SIZE * 2;
+ dev->tx_queue_len = ipoib_sendq_size * 2;
dev->features = NETIF_F_VLAN_CHALLENGED | NETIF_F_LLTX;
/* MTU will be reset when mcast join happens */
@@ -1118,6 +1136,14 @@ static int __init ipoib_init_module(void
{
int ret;
+ ipoib_recvq_size = roundup_pow_of_two(ipoib_recvq_size);
+ ipoib_recvq_size = min(ipoib_recvq_size, IPOIB_MAX_QUEUE_SIZE);
+ ipoib_recvq_size = max(ipoib_recvq_size, IPOIB_MIN_QUEUE_SIZE);
+
+ ipoib_sendq_size = roundup_pow_of_two(ipoib_sendq_size);
+ ipoib_sendq_size = min(ipoib_sendq_size, IPOIB_MAX_QUEUE_SIZE);
+ ipoib_sendq_size = max(ipoib_sendq_size, IPOIB_MIN_QUEUE_SIZE);
+
ret = ipoib_register_debugfs();
if (ret)
return ret;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 93c462e..1dae4b2 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -114,8 +114,7 @@ static void ipoib_mcast_free(struct ipoi
*/
if (neigh->ah)
ipoib_put_ah(neigh->ah);
- *to_ipoib_neigh(neigh->neighbour) = NULL;
- kfree(neigh);
+ ipoib_neigh_free(neigh);
}
spin_unlock_irqrestore(&priv->lock, flags);
@@ -251,6 +250,7 @@ static int ipoib_mcast_join_finish(struc
.port_num = priv->port,
.sl = mcast->mcmember.sl,
.ah_flags = IB_AH_GRH,
+ .static_rate = mcast->mcmember.rate,
.grh = {
.flow_label = be32_to_cpu(mcast->mcmember.flow_label),
.hop_limit = mcast->mcmember.hop_limit,
@@ -258,17 +258,8 @@ static int ipoib_mcast_join_finish(struc
.traffic_class = mcast->mcmember.traffic_class
}
};
- int path_rate = ib_sa_rate_enum_to_int(mcast->mcmember.rate);
-
av.grh.dgid = mcast->mcmember.mgid;
- if (path_rate > 0 && priv->local_rate > path_rate)
- av.static_rate = (priv->local_rate - 1) / path_rate;
-
- ipoib_dbg_mcast(priv, "static_rate %d for local port %dX, mcmember %dX\n",
- av.static_rate, priv->local_rate,
- ib_sa_rate_enum_to_int(mcast->mcmember.rate));
-
ah = ipoib_create_ah(dev, priv->pd, &av);
if (!ah) {
ipoib_warn(priv, "ib_address_create failed\n");
@@ -618,6 +609,22 @@ int ipoib_mcast_start_thread(struct net_
return 0;
}
+static void wait_for_mcast_join(struct ipoib_dev_priv *priv,
+ struct ipoib_mcast *mcast)
+{
+ spin_lock_irq(&priv->lock);
+ if (mcast && mcast->query) {
+ ib_sa_cancel_query(mcast->query_id, mcast->query);
+ mcast->query = NULL;
+ spin_unlock_irq(&priv->lock);
+ ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n",
+ IPOIB_GID_ARG(mcast->mcmember.mgid));
+ wait_for_completion(&mcast->done);
+ }
+ else
+ spin_unlock_irq(&priv->lock);
+}
+
int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -637,28 +644,10 @@ int ipoib_mcast_stop_thread(struct net_d
if (flush)
flush_workqueue(ipoib_workqueue);
- spin_lock_irq(&priv->lock);
- if (priv->broadcast && priv->broadcast->query) {
- ib_sa_cancel_query(priv->broadcast->query_id, priv->broadcast->query);
- priv->broadcast->query = NULL;
- spin_unlock_irq(&priv->lock);
- ipoib_dbg_mcast(priv, "waiting for bcast\n");
- wait_for_completion(&priv->broadcast->done);
- } else
- spin_unlock_irq(&priv->lock);
+ wait_for_mcast_join(priv, priv->broadcast);
- list_for_each_entry(mcast, &priv->multicast_list, list) {
- spin_lock_irq(&priv->lock);
- if (mcast->query) {
- ib_sa_cancel_query(mcast->query_id, mcast->query);
- mcast->query = NULL;
- spin_unlock_irq(&priv->lock);
- ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid));
- wait_for_completion(&mcast->done);
- } else
- spin_unlock_irq(&priv->lock);
- }
+ list_for_each_entry(mcast, &priv->multicast_list, list)
+ wait_for_mcast_join(priv, mcast);
return 0;
}
@@ -772,13 +761,11 @@ out:
if (skb->dst &&
skb->dst->neighbour &&
!*to_ipoib_neigh(skb->dst->neighbour)) {
- struct ipoib_neigh *neigh = kmalloc(sizeof *neigh, GFP_ATOMIC);
+ struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour);
if (neigh) {
kref_get(&mcast->ah->ref);
neigh->ah = mcast->ah;
- neigh->neighbour = skb->dst->neighbour;
- *to_ipoib_neigh(skb->dst->neighbour) = neigh;
list_add_tail(&neigh->list, &mcast->neigh_list);
}
}
@@ -913,6 +900,7 @@ void ipoib_mcast_restart_task(void *dev_
/* We have to cancel outside of the spinlock */
list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
+ wait_for_mcast_join(priv, mcast);
ipoib_mcast_leave(mcast->dev, mcast);
ipoib_mcast_free(mcast);
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index 5f03880..1d49d16 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -159,8 +159,8 @@ int ipoib_transport_dev_init(struct net_
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ib_qp_init_attr init_attr = {
.cap = {
- .max_send_wr = IPOIB_TX_RING_SIZE,
- .max_recv_wr = IPOIB_RX_RING_SIZE,
+ .max_send_wr = ipoib_sendq_size,
+ .max_recv_wr = ipoib_recvq_size,
.max_send_sge = 1,
.max_recv_sge = 1
},
@@ -175,7 +175,7 @@ int ipoib_transport_dev_init(struct net_
}
priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev,
- IPOIB_TX_RING_SIZE + IPOIB_RX_RING_SIZE + 1);
+ ipoib_sendq_size + ipoib_recvq_size + 1);
if (IS_ERR(priv->cq)) {
printk(KERN_WARNING "%s: failed to create CQ\n", ca->name);
goto out_free_pd;
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index fd8a95a..5f2b3f6 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1434,6 +1434,7 @@ static int srp_parse_options(const char
p = match_strdup(args);
if (strlen(p) != 32) {
printk(KERN_WARNING PFX "bad dest GID parameter '%s'\n", p);
+ kfree(p);
goto out;
}
diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h
index 0a9fcd5..c552ee7 100644
--- a/include/rdma/ib_cm.h
+++ b/include/rdma/ib_cm.h
@@ -292,6 +292,10 @@ struct ib_cm_id {
u32 remote_cm_qpn; /* 1 unless redirected */
};
+struct ib_cm_id *__ib_create_cm_id(struct ib_device *device,
+ ib_cm_handler cm_handler,
+ void *context, struct module *owner);
+
/**
* ib_create_cm_id - Allocate a communication identifier.
* @device: Device associated with the cm_id. All related communication will
@@ -303,9 +307,12 @@ struct ib_cm_id {
* Communication identifiers are used to track connection states, service
* ID resolution requests, and listen requests.
*/
-struct ib_cm_id *ib_create_cm_id(struct ib_device *device,
- ib_cm_handler cm_handler,
- void *context);
+static inline struct ib_cm_id *ib_create_cm_id(struct ib_device *device,
+ ib_cm_handler cm_handler,
+ void *context)
+{
+ return __ib_create_cm_id(device, cm_handler, context, THIS_MODULE);
+}
/**
* ib_destroy_cm_id - Destroy a connection identifier.
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
index f404fe2..6769d1b 100644
--- a/include/rdma/ib_sa.h
+++ b/include/rdma/ib_sa.h
@@ -91,34 +91,6 @@ enum ib_sa_selector {
IB_SA_BEST = 3
};
-enum ib_sa_rate {
- IB_SA_RATE_2_5_GBPS = 2,
- IB_SA_RATE_5_GBPS = 5,
- IB_SA_RATE_10_GBPS = 3,
- IB_SA_RATE_20_GBPS = 6,
- IB_SA_RATE_30_GBPS = 4,
- IB_SA_RATE_40_GBPS = 7,
- IB_SA_RATE_60_GBPS = 8,
- IB_SA_RATE_80_GBPS = 9,
- IB_SA_RATE_120_GBPS = 10
-};
-
-static inline int ib_sa_rate_enum_to_int(enum ib_sa_rate rate)
-{
- switch (rate) {
- case IB_SA_RATE_2_5_GBPS: return 1;
- case IB_SA_RATE_5_GBPS: return 2;
- case IB_SA_RATE_10_GBPS: return 4;
- case IB_SA_RATE_20_GBPS: return 8;
- case IB_SA_RATE_30_GBPS: return 12;
- case IB_SA_RATE_40_GBPS: return 16;
- case IB_SA_RATE_60_GBPS: return 24;
- case IB_SA_RATE_80_GBPS: return 32;
- case IB_SA_RATE_120_GBPS: return 48;
- default: return -1;
- }
-}
-
/*
* Structures for SA records are named "struct ib_sa_xxx_rec." No
* attempt is made to pack structures to match the physical layout of
@@ -282,37 +254,80 @@ struct ib_sa_query;
void ib_sa_cancel_query(int id, struct ib_sa_query *query);
-int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
- struct ib_sa_path_rec *rec,
- ib_sa_comp_mask comp_mask,
- int timeout_ms, gfp_t gfp_mask,
- void (*callback)(int status,
- struct ib_sa_path_rec *resp,
- void *context),
- void *context,
- struct ib_sa_query **query);
-
-int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
- u8 method,
- struct ib_sa_mcmember_rec *rec,
- ib_sa_comp_mask comp_mask,
- int timeout_ms, gfp_t gfp_mask,
- void (*callback)(int status,
- struct ib_sa_mcmember_rec *resp,
- void *context),
- void *context,
- struct ib_sa_query **query);
-
-int ib_sa_service_rec_query(struct ib_device *device, u8 port_num,
- u8 method,
- struct ib_sa_service_rec *rec,
+int __ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
+ struct ib_sa_path_rec *rec,
ib_sa_comp_mask comp_mask,
int timeout_ms, gfp_t gfp_mask,
void (*callback)(int status,
- struct ib_sa_service_rec *resp,
+ struct ib_sa_path_rec *resp,
void *context),
void *context,
- struct ib_sa_query **sa_query);
+ struct module *owner,
+ struct ib_sa_query **query);
+
+int __ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num,
+ u8 method,
+ struct ib_sa_mcmember_rec *rec,
+ ib_sa_comp_mask comp_mask,
+ int timeout_ms, gfp_t gfp_mask,
+ void (*callback)(int status,
+ struct ib_sa_mcmember_rec *resp,
+ void *context),
+ void *context,
+ struct module *owner,
+ struct ib_sa_query **query);
+
+int __ib_sa_service_rec_query(struct ib_device *device, u8 port_num,
+ u8 method,
+ struct ib_sa_service_rec *rec,
+ ib_sa_comp_mask comp_mask,
+ int timeout_ms, gfp_t gfp_mask,
+ void (*callback)(int status,
+ struct ib_sa_service_rec *resp,
+ void *context),
+ void *context,
+ struct module *owner,
+ struct ib_sa_query **sa_query);
+
+/**
+ * ib_sa_path_rec_get - Start a Path get query
+ * @device:device to send query on
+ * @port_num: port number to send query on
+ * @rec:Path Record to send in query
+ * @comp_mask:component mask to send in query
+ * @timeout_ms:time to wait for response
+ * @gfp_mask:GFP mask to use for internal allocations
+ * @callback:function called when query completes, times out or is
+ * canceled
+ * @context:opaque user context passed to callback
+ * @sa_query:query context, used to cancel query
+ *
+ * Send a Path Record Get query to the SA to look up a path. The
+ * callback function will be called when the query completes (or
+ * fails); status is 0 for a successful response, -EINTR if the query
+ * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
+ * occurred sending the query. The resp parameter of the callback is
+ * only valid if status is 0.
+ *
+ * If the return value of ib_sa_path_rec_get() is negative, it is an
+ * error code. Otherwise it is a query ID that can be used to cancel
+ * the query.
+ */
+static inline int
+ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
+ struct ib_sa_path_rec *rec,
+ ib_sa_comp_mask comp_mask,
+ int timeout_ms, gfp_t gfp_mask,
+ void (*callback)(int status,
+ struct ib_sa_path_rec *resp,
+ void *context),
+ void *context,
+ struct ib_sa_query **sa_query)
+{
+ return __ib_sa_path_rec_get(device, port_num, rec, comp_mask,
+ timeout_ms, gfp_mask, callback,
+ context, THIS_MODULE, sa_query);
+}
/**
* ib_sa_mcmember_rec_set - Start an MCMember set query
@@ -349,11 +364,11 @@ ib_sa_mcmember_rec_set(struct ib_device
void *context,
struct ib_sa_query **query)
{
- return ib_sa_mcmember_rec_query(device, port_num,
- IB_MGMT_METHOD_SET,
- rec, comp_mask,
- timeout_ms, gfp_mask, callback,
- context, query);
+ return __ib_sa_mcmember_rec_query(device, port_num,
+ IB_MGMT_METHOD_SET,
+ rec, comp_mask,
+ timeout_ms, gfp_mask, callback,
+ context, THIS_MODULE, query);
}
/**
@@ -391,12 +406,54 @@ ib_sa_mcmember_rec_delete(struct ib_devi
void *context,
struct ib_sa_query **query)
{
- return ib_sa_mcmember_rec_query(device, port_num,
- IB_SA_METHOD_DELETE,
- rec, comp_mask,
- timeout_ms, gfp_mask, callback,
- context, query);
+ return __ib_sa_mcmember_rec_query(device, port_num,
+ IB_SA_METHOD_DELETE,
+ rec, comp_mask,
+ timeout_ms, gfp_mask, callback,
+ context, THIS_MODULE, query);
}
+/**
+ * ib_sa_service_rec_query - Start Service Record operation
+ * @device:device to send request on
+ * @port_num: port number to send request on
+ * @method:SA method - should be get, set, or delete
+ * @rec:Service Record to send in request
+ * @comp_mask:component mask to send in request
+ * @timeout_ms:time to wait for response
+ * @gfp_mask:GFP mask to use for internal allocations
+ * @callback:function called when request completes, times out or is
+ * canceled
+ * @context:opaque user context passed to callback
+ * @sa_query:request context, used to cancel request
+ *
+ * Send a Service Record set/get/delete to the SA to register,
+ * unregister or query a service record.
+ * The callback function will be called when the request completes (or
+ * fails); status is 0 for a successful response, -EINTR if the query
+ * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
+ * occurred sending the query. The resp parameter of the callback is
+ * only valid if status is 0.
+ *
+ * If the return value of ib_sa_service_rec_query() is negative, it is an
+ * error code. Otherwise it is a request ID that can be used to cancel
+ * the query.
+ */
+static inline int
+ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
+ struct ib_sa_service_rec *rec,
+ ib_sa_comp_mask comp_mask,
+ int timeout_ms, gfp_t gfp_mask,
+ void (*callback)(int status,
+ struct ib_sa_service_rec *resp,
+ void *context),
+ void *context,
+ struct ib_sa_query **sa_query)
+{
+ return __ib_sa_service_rec_query(device, port_num, method, rec,
+ comp_mask, timeout_ms, gfp_mask,
+ callback, context, THIS_MODULE,
+ sa_query);
+}
#endif /* IB_SA_H */
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index c1ad627..6bbf1b3 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -314,6 +314,34 @@ enum ib_ah_flags {
IB_AH_GRH = 1
};
+enum ib_rate {
+ IB_RATE_PORT_CURRENT = 0,
+ IB_RATE_2_5_GBPS = 2,
+ IB_RATE_5_GBPS = 5,
+ IB_RATE_10_GBPS = 3,
+ IB_RATE_20_GBPS = 6,
+ IB_RATE_30_GBPS = 4,
+ IB_RATE_40_GBPS = 7,
+ IB_RATE_60_GBPS = 8,
+ IB_RATE_80_GBPS = 9,
+ IB_RATE_120_GBPS = 10
+};
+
+/**
+ * ib_rate_to_mult - Convert the IB rate enum to a multiple of the
+ * base rate of 2.5 Gbit/sec. For example, IB_RATE_5_GBPS will be
+ * converted to 2, since 5 Gbit/sec is 2 * 2.5 Gbit/sec.
+ * @rate: rate to convert.
+ */
+int ib_rate_to_mult(enum ib_rate rate) __attribute_const__;
+
+/**
+ * mult_to_ib_rate - Convert a multiple of 2.5 Gbit/sec to an IB rate
+ * enum.
+ * @mult: multiple to convert.
+ */
+enum ib_rate mult_to_ib_rate(int mult) __attribute_const__;
+
struct ib_ah_attr {
struct ib_global_route grh;
u16 dlid;
^ permalink raw reply related
* Re: [PATCH] git log [diff-tree options]...
From: Johannes Schindelin @ 2006-04-09 22:01 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0604092312340.29136@wbgn013.biozentrum.uni-wuerzburg.de>
Hi,
On Sun, 9 Apr 2006, Johannes Schindelin wrote:
> On Sun, 9 Apr 2006, Linus Torvalds wrote:
>
> > - keep it - for historical reasons - as a internal shorthand, and just
> > turn it into "git log --diff -cc"
>
> It is "git log --cc", right?
Like this?
---
git.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
751e205a9ffd3a55094a0c0f657735023776cf74
diff --git a/git.c b/git.c
index 8776088..3a94afa 100644
--- a/git.c
+++ b/git.c
@@ -385,6 +385,13 @@ static int cmd_log(int argc, const char
return 0;
}
+static int cmd_whatchanged(int argc, const char **argv, char **envp)
+{
+ memmove(argv + 2, argv + 1, argc - 1);
+ argv[1] = "--cc";
+ return cmd_log(argc + 1, argv, envp);
+}
+
static void handle_internal_command(int argc, const char **argv, char **envp)
{
const char *cmd = argv[0];
@@ -395,6 +402,7 @@ static void handle_internal_command(int
{ "version", cmd_version },
{ "help", cmd_help },
{ "log", cmd_log },
+ { "whatchanged", cmd_whatchanged },
};
int i;
--
1.2.0.g61002-dirty
^ permalink raw reply related
* Re: [PATCH 5/19] kconfig: improve config load/save output
From: Roman Zippel @ 2006-04-09 22:01 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: linux-kernel, Andrew Morton
In-Reply-To: <20060409215637.GE30208@mars.ravnborg.org>
Hi,
On Sun, 9 Apr 2006, Sam Ravnborg wrote:
> > > sym_change_count is only used as a flag, not as a counter.
> >
> > It was intended as a counter, even it's currently only tested againsted
> > zero.
> That I figured out myself. But the intention should not be reflected
> years after when the intention did not hold.
There is not much point in changing it right now and it doesn't really
matter for this patch.
bye, Roman
^ permalink raw reply
* Re: NATed packets only enter the default routing table
From: Alexander Samad @ 2006-04-09 22:00 UTC (permalink / raw)
To: netfilter
In-Reply-To: <20060409203058.6e375d70.mailinglists@lucassen.org>
[-- Attachment #1: Type: text/plain, Size: 1833 bytes --]
On Sun, Apr 09, 2006 at 08:30:58PM +0200, richard lucassen wrote:
> On Sun, 9 Apr 2006 15:56:02 +0200
> Jeroen Elebaut <jeroen@elebaut.com> wrote:
>
> > i had a similar problem with our setup. The problem is i think that
> > the routing decision on the linux box is made before the address in
> > the packet is changed back to 1.2.3.3. So it doesn't use the source
> > policy routing entry. I solved this by using the connmark module from
> > iptables and then do routing based on the mark. The following should
> > work in your setup:
> >
> > iptables -t mangle -I PREROUTING -m conntrack --ctstate
> > ESTABLISHED,RELATED -j CONNMARK --restore-mark
> > iptables -t mangle -I PREROUTING -i eth1 -m conntrack --ctstate NEW
> > -j CONNMARK --set-mark 1
> >
> > ip rule add fwmark 1 lookup eth1_up
>
> I already found out this:
>
> iptables -t mangle -A PREROUTING -i eth1 -d 192.168.201.3 \
> -j CONNMARK --set-mark 1
>
> iptables -t mangle -A PREROUTING -i eth2 -s 10.0.2.1 \
> -j CONNMARK --restore-mark
>
> > This will route everything that entered via eth1 back via eth1.
>
> And indeed that was the solution. Thnx!
>
> R.
Are the kernel patches from here http://www.ssi.bg/~ja/ the ones that
fix this problem as well.
>
> --
> ___________________________________________________________________
> It is better to remain silent and be thought a fool, than to speak
> aloud and remove all doubt.
>
> +------------------------------------------------------------------+
> | Richard Lucassen, Utrecht |
> | Public key and email address: |
> | http://www.lucassen.org/mail-pubkey.html |
> +------------------------------------------------------------------+
>
>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 191 bytes --]
^ permalink raw reply
* Re: [Qemu-devel] Gentlemen we have absolute movement! was:Absolute USB-HID device musings (was Re: VNC Terminal Server)
From: Brad Campbell @ 2006-04-09 22:01 UTC (permalink / raw)
To: qemu-devel
In-Reply-To: <44397EFA.5070104@us.ibm.com>
Anthony Liguori wrote:
> + kbd_mouse_abs_event(dx * 0x7FFF / width,
> + dy * 0x7FFF / height,
I had just made that same mod to my tree.. solved the tracking problem perfectly.
Now if only it would work under win98 without modification..
Look what I just stumbled across.. irrelevant now I guess..
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/Hid_d/hh/HID_d/km-ovr_8d838937-f6b9-4245-8bb0-758bf162af7e.xml.asp
I wonder.. does windows switch over from ps2 to hid or just react to both and given hid is more
positive about where it wants the mouse to go it wins ?
I'm sure I've used a ps2 mouse and a usb mouse on windows before.. I'm thought they both worked at
the same time.
Like what you have with the rest of the patch.. I'll clean up my tree and go with that I think..
That should work quite well for sdl, gtk and vnc displays.. I guess cocoa also..
Now all we need is X support. I guess as a temporary measure the wacom patch works with linux..
Do you find having usb enabled makes the windows session feel a bit less responsive or jerkier ?
I know the mouse tracking is not as smooth with usb.. perhaps having ps2 and usb on together will
smooth that out a little.
--
"Human beings, who are almost unique in having the ability
to learn from the experience of others, are also remarkable
for their apparent disinclination to do so." -- Douglas Adams
^ permalink raw reply
* Re: [PATCH 5/19] kconfig: improve config load/save output
From: Sam Ravnborg @ 2006-04-09 21:56 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Andrew Morton
In-Reply-To: <Pine.LNX.4.64.0604092347460.32445@scrub.home>
On Sun, Apr 09, 2006 at 11:49:55PM +0200, Roman Zippel wrote:
> Hi,
>
> On Sun, 9 Apr 2006, Sam Ravnborg wrote:
>
> > > + name = *names++;
> > > + if (!name)
> > > + return 1;
> > > + in = zconf_fopen(name);
> > > + if (in)
> > > + goto load;
> > > + sym_change_count++;
> >
> > sym_change_count is only used as a flag, not as a counter.
>
> It was intended as a counter, even it's currently only tested againsted
> zero.
That I figured out myself. But the intention should not be reflected
years after when the intention did not hold.
Sam
^ permalink raw reply
* udp kernel socket problem
From: Bjoern Schmidt @ 2006-04-09 21:55 UTC (permalink / raw)
To: linux-kernel
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello,
i wrote a kernel driver which sends data as payload of an udp packet via
a udp kernel socket.
The problem is that _not_ every sock_sendmsg() call puts a packet onto
the wire. Instead the data from several sock_sendmsg() calls will be
merged in one big udp packet and then put on the wire. (Is THAT called
CORK?)
How can i force the kernel to put one udp packet per sock_sendmsg()
call (immediately ) onto the wire?
Please CC because i am not a subscriber of this list!
- --
greetings
Bjoern Schmidt
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (MingW32)
iD8DBQFEOYLiLR9iDVPSetsRAqgzAJ9GQSyO2l1venCyjwG4u653lpc6QwCgkBMS
lxnJjExKNg/8FT5DAGastcA=
=FgOJ
-----END PGP SIGNATURE-----
^ permalink raw reply
* Re: [PATCH 3/19] kconfig: recenter menuconfig
From: Sam Ravnborg @ 2006-04-09 21:55 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Andrew Morton
In-Reply-To: <Pine.LNX.4.64.0604092341130.32445@scrub.home>
On Sun, Apr 09, 2006 at 11:46:00PM +0200, Roman Zippel wrote:
> Hi,
>
> On Sun, 9 Apr 2006, Sam Ravnborg wrote:
>
> > With this change when window width is > 80 then we waste half of
> > the screen width only to right-indent the menus.
>
> Currently we waste a lot of screen on right side, which is not much
> different.
Thats normal behaviour vi does the same for this text.
> Further there is now a mix of left aligned and centered output,
> which is ugly
So we should fix the rest too instead of reintroducing the old
behaviour.
>
> > We truncate longer prompts and with this we require twice the
> > width to see full prompt.
>
> If these longer prompts don't fit into a 80 coloumn window, it's a bug.
Try to add three directories somewhere deep to "Initramfs source file(s)".
Thats where I have been hit by the limitation today.
Sam
^ permalink raw reply
* [U-Boot-Users] Linux-Hangs
From: Wolfgang Denk @ 2006-04-09 21:51 UTC (permalink / raw)
To: u-boot
In-Reply-To: <21c86c970604080543q791e61c7mdb67fdc2683662c4@mail.gmail.com>
In message <21c86c970604080543q791e61c7mdb67fdc2683662c4@mail.gmail.com> you wrote:
>
> I'm now trying with Non-XIP-Image. I am getting the Same.
Please provide logs.
I hope you changes the load address /entry point address as needed?
> 1) I have a small doubt in ATAG. While passing the command line argument
> through 'theKernel', where will be the control passed in the kernel. I mean
> which function.
HWat do you mean? In U-Boot? In Linux?
> 2) Is Control Register and ATAG both are same in Kernel? I couldn't find
> ATAG in kernel comments i found only the Control Register.
What's "Control Register"?
For Linux booting details please see the FAQ and documents on the
linuxarm web site.
> ------=_Part_16457_28377138.1144500191376
> Content-Type: text/html; charset=ISO-8859-1
> Content-Transfer-Encoding: quoted-printable
> Content-Disposition: inline
AND STOP POSTING HTML!!!!
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
If you're not part of the solution, you're part of the problem.
^ permalink raw reply
* Re: [PATCH 5/19] kconfig: improve config load/save output
From: Roman Zippel @ 2006-04-09 21:49 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: linux-kernel, Andrew Morton
In-Reply-To: <20060409213621.GC30208@mars.ravnborg.org>
Hi,
On Sun, 9 Apr 2006, Sam Ravnborg wrote:
> > + name = *names++;
> > + if (!name)
> > + return 1;
> > + in = zconf_fopen(name);
> > + if (in)
> > + goto load;
> > + sym_change_count++;
>
> sym_change_count is only used as a flag, not as a counter.
It was intended as a counter, even it's currently only tested againsted
zero.
bye, Roman
^ permalink raw reply
* Re: [PATCH 4/19] kconfig: fix typo in change count initialization
From: Roman Zippel @ 2006-04-09 21:47 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: linux-kernel, Andrew Morton
In-Reply-To: <20060409212704.GB30208@mars.ravnborg.org>
Hi,
On Sun, 9 Apr 2006, Sam Ravnborg wrote:
> > @@ -325,7 +325,7 @@ int conf_read(const char *name)
> > sym->flags |= e->right.sym->flags & SYMBOL_NEW;
> > }
> >
> > - sym_change_count = conf_warnings && conf_unsaved;
> > + sym_change_count = conf_warnings || conf_unsaved;
> >
> > return 0;
> > }
>
> Please explain what this actually fixes.
Configuration needs saving when either of these conditions is true.
bye, Roman
^ permalink raw reply
* Re: [PATCH 3/19] kconfig: recenter menuconfig
From: Roman Zippel @ 2006-04-09 21:46 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: linux-kernel, Andrew Morton
In-Reply-To: <20060409212548.GA30208@mars.ravnborg.org>
Hi,
On Sun, 9 Apr 2006, Sam Ravnborg wrote:
> With this change when window width is > 80 then we waste half of
> the screen width only to right-indent the menus.
Currently we waste a lot of screen on right side, which is not much
different. Further there is now a mix of left aligned and centered output,
which is ugly, so this patch only restores the old behaviour (without the
jumping around for small text changes).
> We truncate longer prompts and with this we require twice the
> width to see full prompt.
If these longer prompts don't fit into a 80 coloumn window, it's a bug.
bye, Roman
^ permalink raw reply
* Re: [Qemu-devel] Gentlemen we have absolute movement! was:Absolute USB-HID device musings (was Re: VNC Terminal Server)
From: Anthony Liguori @ 2006-04-09 21:39 UTC (permalink / raw)
To: qemu-devel
In-Reply-To: <44397848.1070707@wasp.net.au>
[-- Attachment #1: Type: text/plain, Size: 2742 bytes --]
Brad Campbell wrote:
> Anthony Liguori wrote:
>> Hi Brad,
>>
>> I have your patch applied and the previous one and it doesn't seem to
>> work under win2k. Can you post a patch of what you have?
>>
>> I've got what I have attached. I did a little bit of SDL plumbing
>> based on my touchscreen patch.
>>
>
> Ok.. now I've embarrassed myself by publicly releasing my spaghetti,
> I've had a look at what you are up to..
> The VNC patch extends the existing mouse handler by passing it abs
> coordinates as well, (this is the basis of what I used) so there are
> no additional routines.. I figure if you pass both relative (faked if
> need be) and abs to the routine then the mouse can use whatever it likes.
I don't really like that myself.
>
> It looks like you are adding a completely separate handler there ?
Yeah, I figure if a device is interested only in relative movements
(like the PS/2 mouse), that's all it should get.
> I had to stop the ps2 mouse handler registering itself to let the usb
> one have a go. But now its working. I've left both cursors live so you
> can see how well it mates up. There is a minor elastic discrepancy
> toward the bottom right of the screen, but I'm *sure* its just due to
> my off the top of my head hacky position calculations and it can be
> refined further..
Everything seems to work fine for me. Both mice get their own
coordinates and the guest choices which one it wants. In Windows, once
you log in the first time, it detects the mouse and switches over to the
USB mouse.
I've added the necessary stuff to SDL so that the switch over occurs
gracefully. Once the USB mouse starts being used, SDL no longer
triggers grab on left click (but still on ctrl-alt) and always reports
mouse movements. I also got rid of the ShowCursor() calls as that warps
the host mouse.
> I figure a command line switch for usbmouse/usbabs/ps2 might be in
> order so you can change depending on your os. Hopefully the evdev
> patch in X gets up and running and we can just default to abs mode.
I'm not sure a command line switch is needed. I think we can have it
automatically do the right thing. Attached is my latest patch. I did
some awful things to SDL that I'd like to clean up. The only real
"feature" I'd like to add is automatic breaking of grap when the USB
mouse is detected.
>
> I'll get hold of a wheel mouse tomorrow (my trackpad does not have a
> Z) and see if I can get the Z axis going..
>
> Tested under win2k-SP4. How cool is it to be grabless and change
> resolutions on the fly..
> I'll clean it up tomorrow and graft it into the vnc patch also..
> virtual servers here we come!
Seriously, awesome job here :-)
Regards,
Anthony Liguori
>
> Brad
[-- Attachment #2: qemu-abs-hid.diff --]
[-- Type: text/plain, Size: 10219 bytes --]
diff -r 8937c657c23f hw/usb-hid.c
--- a/hw/usb-hid.c Sun Mar 26 01:31:22 2006 +0000
+++ b/hw/usb-hid.c Sun Apr 9 16:29:35 2006 -0500
@@ -33,6 +33,7 @@
typedef struct USBMouseState {
USBDevice dev;
int dx, dy, dz, buttons_state;
+ int X, Y;
} USBMouseState;
/* mostly the same values as the Bochs USB Mouse device */
@@ -92,14 +93,6 @@
0x01, /* u8 if_bInterfaceSubClass; */
0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */
0x05, /* u8 if_iInterface; */
-
- /* one endpoint (status change endpoint) */
- 0x07, /* u8 ep_bLength; */
- 0x05, /* u8 ep_bDescriptorType; Endpoint */
- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* u8 ep_bmAttributes; Interrupt */
- 0x03, 0x00, /* u16 ep_wMaxPacketSize; */
- 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
/* HID descriptor */
0x09, /* u8 bLength; */
@@ -108,9 +101,18 @@
0x00, /* u8 country_code */
0x01, /* u8 num_descriptors */
0x22, /* u8 type; Report */
- 50, 0, /* u16 len */
+ 53, 0, /* u16 len */
+
+ /* one endpoint (status change endpoint) */
+ 0x07, /* u8 ep_bLength; */
+ 0x05, /* u8 ep_bDescriptorType; Endpoint */
+ 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */
+ 0x03, /* u8 ep_bmAttributes; Interrupt */
+ 0x08, 0x00, /* u16 ep_wMaxPacketSize; */
+ 0x03, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */
};
+#if 0
static const uint8_t qemu_mouse_hid_report_descriptor[] = {
0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01,
0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
@@ -120,6 +122,41 @@
0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06,
0xC0, 0xC0,
};
+#else
+static const uint8_t qemu_mouse_hid_report_descriptor[] = {
+ 0x05, 0x01, /* Usage Page Generic Desktop */
+ 0x09, 0x01, /* Usage Mouse */
+ 0xA1, 0x01, /* Collection Application */
+ 0x09, 0x01, /* Usage Pointer */
+ 0xA1, 0x00, /* Collection Physical */
+ 0x05, 0x09, /* Usage Page Button */
+ 0x19, 0x01, /* Usage Minimum Button 1 */
+ 0x29, 0x03, /* Usage Maximum Button 3 */
+ 0x15, 0x00, /* Logical Minimum 0 */
+ 0x25, 0x01, /* Logical Maximum 1 */
+ 0x95, 0x03, /* Report Count 3 */
+ 0x75, 0x01, /* Report Size 1 */
+ 0x81, 0x02, /* Input (Data, Var, Abs) */
+ 0x95, 0x01, /* Report Count 1 */
+ 0x75, 0x05, /* Report Size 5 */
+ 0x81, 0x01, /* Input (Cnst, Var, Abs) */
+ 0x05, 0x01, /* Usage Page Generic Desktop */
+ 0x09, 0x30, /* Usage X */
+ 0x09, 0x31, /* Usage Y */
+ 0x15, 0x00, /* Logical Minimum 0 */
+ 0x27, 0xFF, 0xFF, 0x00, 0x00, /* Logical Maximum 0xffff */
+ 0x75, 0x10, /* Report Size 32 */
+ 0x95, 0x02, /* Report Count 2 */
+ 0x81, 0x02, /* Input (Data, Var, Abs) */
+// 0x09, 0x32, /* Usage Z */
+// 0x15, 0x81, /* Logical Minimum -127 */
+// 0x25, 0x7F, /* Logical Maximum 127 */
+// 0x75, 0x08, /* Report Size 8 */
+// 0x95, 0x01, /* Report Count 1 */
+ 0xC0, /* End Collection */
+ 0xC0, /* End Collection */
+};
+#endif
static void usb_mouse_event(void *opaque,
int dx1, int dy1, int dz1, int buttons_state)
@@ -129,6 +166,8 @@
s->dx += dx1;
s->dy += dy1;
s->dz += dz1;
+ s->X = dx1;
+ s->Y = dy1;
s->buttons_state = buttons_state;
}
@@ -142,6 +181,7 @@
return val;
}
+#if 0
static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len)
{
int dx, dy, dz, b, l;
@@ -172,6 +212,40 @@
}
return l;
}
+#else
+
+static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len)
+{
+ int dx, dy, dz, b, l;
+
+ /* FIXME this is ugly */
+ absolute_mouse = 1;
+
+ dx = int_clamp(s->dx, -128, 127);
+ dy = int_clamp(s->dy, -128, 127);
+ dz = int_clamp(s->dz, -128, 127);
+
+ s->dx -= dx;
+ s->dy -= dy;
+ s->dz -= dz;
+ b = 0;
+ if (s->buttons_state & MOUSE_EVENT_LBUTTON)
+ b |= 0x01;
+ if (s->buttons_state & MOUSE_EVENT_RBUTTON)
+ b |= 0x02;
+ if (s->buttons_state & MOUSE_EVENT_MBUTTON)
+ b |= 0x04;
+
+ buf[0] = b;
+ buf[1] = s->X & 0xff;
+ buf[2] = s->X >> 8;
+ buf[3] = s->Y & 0xff;
+ buf[4] = s->Y >> 8;
+ l = 5;
+
+ return l;
+}
+#endif
static void usb_mouse_handle_reset(USBDevice *dev)
{
@@ -180,6 +254,8 @@
s->dx = 0;
s->dy = 0;
s->dz = 0;
+ s->X = 0;
+ s->Y = 0;
s->buttons_state = 0;
}
@@ -341,7 +417,8 @@
s->dev.handle_control = usb_mouse_handle_control;
s->dev.handle_data = usb_mouse_handle_data;
- qemu_add_mouse_event_handler(usb_mouse_event, s);
+ qemu_add_mouse_event_handler(NULL, NULL);
+ qemu_add_mouse_abs_event_handler(usb_mouse_event, s);
return (USBDevice *)s;
}
diff -r 8937c657c23f sdl.c
--- a/sdl.c Sun Mar 26 01:31:22 2006 +0000
+++ b/sdl.c Sun Apr 9 16:29:35 2006 -0500
@@ -39,6 +39,10 @@
static int gui_fullscreen_initial_grab;
static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
static uint8_t modifiers_state[256];
+static int width, height;
+static SDL_Cursor *sdl_cursor_normal;
+static SDL_Cursor *sdl_cursor_hidden;
+static int cursor_hidden = 0;
static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
{
@@ -55,6 +59,9 @@
flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
if (gui_fullscreen)
flags |= SDL_FULLSCREEN;
+
+ width = w;
+ height = h;
again:
screen = SDL_SetVideoMode(w, h, 0, flags);
@@ -273,7 +280,9 @@
static void sdl_grab_start(void)
{
- SDL_ShowCursor(0);
+ sdl_cursor_normal = SDL_GetCursor();
+ SDL_SetCursor(sdl_cursor_hidden);
+ cursor_hidden = 1;
SDL_WM_GrabInput(SDL_GRAB_ON);
/* dummy read to avoid moving the mouse */
SDL_GetRelativeMouseState(NULL, NULL);
@@ -284,7 +293,10 @@
static void sdl_grab_end(void)
{
SDL_WM_GrabInput(SDL_GRAB_OFF);
- SDL_ShowCursor(1);
+ if (!absolute_mouse) {
+ SDL_SetCursor(sdl_cursor_normal);
+ cursor_hidden = 1;
+ }
gui_grab = 0;
sdl_update_caption();
}
@@ -301,6 +313,17 @@
if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
buttons |= MOUSE_EVENT_MBUTTON;
kbd_mouse_event(dx, dy, dz, buttons);
+
+ SDL_GetMouseState(&dx, &dy);
+ kbd_mouse_abs_event(dx * 0x7FFF / width,
+ dy * 0x7FFF / height,
+ dz, buttons);
+ if (absolute_mouse && !cursor_hidden) {
+ sdl_cursor_normal = SDL_GetCursor();
+ SDL_SetCursor(sdl_cursor_hidden);
+ cursor_hidden = 1;
+ }
+
}
static void toggle_full_screen(DisplayState *ds)
@@ -427,7 +450,7 @@
qemu_system_shutdown_request();
break;
case SDL_MOUSEMOTION:
- if (gui_grab) {
+ if (gui_grab || absolute_mouse) {
sdl_send_mouse_event(0);
}
break;
@@ -435,7 +458,7 @@
case SDL_MOUSEBUTTONUP:
{
SDL_MouseButtonEvent *bev = &ev->button;
- if (!gui_grab) {
+ if (!gui_grab && !absolute_mouse) {
if (ev->type == SDL_MOUSEBUTTONDOWN &&
(bev->state & SDL_BUTTON_LMASK)) {
/* start grabbing all events */
@@ -475,6 +498,7 @@
void sdl_display_init(DisplayState *ds, int full_screen)
{
int flags;
+ uint8_t data = 0;
#if defined(__APPLE__)
/* always use generic keymaps */
@@ -508,6 +532,8 @@
SDL_EnableUNICODE(1);
gui_grab = 0;
+ sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
+
atexit(sdl_cleanup);
if (full_screen) {
gui_fullscreen = 1;
diff -r 8937c657c23f vl.c
--- a/vl.c Sun Mar 26 01:31:22 2006 +0000
+++ b/vl.c Sun Apr 9 16:29:35 2006 -0500
@@ -148,6 +148,7 @@
USBDevice *vm_usb_hub;
static VLANState *first_vlan;
int smp_cpus = 1;
+int absolute_mouse = 0;
#if defined(TARGET_SPARC)
#define MAX_CPUS 16
#elif defined(TARGET_I386)
@@ -475,6 +476,8 @@
static void *qemu_put_kbd_event_opaque;
static QEMUPutMouseEvent *qemu_put_mouse_event;
static void *qemu_put_mouse_event_opaque;
+static QEMUPutMouseAbsEvent *qemu_put_mouse_abs_event;
+static void *qemu_put_mouse_abs_event_opaque;
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
{
@@ -486,6 +489,12 @@
{
qemu_put_mouse_event_opaque = opaque;
qemu_put_mouse_event = func;
+}
+
+void qemu_add_mouse_abs_event_handler(QEMUPutMouseAbsEvent *func, void *opaque)
+{
+ qemu_put_mouse_abs_event_opaque = opaque;
+ qemu_put_mouse_abs_event = func;
}
void kbd_put_keycode(int keycode)
@@ -500,6 +509,14 @@
if (qemu_put_mouse_event) {
qemu_put_mouse_event(qemu_put_mouse_event_opaque,
dx, dy, dz, buttons_state);
+ }
+}
+
+void kbd_mouse_abs_event(int x, int y, int dz, int buttons_state)
+{
+ if (qemu_put_mouse_abs_event) {
+ qemu_put_mouse_abs_event(qemu_put_mouse_abs_event_opaque,
+ x, y, dz, buttons_state);
}
}
diff -r 8937c657c23f vl.h
--- a/vl.h Sun Mar 26 01:31:22 2006 +0000
+++ b/vl.h Sun Apr 9 16:29:35 2006 -0500
@@ -138,6 +138,7 @@
extern int win2k_install_hack;
extern int usb_enabled;
extern int smp_cpus;
+extern int absolute_mouse;
/* XXX: make it dynamic */
#if defined (TARGET_PPC)
@@ -156,12 +157,15 @@
typedef void QEMUPutKBDEvent(void *opaque, int keycode);
typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
+typedef void QEMUPutMouseAbsEvent(void *opaque, int x, int y, int dz, int buttons_state);
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque);
+void qemu_add_mouse_abs_event_handler(QEMUPutMouseAbsEvent *func, void *opaque);
void kbd_put_keycode(int keycode);
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
+void kbd_mouse_abs_event(int x, int y, int dz, int buttons_state);
/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
constants) */
^ permalink raw reply
* Re: [PATCH 5/19] kconfig: improve config load/save output
From: Sam Ravnborg @ 2006-04-09 21:36 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Andrew Morton
In-Reply-To: <Pine.LNX.4.64.0604091727330.23124@scrub.home>
On Sun, Apr 09, 2006 at 05:27:41PM +0200, Roman Zippel wrote:
>
> During loading special case the first common case (.config), be silent
> about it and otherwise mark it as a change that requires saving. Instead
> output that the file has been changed.
> IOW if conf does nothing (special), it's silent.
>
> Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
>
> ---
>
> scripts/kconfig/confdata.c | 22 ++++++++++++++++++----
> 1 file changed, 18 insertions(+), 4 deletions(-)
>
> Index: linux-2.6-git/scripts/kconfig/confdata.c
> ===================================================================
> --- linux-2.6-git.orig/scripts/kconfig/confdata.c
> +++ linux-2.6-git/scripts/kconfig/confdata.c
> @@ -98,20 +98,28 @@ int conf_read_simple(const char *name)
> in = zconf_fopen(name);
> } else {
> const char **names = conf_confnames;
> + name = *names++;
> + if (!name)
> + return 1;
> + in = zconf_fopen(name);
> + if (in)
> + goto load;
> + sym_change_count++;
sym_change_count is only used as a flag, not as a counter.
It would be less confusing to let the name reflect it is a flag.
@@ -325,7 +335,7 @@ int conf_read(const char *name)
> sym->flags |= e->right.sym->flags & SYMBOL_NEW;
> }
>
> - sym_change_count = conf_warnings || conf_unsaved;
> + sym_change_count += conf_warnings || conf_unsaved;
One example where is obvious it is a flag.
Sam
^ permalink raw reply
* Re: [Qemu-devel] Gentlemen we have absolute movement! was:Absolute USB-HID device musings (was Re: VNC Terminal Server)
From: Brad Campbell @ 2006-04-09 21:35 UTC (permalink / raw)
To: qemu-devel
In-Reply-To: <Pine.LNX.4.63.0604092317480.29255@wbgn013.biozentrum.uni-wuerzburg.de>
Johannes Schindelin wrote:
> Hi,
>
> On Mon, 10 Apr 2006, Brad Campbell wrote:
>
>> The VNC patch extends the existing mouse handler by passing it abs
>> coordinates as well, (this is the basis of what I used) so there are no
>> additional routines.. I figure if you pass both relative (faked if need
>> be) and abs to the routine then the mouse can use whatever it likes.
>
> That was a kludge. I always meant to do some cleanup there as soon as I
> got Summagraphics to work with win98 (which has not yet happened :-( ).
Ok, well I'll look at the work that Anthony has put in already and see what we come up with.
Speaking of Win98. I just tried this under win98, and after it installed its usb kit and the HID
driver it kinda works.. looks like win98 expects 0x0-0xffff while 2k expects 0x0-0x7fff for the
position information.. buttons are ok and tracking is good, just the target pointer only moves half
the distance.
A problem perhaps, but one that could be worked around in a pinch..
--
"Human beings, who are almost unique in having the ability
to learn from the experience of others, are also remarkable
for their apparent disinclination to do so." -- Douglas Adams
^ permalink raw reply
* Re: [ANNOUNCE] git-svnconvert: YASI (Yet Another SVN importer)
From: Johannes Schindelin @ 2006-04-09 21:30 UTC (permalink / raw)
To: git; +Cc: Jakub Narebski, git
In-Reply-To: <20060409211505.GA30567@nospam.com>
Hi,
On Sun, 9 Apr 2006, Rutger Nijlunsing wrote:
> On Sun, Apr 09, 2006 at 06:43:53PM +0200, Jakub Narebski wrote:
> >
> > Instead adding dependence on Ruby, eh?
>
> Take some, lose some ;)
>
> Seriously, though, a dependancy on a mainstream language like
> Python/Perl/Ruby/.. isn't a problem since a package is available for
> all distributions. However, packages for mainstream languages are
> quite often out-of-date or are not supported at all. Seeing a program
> being dependant on a non-packaged module is enough for a truckload of
> people to not even try it.
I have _never_ seen a setup where Ruby was installed by default. Perl
always, Python often.
Furthermore, my feeling is that we are in the beginning phase of migration
from scripting languages (which are good for prototyping) towards plain C.
So adding yet another scripting language dependency is a little backwards.
Ciao,
Dscho
^ permalink raw reply
* [ALSA - driver 0001732]: Support for Intel D945Pvs Board
From: bugtrack @ 2006-04-09 21:30 UTC (permalink / raw)
To: alsa-devel
A NOTE has been added to this issue.
======================================================================
<https://bugtrack.alsa-project.org/alsa-bug/view.php?id=1732>
======================================================================
Reported By: timtt
Assigned To: tiwai
======================================================================
Project: ALSA - driver
Issue ID: 1732
Category: PCI - hda-intel
Reproducibility: always
Severity: feature
Priority: normal
Status: assigned
Distribution: FC4
Kernel Version: 2.6.14-1656
======================================================================
Date Submitted: 01-11-2006 04:53 CET
Last Modified: 04-09-2006 23:30 CEST
======================================================================
Summary: Support for Intel D945Pvs Board
Description:
Alsa is only able to output regular 2-channel audio via the headphone jack
at the back of this motherboard. This motherboard has an SPDIF connection
available that is currently not supported, but should be.
======================================================================
----------------------------------------------------------------------
aclark - 04-09-06 23:19
----------------------------------------------------------------------
This patch adds the 5-stack pin-config for the STAC chip on the Intel
D945Pvs board with subdevice id 0x0707.
With this patch against 1.0.11rc4, I'm able to successfully output over
the optical port and analog ports.
----------------------------------------------------------------------
rlrevell - 04-09-06 23:30
----------------------------------------------------------------------
Can you please send the patch to alsa-devel at lists.sourceforge.net
mailing list (you do not have to subscribe), and include a Signed-Off-By
line?
Issue History
Date Modified Username Field Change
======================================================================
01-11-06 04:53 timtt New Issue
01-11-06 04:53 timtt Distribution => FC4
01-11-06 04:53 timtt Kernel Version => 2.6.14-1656
01-11-06 05:04 rlrevell Note Added: 0007558
01-11-06 18:30 timtt Note Added: 0007563
01-11-06 18:36 rlrevell Note Added: 0007564
01-20-06 22:47 timtt Note Added: 0007728
04-09-06 23:19 aclark Note Added: 0009187
04-09-06 23:19 aclark File Added: sigmatel.diff
04-09-06 23:19 aclark Issue Monitored: aclark
04-09-06 23:30 rlrevell Note Added: 0009188
======================================================================
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply
* Re: [Adeos-main] Re: [Xenomai-core] kgdb over ipipe
From: Philippe Gerum @ 2006-04-09 21:29 UTC (permalink / raw)
To: Jan Kiszka; +Cc: adeos-main, xenomai-core
In-Reply-To: <4438FAFA.3020105@domain.hid>
Jan Kiszka wrote:
> Jan Kiszka wrote:
>
>>Hi,
>>
>>this is the preliminary, though already usable result of my recent
>>effort to extend the tool situation for Xenomai: A kgdb patch series for
>>2.6.15 on x86. It already works quite well but likely does not yet catch
>>all fatal scenarios (e.g. page faults in the Xenomai domain).
>>
>
>
> And here comes another revision (prepare patch remains unmodified).
>
> It gets closer to what Philippe also just suggested in the original
> thread: hook KGDB into I-pipe in favour of registering a dedicated
> domain. The latter approach modifies the I-pipe state in a way which may
> blur the picture of I-pipe itself to the debugger. This revision hooks
> exception events into the I-pipe core so that they are delivered the
> normal way when the root domain is active, but get catched early for
> higher domains like Xenomai. I'm just not sure about the best way to
> handle the serial line IRQ. Philippe, do you see problems with current
> approach? Should we better hook into __ipipe_handle_irq (which would
> make things more complicated, I'm afraid)?
>
The current approach works fine unless a runaway thread goes wild with
interrupts disabled (i.e. stall bit set) in the root stage or in any
higher priority domain regardless of the root domain state, in which
case the serial IRQ won't make it through the pipeline to KGDB.
> In contrast to the first version, exceptions happening in the Xenomai
> domain now also get reported to KGDB. Debugging mostly works fine, I'm
> just facing unknown problems with intercepting and then continuing
> kernel-only RT threads. KGDB sometimes reports "E22" back in this case,
> but always locks up. Maybe it gets confused by the fact the there is no
> Linux task behind Xenomai kernel threads? I tested this by putting a
> breakpoint into xnpod_suspend_thread and running latency in mode 0 and
> 1. 0 works fine, 1 not.
>
KGDB is relying on "current", so it's reading garbage over Xenomai's
kernel threads.
--
Philippe.
^ permalink raw reply
* Re: [PATCH 4/19] kconfig: fix typo in change count initialization
From: Sam Ravnborg @ 2006-04-09 21:27 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Andrew Morton
In-Reply-To: <Pine.LNX.4.64.0604091727190.23120@scrub.home>
On Sun, Apr 09, 2006 at 05:27:28PM +0200, Roman Zippel wrote:
>
> Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
>
> ---
>
> scripts/kconfig/confdata.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> Index: linux-2.6-git/scripts/kconfig/confdata.c
> ===================================================================
> --- linux-2.6-git.orig/scripts/kconfig/confdata.c
> +++ linux-2.6-git/scripts/kconfig/confdata.c
> @@ -325,7 +325,7 @@ int conf_read(const char *name)
> sym->flags |= e->right.sym->flags & SYMBOL_NEW;
> }
>
> - sym_change_count = conf_warnings && conf_unsaved;
> + sym_change_count = conf_warnings || conf_unsaved;
>
> return 0;
> }
Please explain what this actually fixes.
I recall we have touched this area before but I do not recall the
details.
Sam
^ permalink raw reply
* Re: [PATCH 3/19] kconfig: recenter menuconfig
From: Sam Ravnborg @ 2006-04-09 21:25 UTC (permalink / raw)
To: Roman Zippel; +Cc: linux-kernel, Andrew Morton
In-Reply-To: <Pine.LNX.4.64.0604091726550.23116@scrub.home>
On Sun, Apr 09, 2006 at 05:27:14PM +0200, Roman Zippel wrote:
>
> Move the menuconfig output more into the centre again, it's using a
> fixed position depending on the window width using the fact that the
> menu output has to work in a 80 chars terminal.
>
> Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
NACK.
With this change when window width is > 80 then we waste half of
the screen width only to right-indent the menus.
We truncate longer prompts and with this we require twice the
width to see full prompt.
One could argue that the old ITEM_IDENT should be 0 instead of 1,
avoiding wasting an extra char. But with this change we waste
a lot of space.
Sam
^ permalink raw reply
* Re: 2.6.17-rc1-mm2: badness in 3w_xxxx driver
From: Nick Orlov @ 2006-04-09 21:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel
In-Reply-To: <20060409124301.44a9567c.akpm@osdl.org>
On Sun, Apr 09, 2006 at 12:43:01PM -0700, Andrew Morton wrote:
> Nick Orlov <bugfixer@list.ru> wrote:
> >
> > Confirmed, this patch solves the "badness" problem for me.
>
> yup, thanks.
>
> > I still experiencing a weird hangs though (the box just hangs, no
> > messages on console/syslog, nothing). I'll try to nail it down.
> >
> > 2.6.16-mm2 works like a charm with the same config.
> > Do you know which patches should I try to revert first?
>
> Gee, 2.6.16-mm2 was a long time ago.
>
> Tried sysrq?
>
> echo 1 > /proc/sys/kernel/sysrq
> <wait for hang>
> ALT-SYSRQ-P or ALT-SYSRQ-T
>
> Is the NMi watchdog enabled? Boot with `nmi_watchdog=1', make sure that
> the NMI counts are incrementing in /proc/interrupts.
>
> Failing all that, testing 2.6.17-rc1 would be interesting.
2.6.17-rc1 fails in the same fashion - it hangs "randomly".
Good news that I've found the pattern and solution:
it always happens when 2 applications open /dev/dsp simultaneously.
Applying the following patches published by Takashi Iwai solves the
problem:
http://marc.theaimsgroup.com/?l=linux-kernel&m=114423578508165&w=2
http://marc.theaimsgroup.com/?l=linux-kernel&m=114424198614019&w=2
Not sure if the first one is enough.
I would probably recommend to put them into the hot-fixes,
since many people can be frustrated because of this.
--
With best wishes,
Nick Orlov.
^ permalink raw reply
* Re: [Qemu-devel] Gentlemen we have absolute movement! was:Absolute USB-HID device musings (was Re: VNC Terminal Server)
From: Johannes Schindelin @ 2006-04-09 21:20 UTC (permalink / raw)
To: qemu-devel
In-Reply-To: <44397848.1070707@wasp.net.au>
Hi,
On Mon, 10 Apr 2006, Brad Campbell wrote:
> The VNC patch extends the existing mouse handler by passing it abs
> coordinates as well, (this is the basis of what I used) so there are no
> additional routines.. I figure if you pass both relative (faked if need
> be) and abs to the routine then the mouse can use whatever it likes.
That was a kludge. I always meant to do some cleanup there as soon as I
got Summagraphics to work with win98 (which has not yet happened :-( ).
I'd rather have two calls, one for absolute and one for relative, where
relative checks if the current active mouse is relative or absolute, and
in the latter case just calls absolute and vice versa.
Ciao,
Dscho
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.