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;
}
Esempio n. 2
0
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();
}