static inline SshInterceptorInternalPacket ssh_freelist_packet_get(SshInterceptor interceptor, Boolean may_borrow) { SshInterceptorInternalPacket p; unsigned int cpu; icept_preempt_disable(); cpu = smp_processor_id(); p = ssh_packet_freelist_head[cpu]; if (p) { p->cpu = cpu; ssh_packet_freelist_head[p->cpu] = (SshInterceptorInternalPacket) p->packet.next; } else { /* Try getting a packet from the shared freelist */ ssh_kernel_mutex_lock(interceptor->packet_lock); p = ssh_packet_freelist_head[SSH_LINUX_INTERCEPTOR_NR_CPUS]; if (p) { p->cpu = cpu; ssh_packet_freelist_head[SSH_LINUX_INTERCEPTOR_NR_CPUS] = (SshInterceptorInternalPacket) p->packet.next; ssh_kernel_mutex_unlock(interceptor->packet_lock); goto done; } ssh_kernel_mutex_unlock(interceptor->packet_lock); p = ssh_malloc(sizeof(*p)); if (!p) goto done; p->cpu = cpu; } done: icept_preempt_enable(); return p; }
static inline void ssh_freelist_packet_put(SshInterceptor interceptor, SshInterceptorInternalPacket p) { unsigned int cpu; icept_preempt_disable(); cpu = p->cpu; SSH_ASSERT(cpu < SSH_LINUX_INTERCEPTOR_NR_CPUS); #ifdef DEBUG_LIGHT memset(p, 'F', sizeof(*p)); #endif /* DEBUG_LIGHT */ if (likely(cpu == smp_processor_id())) { p->packet.next = (SshInterceptorPacket) ssh_packet_freelist_head[cpu]; ssh_packet_freelist_head[cpu] = p; } else { cpu = SSH_LINUX_INTERCEPTOR_NR_CPUS; /* The executing CPU is not the same as when the packet was allocated. Put the packet back to the shared freelist */ ssh_kernel_mutex_lock(interceptor->packet_lock); p->packet.next = (SshInterceptorPacket) ssh_packet_freelist_head[cpu]; ssh_packet_freelist_head[cpu] = p; ssh_kernel_mutex_unlock(interceptor->packet_lock); } icept_preempt_enable(); }