spu_create(2)

✨ spu_create β€” create a new spu context ✨

okay bestie, gather round πŸ’– this is spu_create from section 2 of the manual (the System Calls Manual, the real ones), and yes it's a whole vibe. It's giving "I only run on very specific PowerPC hardware" energy and honestly? iconic. Let's get into it 🫢


🌸 NAME 🌸

spu_create β€” create a new spu context


πŸŽ€ LIBRARY πŸŽ€

Standard C library (libc, -lc)


✨ SYNOPSIS ✨

#include <sys/spu.h>          /* Definition of SPU_* constants */
#include <sys/syscall.h>      /* Definition of SYS_* constants */
#include <unistd.h>

int syscall(SYS_spu_create, const char *path, unsigned int flags,
            mode_t mode, int neighbor_fd);
🚨 not me β€” glibc does not give you a wrapper for spu_create(), so you literally have to go through syscall(2). no convenience function, no cute little spu_create() you can just call. rude but okay πŸ’…

πŸ’– DESCRIPTION πŸ’–

So, spu_create() is a system call that lives on PowerPC machines implementing the Cell Broadband Engine Architecture, and it's how you get at Synergistic Processor Units (SPUs) β€” the main character hardware of this whole situation πŸ‘‘

It creates a fresh logical context for an SPU at path and hands you back a file descriptor linked to it. Important: path must point to a directory that doesn't exist yet, inside the mount point of the SPU filesystem (spufs). If spu_create() works, a directory gets created at path and it's filled with all the files described over in spufs(7).

Once the context exists, the file descriptor you got back is on a strict little leash β€” you can only:

  • pass it to spu_run(2),
  • use it as the dirfd argument to the *at family of system calls (like openat(2)), or
  • close it.

Anything else? not defined. no cap πŸ™ˆ

A logical SPU context gets destroyed (along with every file created inside the context's path directory) as soon as the last reference to it is gone β€” which usually happens when you close that file descriptor from spu_create().

The mode argument (minus whatever bits are set in the process's umask(2)) says what permissions to use when creating that new directory in spufs. Full list of possible mode values lives in stat(2), go peek.

neighbor_fd only does anything when the SPU_CREATE_AFFINITY_SPU flag is set β€” details below ⬇️

The flags argument can be zero, or any bitwise OR-ed combo of these constants:

🌈 the flags 🌈

  • SPU_CREATE_EVENTS_ENABLED β€” instead of using signals to report DMA errors, use the event argument to spu_run(2). switching up the notification system, we love options πŸ’…
  • SPU_CREATE_GANG β€” create an SPU gang instead of a context. (a gang is a group of SPU contexts that are functionally related to each other and share common scheduling parameters β€” priority and policy. In the future, gang scheduling may get implemented, which would cause the group to be switched in and out as a single unit.)

A new directory gets created at the location you gave in path. You can then use this gang to hold other SPU contexts by handing a pathname that's inside the gang directory to further calls of spu_create(). it's a whole friend group 🫢

  • SPU_CREATE_NOSCHED β€” create a context that the SPU scheduler straight-up cannot touch. Once it's running, it will not be scheduled out until the creating process destroys it. main character refuses to be interrupted πŸ‘‘

Because the context can't be removed from the SPU, some functionality is disabled for SPU_CREATE_NOSCHED contexts. Only a subset of the files will be available in this context directory in spufs. Also, SPU_CREATE_NOSCHED contexts cannot dump a core file when crashing 😭

Creating SPU_CREATE_NOSCHED contexts requires the CAP_SYS_NICE capability.

  • SPU_CREATE_ISOLATE β€” create an isolated SPU context. Isolated contexts are protected from some PPE (PowerPC Processing Element) operations, like access to the SPU local store and the NPC register. very "do not perceive me" energy 🧚

Creating SPU_CREATE_ISOLATE contexts also requires the SPU_CREATE_NOSCHED flag.

  • SPU_CREATE_AFFINITY_SPU (since Linux 2.6.23) β€” create a context with affinity to another SPU context. This affinity info gets used inside the SPU scheduling algorithm. Using this flag requires that you pass a file descriptor referring to the other SPU context in the neighbor_fd argument. besties stick together fr fr πŸ’œ
  • SPU_CREATE_AFFINITY_MEM (since Linux 2.6.23) β€” create a context with affinity to system memory. This affinity info gets used inside the SPU scheduling algorithm.

πŸ¦‹ RETURN VALUE πŸ¦‹

Slay: on success, spu_create() returns a new file descriptor.

Not slay: on failure, it returns -1 and errno is set to tell you what went wrong πŸ’€


πŸ’… ERRORS πŸ’…

  • EACCES β€” the current user does not have write access to the spufs(7) mount point.
  • EEXIST β€” an SPU context already exists at the given pathname. taken. occupied. move on πŸ™ˆ
  • EFAULT β€” path is not a valid string pointer in the calling process's address space.
  • EINVAL β€” path is not a directory in the spufs(7) mount point, or invalid flags were provided.
  • ELOOP β€” too many symbolic links were found while resolving path.
  • EMFILE β€” the per-process limit on the number of open file descriptors has been reached.
  • ENAMETOOLONG β€” path is too long.
  • ENFILE β€” the system-wide limit on the total number of open files has been reached.
  • ENODEV β€” an isolated context was requested, but the hardware does not support SPU isolation.
  • ENOENT β€” part of path could not be resolved.
  • ENOMEM β€” the kernel could not allocate all resources required.
  • ENOSPC β€” there are not enough SPU resources available to create a new context, or the user-specific limit for the number of SPU contexts has been reached.
  • ENOSYS β€” the functionality is not provided by the current system, because either the hardware doesn't provide SPUs or the spufs module isn't loaded.
  • ENOTDIR β€” a part of path is not a directory.
  • EPERM β€” the SPU_CREATE_NOSCHED flag was given, but the user doesn't have the CAP_SYS_NICE capability.

πŸ“ FILES πŸ“

path must point to a location beneath the mount point of spufs. By convention, it gets mounted in /spu.


⭐ STANDARDS ⭐

Linux on PowerPC. (yes, that's the whole standards section. it's niche and it knows it πŸ’…)


🌸 HISTORY 🌸

Linux 2.6.16.

Before the SPU_CREATE_AFFINITY_SPU flag was added in Linux 2.6.23, the spu_create() system call took only three arguments (i.e., there was no neighbor_fd argument). glow-up moment ✨


🧚 NOTES 🧚

spu_create() is meant to be used from libraries that implement a more abstract interface to SPUs β€” not to be used from regular applications. so like, don't just casually call it from your little app, bestie. The recommended libraries live at http://www.bsc.es/projects/deepcomputing/linuxoncell/ πŸ“š


πŸ‘‘ EXAMPLES πŸ‘‘

See spu_run(2) for an example of the use of spu_create()


πŸ’œ SEE ALSO πŸ’œ

close(2), spu_run(2), capabilities(7), spufs(7)


and that's the whole page, bestie, we ate and left no crumbs πŸŽ€

This one came from Linux man-pages 6.20, dated 2026-02-08 β€” so if your page looks different, your man-pages are lowkey outdated and you should probably update, iykyk πŸ¦‹πŸ’–

πŸ“¦ where this page comes from
  • arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • πŸ“œ the page's license: GPL-2.0-or-later
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms