Re: [PATCH RFC V2 3/5] jump_label: if a key has already been initialized, don't nop it out

Jeremy Fitzhardinge
2011-10-06T17:53:36Z

[-- Attachment #1: Type: text/plain, Size: 902 bytes --]

On 10/05/2011 05:17 PM, H. Peter Anvin wrote:
> On 10/05/2011 05:16 PM, Jeremy Fitzhardinge wrote:
>> On 10/04/2011 09:30 AM, H. Peter Anvin wrote:
>>> On 10/04/2011 07:10 AM, Jason Baron wrote:
>>>> 1) The jmp +0, is a 'safe' no-op that I know is going to initially
>>>> boot for all x86. I'm not sure if there is a 5-byte nop that works on
>>>> all x86 variants - but by using jmp +0, we make it much easier to debug
>>>> cases where we may be using broken no-ops.
>>>>
>>> There are *plenty*. jmp+0 is about as pessimal as you can get.
>> As an aside, do you know if a 2-byte unconditional jmp is any more
>> efficient than 5-byte, aside from just being a smaller instruction and
>> taking less icache?
>>
> I don't know for sure, no. I probably depends on the CPU.

Looks like jmp2 is about 5% faster than jmp5 on Sandybridge with this
benchmark.

But insignificant difference on Nehalem.

J

[-- Attachment #2: jmp2.c --]
[-- Type: text/x-csrc, Size: 550 bytes --]

#include <stdio.h>

struct {
unsigned char flag;
unsigned char val;
} l;

#define JMP2 asm volatile ("jmp 1f; .byte 0x0f,0x1f,0x00; 1: ");
#define JMPJMP2 JMP2 JMP2
#define JMPJMPJMP2 JMPJMP2 JMPJMP2
#define JMPJMPJMP2 JMPJMP2 JMPJMP2
#define JMPJMPJMPJMP2 JMPJMPJMP2 JMPJMPJMP2
#define JMPJMPJMPJMPJMP2 JMPJMPJMPJMP2 JMPJMPJMPJMP2
#define JMPJMPJMPJMPJMPJMP2 JMPJMPJMPJMPJMP2 JMPJMPJMPJMPJMP2

int main(int argc, char **argv)
{
int i;

for (i = 0; i < 100000000; i++) {
JMPJMPJMPJMPJMPJMP2;
asm volatile("" : : : "memory");
}

return 0;
}

[-- Attachment #3: jmp5.c --]
[-- Type: text/x-csrc, Size: 536 bytes --]

#include <stdio.h>

struct {
unsigned char flag;
unsigned char val;
} l;

#define JMP5 asm volatile (".byte 0xe9; .long 0");
#define JMPJMP5 JMP5 JMP5
#define JMPJMPJMP5 JMPJMP5 JMPJMP5
#define JMPJMPJMP5 JMPJMP5 JMPJMP5
#define JMPJMPJMPJMP5 JMPJMPJMP5 JMPJMPJMP5
#define JMPJMPJMPJMPJMP5 JMPJMPJMPJMP5 JMPJMPJMPJMP5
#define JMPJMPJMPJMPJMPJMP5 JMPJMPJMPJMPJMP5 JMPJMPJMPJMPJMP5

int main(int argc, char **argv)
{
int i;

for (i = 0; i < 100000000; i++) {
JMPJMPJMPJMPJMPJMP5;
asm volatile("" : : : "memory");
}

return 0;
}